diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:31:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:31:55 +0000 |
commit | cd6cce235837a74b252a369bcc40e7b93f91cee4 (patch) | |
tree | 7049356b06fcdcdaf9dbae476f55a43942e7c25f | |
parent | Initial commit. (diff) | |
download | geoip-cd6cce235837a74b252a369bcc40e7b93f91cee4.tar.xz geoip-cd6cce235837a74b252a369bcc40e7b93f91cee4.zip |
Adding upstream version 1.6.12.upstream/1.6.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
67 files changed, 25678 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..a72e2df --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +BinPackArguments: false +BinPackParameters: false +IndentCaseLabels: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..67550b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +*.la +*.lo +*.o +*.swp +*~ +.DS_Store +.deps +.libs +/m4 +GeoIP-*.tar.gz +GeoIP.spec +Makefile +Makefile.in +aclocal.m4 +apps/geoiplookup +apps/geoiplookup6 +apps/geoipupdate +autom4te.cache +compile +config.guess +config.log +config.status +config.sub +configure +depcomp +geoip.pc +install-sh +libtool +ltmain.sh +man/geoiplookup.1 +man/geoiplookup6.1 +man/geoipupdate.1 +missing +test-driver +test/benchmark +test/test-geoip +test/test-geoip-asnum +test/test-geoip-city +test/test-geoip-domain +test/test-geoip-invalid-file +test/test-geoip-invalid-file.log +test/test-geoip-invalid-file.trs +test/test-geoip-isp +test/test-geoip-netspeed +test/test-geoip-org +test/test-geoip-region +test/test-geoip.log +test/test-geoip.trs +test/test-suite.log diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..305b113 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,36 @@ +--- +sudo: false +addons: + coverity_scan: + project: + description: Build submitted via Travis CI + name: maxmind/geoip-api-c + notification_email: dev-ci@maxmind.com + build_command_prepend: ./configure; make clean + build_command: make -j 4 + branch_pattern: .*coverity.* +language: c +compiler: + - clang + - gcc +env: + global: + secure: |- + bMDurejTvGTXwVcD/fTij5xkhqOzwHSFQHxP1tLGBfemvRQ/FgX2E2M8rWaD + KbgKCgTSNB7fKtAvkFP+uteJ3/RY4HrQxlkY4/lG6tqlYJDCyLjxC0LLU5GE + hfW0iiu9ozNtJzQ2A2O3mgTUmN4+ay25VMTfoAYALvT67qpW+NM= +before_script: + - ./bootstrap + - CFLAGS="-Wall -Wextra -Werror -Wno-unused-parameter" ./configure + - make +script: + - make check +notifications: + email: + on_failure: always + on_success: change + recipients: + - dev-ci@maxmind.com + slack: + rooms: + secure: "WfyHKjt7GkS4U1tFmleDAwXEcs99LW33Gp0p8OwIPaV8ZI7WXZTw1ClJwr+Bpa9TDgfl26HX6IBcgX4ef/SAGvfLkYdEK8czYA2iT7VRudNQb/2oXdlwFz3hgY7yaROohkUgjo+IMq2efWFix7Z149ynex2k78Qp5g4GdZOLz48=\n" @@ -0,0 +1 @@ +T.J. Mather <geoipapi@maxmind.com> @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..b6b2ca0 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,973 @@ +1.6.12 2018-01-17 + +* Populate metro and area code when performing lookups in IPv6 City databases. + Previously this was only done when using IPv4 City databases. + +1.6.11 2017-05-15 + +* Fix use of a NULL pointer when opening a corrupt database with + `GeoIP_open`. Reported by Stephan Zeisberg. GitHub #87. + +1.6.10 2017-03-29 + +* GeoIP_database_info now returns the full version string rather than + incorrectly truncating it. GitHub #79. +* This API is now distributed with a small test copy of GeoIP.dat rather than + a full copy. +* Fix issue where Visual Studio 2015 was optimizing out initialization code. + Reported and fixed by Scott Godin. GitHub #81. +* Fix test/benchmark on Windows. Gisle Vanem. GitHub #75. + +1.6.9 2016-01-11 + +* Fix a regression introduced in version 1.6.8, which caused + GeoIP_database_info to erroneously return NULL. + +1.6.8 2016-01-11 + +* Allow compilation on older systems by relaxing the autoconf and automake + minimum versions. Thank you, Jose Rubio! +* Avoid potential problems in multi-threaded environments by consistently using + pread() rather than read(). +* Fix various small issues reported by clang's static analyser. + +1.6.7 2015-10-30 + +* Fixed a MSVC parser stack overflow when parsing `regionName.c` and + `timeZone.c`. Fix by elliotlo. GitHub #64. +* Updated region codes and timezones. +* When using `GEOIP_MEMORY_CACHE` with an invalid database file, the search + tree traversal could attempt to read memory outside of the memory allocated + for the memory cache, resulting in a segmentation fault. A check was added + to ensure that the traversal code does not try to read beyond the end of the + file, whether in memory, memory mapped, or on disk. +* Previously the return values from file reads were ignored. We now check + these values to ensure that there were no errors. + + +1.6.6 2015-07-28 + +* Replaced usage of deprecated fileno, read, and lseek on Visual Studio 2005+ + with their ISO C++ conformant replacements. (Fix by ClaudiuHKS. GitHub #55.) +* A warning about using a double as a float was fixed. (Fix by ClaudiuHKS. + GitHub #56.) +* Fixed segfault when doing a lookup on an empty database. (Fix by NesoK. + GitHub #62.) +* Fixed a memcheck error from valgrind in the `_check_mtime` + function. (Reported by yurivct. GitHub #60.) +* Fixed `_check_mtime` to check the return value of `gettimeofday` rather than + just assuming it worked. + + +1.6.5 2015-02-25 + +* A segmentation fault in `geoiplookup` was fixed when the utility was passed + an invalid database. (Reported in Red Hat bug #1180874.) +* Additional validation was added for validation of the size used in the + creation of the index cache. (Based on discussion in Red Hat bug #832913.) +* Changed the code to only look up country codes by using functions which + ensure that we do not try to look past the end of an array. (Reported by + Ivan Sorokin. GitHub #53) + + +1.6.4 2015-01-12 + +* Update Fips codes (Boris Zentner) +* Several issues with the MinGW build were fixed. (Thomas Pöchtrager. Github + #46.) +* Use a constructor in pread.c to ensure the critical section is always + initialized. (Thomas Pöchtrager. Github #47.) +* Added missing include of `io.h` on Windows. (Thomas Pöchtrager. Github #49.) +* Fixed `configure` warning that `'missing' script is too old or missing`. + (Reported by Floren Munteanu. Github #33.) +* Previously `nmake /f Makefile.vc clean` would fail on Windows. This was + fixed. +* Obsolete win32 and NetWare make files were removed. +* Numerous documentation updates. (Reported by Thomas Pöchtrager. GitHub #48.) + + +1.6.3 2014-10-29 + +* Added a GEOIP_SILENCE flag. Include this flag when calling GeoIP_open to + prevent any messages from being written to stderr. (Philip Prindeville + and Boris Zentner) +* Mitigate a possible race condition when running under threads in the + GeoIP_cleanup function. (Anthon Pang) +* Added some recommendations to the docs on using this library in a + threaded application. (Boriz Zentner) +* Fixed some bugs discovered by coverity, including failure to check some + system call return values and making sure all strings are + null-terminated. (Boris Zentner) + + +1.6.2 2014-07-08 + +* Two files required for building on Win32 were missing from the 1.6.1 + release. These files were added. There are no changes affecting other + platforms. (Boris Zentner) + + +1.6.1 2014-06-26 + +* Improve Win32 support (Evan Hunt) +* Update FIPS codes (Boris Zentner) + + +1.6.0 2013-10-29 + +* Remove geoipupdate (Boris Zentner) + + +1.5.2 2013-10-29 + +* Update region and time zones (Boris Zentner) +* Fix benchmark script (Boris Zentner) +* Remove autogenerated files ltmain.sh, man/geoip*.1 (Boris Zentner) +* Explain how to download free geolite databases in the README.md and + GeoIP.conf.default (Boris Zentner) +* geoipupdate returns 1 on error 0 on success instead of the error code + (Boris Zentner) +* README is replaced by README.md (Gregory Oschwald) +* Add support for OS X Mavericks (Boris Zentner) + + +1.5.1 2013-05-14 + +* Update time_zone for Ontario, Canada (Boris Zentner) +* geoiplookup and geoiplookup6 exit code is 0 when user asked for help + (Jan Safranek) +* Added -h option to geoiplookup6 (Jan Safranek) +* Do not load the database file if nodes and file size do not make + sense. (Boris Zentner) +* Keep README and man pages in pure ascii. (Boris Zentner) +* It doesn't make sense to use GEOIP_INDEX_MODE with small databases + like GEOIP_COUNTRY_EDITION. Instead of undefined behaviour we handle + it silently as GEOIP_MEMORY_MODE (Boris Zentner) +* Update FIPS codes for Greece (Boris Zentner) + + +1.5.0 2013-02-21 + +* Rename custom_directory to GeoIP_custom_directory. (Boris Zentner) +* Make sure the database match the requested type. This is helpful for + Databases with the same default name and the general geoiplookup form + (geoiplookup without a specific database) (Boris Zentner) +* apps/geoiplookup6.c use the ipnum instead of the hostname for lookups. + (Boris Zentner) +* Use configure.ac instead of configure.in (Boris Zentner) +* Region lookup is a bit faster (Boris Zentner) +* Add pkg-config file (Bastien Nocera) +* Updates required to build a Windows DLL under MinGW (Gerald Combs) +* Make API thread safe (Boris Zentner) +* geoiplookup's default charset is UTF8 + -l change the charset back to iso8859-1 (Boris Zentner) +* geoipupdate skips \r otherwise it might be part of the last + product_id (Boris Zentner) +* Update time zones (Boris Zentner) +* Update Region codes (Boris Zentner) +* Remove the unused CITYCONFIDENCE* database types (Boris Zentner) +* bootstrap rebuilds ltmain.sh (Boris Zentner) +* Update README.OSX for Lion (Boris Zentner) +* Change Macedonia to Macedonia, The Former Yugoslav Republic of + (Boris Zentner) +* Add region_name to geoiplookup GEOIP_CITY_EDITION_REV1 (Boris Zentner) +* Add region_name to geoiplookup GEOIP_CITY_EDITION_REV0 (Chris Johnson) +* Add a --disable-data-files option. This allows you to build and install + the library without having a data/GeoIP.dat file. This is useful when + building the library from a checkout of the source tree, rather than a + tarball (Dave Rolsky) +* Add GEOIP_ACCURACYRADIUS_EDITION and GEOIP_ACCURACYRADIUS_EDITION_V6 + (Boris Zentner) +* Add more database types GEOIP_COUNTRYCONF_EDITION, + GEOIP_CITYCONF_EDITION, GEOIP_REGIONCONF_EDITION and + GEOIP_POSTALCONF_EDITION (Boris Zentner) +* Fix default filenames for GEOIP_NETSPEED_EDITION_REV1 and + GEOIP_NETSPEED_EDITION_REV1_V6 (Boris Zentner) + + +1.4.8 + +* Fix GEOIP_DOMAIN_EDITION_V6 (Boris Zentner) +* Add new Datatypes GEOIP_NETSPEED_EDITION_REV1_V6 and + GEOIP_NETSPEED_EDITION_REV1 (Boris Zentner) +* Fix possible directory traversal weakness in geoipupdate-pureperl.pl with + malicious update server (Boris Zentner) +* Fix GEOIP_ORG_EDITION_V6 and GEOIP_ISP_EDITION_V6 (Boris Zentner) + + +1.4.7 2011-12-19 + +* Upd timezone.c Add SX, BQ and CW remove AN and FX (Boris Zentner) +* Add support for the new types in geoiplookup6 (Boris Zentner) +* Add new database types GEOIP_CITY_EDITION_REV0_V6, + GEOIP_CITY_EDITION_REV1_V6, GEOIP_DOMAIN_EDITION_V6, + GEOIP_ORG_EDITION_V6 and GEOIP_ISP_EDITION_V6 (Boris Zentner) +* Remove AN and FX. Add SX, BQ and CW (Boris Zentner) +* Fix possible segfault in geoipupdate if the connection disappear + unexpected. (Boris Zentner) +* Add sanity check for geoipupdate-pureperl.pl (Boris Zentner) +* Add GEOIP_USERTYPE_EDITION and GEOIP_USERTYPE_EDITION_V6 + datatypes (Boris Zentner) +* Add new functions GeoIP_is_private_ipnum_v4 and GeoIP_is_private_v4 + (Boris Zentner) +* Add new functions GeoIP_teredo and GeoIP_enable_teredo. + teredo is enabled by default (Boris Zentner) +* Fix output of geoiplookup for unknown or private regions. + (Boris Zentner) +* Fix geoipupdate-pureperl.pl to accept more product codes. + (Boris Zentner) +* Fix minor output issue in geoipupdate -v (Boris Zentner) +* Add support for various databases. (Boris Zentner) +* Add experimental teredo support (Boris Zentner) +* Fix possible buffer overflow in conjunction with + http_proxies (Elso Andras) +* Remove memcpy/bcopy macro for BSD (Boris Zentner) +* Add GeoIP_lib_version and GeoIP_cleanup (Ladar Levison) +* Upd Makefile.vc (Thomas Winzig) +* Fix typo in DK,18,Midtjylland (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100810 (Boris Zentner) +* Fix continent codes (Boris Zentner) +* Fix 3letter country codes for ATA, BVT, IOT, CXR, CCK, ATF, HMD, + MYT, SGS and UMI (Boris Zentner) +* Fix typo/segfault in GeoIP_id_by_name_v6 (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100529 (Boris Zentner) +* Remove buffered IO functions, to fix issues with dup'ed file + descriptors (Boris Zentner) +* Fix very minor memleak in geoipupdate (Boris Zentner) +* Add GEOIP_CITYCONFIDENCEDIST_EDITION, GEOIP_LARGE_COUNTRY_EDITION + and GEOIP_LARGE_COUNTRY_EDITION_V6 database types (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100422 (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100420 (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100221 (Boris Zentner) +* Add missing timezones (Boris Zentner) +* Add missing include for Windows 2000 (Jaap Keute) +* 'GeoIP Database up to date' and 'Updated database' prints to stdout + instead of stderr (Boris Zentner) +* Add missing GeoIPRecord_delete to geoiplookup.c (Piotr Kaczuba) +* Add some IPv4 helper functions + unsigned long GeoIP_addr_to_num(const char *addr); + char * GeoIP_num_to_addr(unsigned long ipnum); (Boris Zentner) +* Fix default name for the accuracy radius database to GeoIPDistance.dat (Boris Zentner) +* Add GEOIP_CITYCONFIDENCE_EDITION database type. (Boris Zentner) +* geoiplookup use GeoIPDistance.dat files if avail (Boris Zentner) +* Fix geoiplookup/geoiplookup6 output, when the databaseinfo string is + not avail. (Boris Zentner) +* Change continent code for RU from AS to EU (Boris Zentner) +* Add GEOIP_ACCURACYRADIUS_EDITION database type. (Boris Zentner) +* Add GEOIP_LOCATIONA_EDITION the database to map back from binary to + the csv database (Boris Zentner) +* Change Turkey's continent code from Asia to Europe (Boris Zentner) +* Rename _iso_8859_1__utf8 to _GeoIP_iso_8859_1__utf8 (Boris Zentner) +* GEOIP_ORG_EDITION, GEOIP_ISP_EDITION, GEOIP_DOMAIN_EDITION and + GEOIP_ASNUM_EDITION databases return UTF8 results, if gi->charset is set + to GEOIP_CHARSET_UTF8 (Boris Zentner) +* Avoid unnecesary call to gettimeofday when GEOIP_CHECK_CACHE is not set (John Douglass) +* Delayed loading of changed database files for 60 seconds. To avoid + reading halve written databases (Boris Zentner) +* Update README.OSX for Leopard and Snow Leopard (Boris Zentner) +* Add more IPv6 functions (Boris Zentner) + const char *GeoIP_country_code_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_code_by_name_v6 (GeoIP* gi, const char *host); + const char *GeoIP_country_code3_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_code3_by_name_v6 (GeoIP* gi, const char *host); + const char *GeoIP_country_name_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_name_by_name_v6 (GeoIP* gi, const char *host); +* Make sure that GeoIP_*_v6 functions refuse GEOIP_PROXY_EDITION and + GEOIP_NETSPEED_EDITION databases (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes from 20090723 (Boris Zentner) +* Fix geoipupdate's -v option to not change the license filename (Thom May) +* Fix geoipupdate's exit code (Thom May) +* Add support for ASNUM_EDITION (Boris Zentner) +* Fix -i output for larger values, sign issue (Boris Zentner) +* Add -i flag for more information on netmask, range_by_ip and the current network range (Boris Zentner) +* Add support for DOMAIN_EDITION database type (Boris Zentner) +* Fix apps/geoipupdate-pureperl.pl output layer on W32 (Boris Zentner) + + +1.4.6 2009-02-25 + +* Fix geoipupdate's my_printf function (Boris Zentner) +* Fix typo in apps/geoipupdate-pureperl.pl replace PerlIO::Gzip with PerlIO::gzip (Boris Zentner) +* Update region codes in libGeoIP/regionName.c (Boris Zentner) +* Fix regioncode/generate_regionName.pl to handle regioncodes with ',' correct (Boris Zentner) +* Update fips codes 20090201 (Boris Zentner) +* Fix unicode builds on WIN32 and eliminate some warnings (Stu Redman) +* Fix sign error in _iso_8859_1__utf8 for PPC64 (Boris Zentner) +* Change WIN32 to _WIN32, since _WIN32 is defined by default. _WIN32 is also defined for WIN64 machines (Boris Zentner) +! Remove the WSAStartup call from GeoIP_open. All Applications need to call WSAStartup and WSACleanup to initialize the Windows Socket library. Before they use any of the GeoIP_*_by_name functions. (Boris Zentner) +* geoiplookup and test-geoip-* output N/A instead of (null) (Boris Zentner) +* Silence various warnings. (Boris Zentner) +* Add more timezone region's for Australia +* Fix possible segfault in apps/geoiplookup with null pointers in non gnu printf implementations for example solaris (Boris Zentner) +* Add README.OSX to build fat binaries easy (Boris Zentner) +* Silence vasprintf warning via AC_GNU_SOURCE (Boris Zentner) +* Add several Makefiles to build a static GeoIP.lib for w32 (Stanislaw Pusep and Randy Kobes) +* Silence signedness warnings (Peter Volkov) +* Remove --with-city configure option. (Boris Zentner) +* Remove configure's --with-dbdir option. Use the similar --datadir instead (Peter Volkov) +* Various autotools improvements and cleanups. Including parallel + build fix (Peter Volkov) +* Fix libGeoIP/timeZone.c (Martin Haller) +* Fix timezone/generate_timeZone.pl (Boris Zenter) +* Sync FIPS codes again Jan 14th, 2009 (Boris Zentner) +* Fix CA,NL regioncode. (Boris Zentner) +* Change logic in generate_regionName.pl and GeoIP_region_name_by_code to handle any mixture of two letter fips codes matching [A-Z0-9]{2} the change allow GZ and WE region codes (Boris Zentner) +* Sync regionName.c with http://www.maxmind.com/app/fips10_4 from Dec 17th, 2008 (Boris Zentner) +* Fix _GeoIP_lookupaddress for 64bit big endian systems like ppc64 (Peter Volkov) +* Add proper WIN32/64 support (Gerald Combs) +* Escape - in all manpages (Patrick Matthäi) +* Add manpage for geoiplookup6 (Boris Zentner) +* Fix -d command line option (Klaus Heinz) +* GeoIPUpdate.c use vasprintf if avail, otherwise try vsnprintf and sprintf (Boris Zentner) +* avoid pre/postincrement and assignment on the same variable (Boris Zentner) + + +1.4.5 2008-09-16 + +* metro_code replace the depreciated dma_code field (Boris Zentner) +* Add new function GeoIP_range_by_ip_delete + r = GeoIP_range_by_ip(gi, '24.24.24.24'); + ... + GeoIP_range_by_ip_delete(r); (Boris Zentner) +* Fix small memoryleak and wrap around in GeoIP_range_by_ip (Boris Zentner) +* CHECK_CACHE stat the database file not faster than once a second anymore (Patrick McManus) +* Fixed a typo in the geoipupdate(1) manpage and also an non-existent path on Debian (Patrick Matthäi) +* Fixes two little format errors (hyphen used as minus sign) in both manpages (Patrick Matthäi) +* Sync regionName.c with a recent fips code list (Boris Zentner) +* Fix segfault when open failed for a custom file (-f) (Boris Zentner) +* Fix sync geoiplookup's man page with the code (Klaus Heinz) +* remove unused code from GeoIP_country_name_by_addr and GeoIP_country_code3_by_addr (Boris Zentner) +* Fix geoiplookup and geoiplookup6 to distinguish between failed namelookups and unknown ips (Boris Zentner) +* add geoiplookup6 that can handle the new database type GEOIP_COUNTRY_EDITION_V6 (Boris Zentner) +* add new functions to handle ipv6: + GEOIP_API const char *GeoIP_country_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API const char *GeoIP_country_code_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API const char *GeoIP_country_code3_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_org_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_org_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API char *GeoIP_org_by_name_v6 (GeoIP* gi, const char *name); + GEOIP_API int GeoIP_id_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API int GeoIP_id_by_name_v6 (GeoIP* gi, const char *host); + GEOIP_API int GeoIP_id_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API GeoIPRegion * GeoIP_region_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API GeoIPRegion * GeoIP_region_by_name_v6 (GeoIP* gi, const char *host); + GEOIP_API GeoIPRegion * GeoIP_region_by_ipnum_v6 (GeoIP *gi, geoipv6_t ipnum); + GEOIP_API void GeoIP_assign_region_by_inetaddr_v6(GeoIP* gi, geoipv6_t inetaddr, GeoIPRegion *gir); + GEOIP_API char *GeoIP_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_name_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API char *GeoIP_name_by_name_v6 (GeoIP* gi, const char *name); + + # allowed input for addr + 2001:4860:0:1001::68 + ::85.8.93.71 + ::1 + ::5508::5d47 + ::ffff:5508::5d47 + + # allowed input for host + ipv6.google.com + 2001:4860:0:1001::68 + ::85.8.93.71 + ::1 + ::5508::5d47 + ::ffff:5508::5d47 + (Boris Zentner) +* Fix geoiplookup usage string (add -d -f) (Boris Zentner) +* Added GeoIP_range_by_ip, returns the start and end IP address for the range containing the IP address. + This range has a constant value in the GeoIP database. +* Add geoipupdate-pureperl.pl a alternative geoipupdate version. with Proxy Server support via via the "http_proxy" environment variable. Easy to customize. (Boris Zentner) +* Add WIN64 since WIN32 is not defined on WIN64 Systems (Boris Zentner) +* Fix WIN32 compilation by encircle all MMAP functions with #ifdef WIN32 #endif pairs. MMAP is not avail in W32 (Boris Zentner) +* Update timezone/generate_timeZone.pl (Boris Zentner) +* Update libGeoIP/timeZone.c (Boris Zentner) +* Added GeoIP_printf and GeoIP_fprintf as a experimental feature to + libGeoIPUpdate. (Boris Zentner, Andrew Droffner) +* Added cast in _iso_8859_1__utf8 function to fix NetWare/Win32 compilation issue (Guenter Knauf) +* Add HTTP Proxy Server support for geoipupdate via the "http_proxy" + environment variable. + ie: export http_proxy="http://proxy-hostname:port" + (Andrew Droffner, Derek Nicol) +* Notice, that __YOU__ need to free the results of + + GeoIP_database_info + GeoIP_name_by_ipnum + GeoIP_name_by_addr + GeoIP_name_by_name + GeoIP_org_by_ipnum + GeoIP_org_by_addr + GeoIP_org_by_name + + not libgeoip + (Boris Zentner, Andrew Cheung) +* Fixed segfault with geoiplookup, if used with a custom_file database, that + could not be opened. (Boris Zentner) +* Add Usage info for options -f and -d in geoipupdate (Boris Zentner) +* Fixed segfault with geoipupdate when called with a illformed license file + (Boris Zentner) +* Update add more timezones to GeoIP_time_zone_by_country_and_region + (Boris Zentner) +* Add array access functions so programs can avoid accessing the + arrays directly which whould break binary compatability (Ludwig Nussel at SUSE) +* Updated README to state API is only thread-safe if GEOIP_CHECK_CACHE is not used + + +1.4.4 2008-1-21 + +* Updated original geoipupdate to return "Invalid product ID or subscription expired" +* Added BL/Saint Barthelemy, MF/Saint Martin (ISO-3166-1 additions) +* Check for illegal IP strings, return 0 if IP is not well formed IPv4 e.g. 1.2.3.4.5 and 1.2.3 +* Clarified that while core GeoIP library is LGPL, libGeoIPUpdate depends on md5.c and types.h which are GPL. +* speedup the conversion from ipstring to ipnum in _GeoIP_addr_to_num. Doubles the speed of GEOIP_MEMORY_CACHE and GEOIP_MMAP_CACHE +* Added new mmap shared memory caching option, GEOIP_MMAP_CACHE (Peter Shipley, LookSmart) + - mmaps: our maps are shared, but we need only private readonly pages + + +1.4.3 2007-8-30 + +! CHANGE with geoiplookup facility: -v flag now returns database info for all databases, not just GeoIP Country +* Added ability to get netmask of network block from last lookup using GeoIP_last_netmask +* Fixed GeoIP_database_info bug with GeoLite City +* Replaced 4 with sizeof(char*) to fix issues with geoipupdate on 64 Bit machines +* Added GeoIP_set_charset function - enables UTF8 output of city name if GEOIP_CHARSET_UTF8 flag is passed +to GeoIP_set_charset +* Fixed segfault issue if calling GeoIP_db_avail before opening a database +* Added continent_code to GeoIP City's record struct (Frank Mather) + + +1.4.2 2007-2-8 + +* Added -d flag to enable custom path for geoipupdate utility program (Frank Mather) +* Replaced _WIN32 with WIN32 since WIN32 is already set by compilers +* Moved var definitions to top of code, defined size_t (Guenter Knauf) +* Added Makefile.win32, Makefile.netware, get_ver.awk, geoip.ico to EXTRA_DIST in Makefile.am (Guenter Knauf) + + +1.4.1 2007-1-2 + +* Replaced CS/Serbia and Montenegro with RS/Serbia, removed ZR/Zaire, added ME/Montenegro +* Added AX/Aland Islands, GG/Guernsey, IM/Isle of Man, JE/Jersey (ISO-3166-1 changes) +* Added GeoIP_time_zone_by_country_and_region, to lookup zoneinfo timezone by country and region (Frank Mather) +* Added GeoIP_region_name_by_code, to lookup region name from region code (Frank Mather) +* added -f and -d flags to enable custom paths for geoiplookup utility program (Frank Mather) +* Added benchmarks for GeoIP Region and City in test/benchmark.c (Frank Mather) +* Fixed build issue when using --as-needed flag (Diego 'Flameeyes' Pettenò) +* Add sanity checking for filename returned by MaxMind.com server for geoipupdate filename + (Dean Gaudet, arctic.org) +* Fixed memory leaks under error conditions, buffer overflow using sprintf, + and issue where a corrupted cache file could core dump the file + (Nick Galbreath, Right Media Inc) + + +1.4.0 2006-8-7 + +* Changed license from GPL to LGPL, so that PHP Extension can be included in PECL (Olivier Hill) +* Rewrote GEOIP_CHECK_CACHE code, fixed numerous bugs + - CheckCache now works if GeoIP file is overwriten by mv command + - Fixed bug where CheckCache kept reloading in GEOIP_STANDARD_MODE + - Fixed segfault issue in GEOIP_MEMORY_CACHE mode + - Fixed garbage data appearing in GEOIP_INDEX_CACHE mode + - Fixed realloc in case realloc returns new memory block (Andre Morozov of Stone Steps) +* Updated geoipupdate to print status messages for each database instead of just last database +* Check that gi is not null before running code in GeoIP_delete +* Fixed alpha-3 codes ordering, replaced TLS,TKM,TUN,TON with TKM,TUN,TON,TLS +* TP/East Timor changed to TL/Timor-Leste, reflecting changes in ISO-3166 + +* Added Netware and Windows makefiles (Guenter Knauf) +* Fixed NetWare compiler issue with char block[block_size] declaration (Guenter Knauf) +* Updated geoipupdate example to run weekly + + +1.3.17 2006-5-14 + +* Fixed headers for Windows/Netware compilation (Guenter Knauf) +* Fixed Received Error -21 (Sanity check database_info string failed) + when running geoipupdate with GeoIP Country when UserId and + productIds were not specified. Bug was introduced in 1.3.15. + + +1.3.16 2006-4-17 + +* Fixed compliation error in GeoIPUpdate.c + + +1.3.15 2006-4-14 + +* Updated README documentation +* Updated geoipupdate so that it writes file as it is uncompressed instead +of storing entire GeoIP.dat file in memory (Frank Mather) +* Updated geoiplookup so that it returns GeoIP Domain Name if available + (Frank Mather) +* Updated geoipupdate so that it reports whether databases are updated +in non-verbose mode (Frank Mather) + + +1.3.14 2005-9-7 + +* Check if byte, ushort, ulong, u16, u32 are defined in configure + script. Fixes compilation issue on FreeBSD systems. +* Check for Big Endian byte order (needed for MD5 code in geoipupdate + to work properly on Mac OS X and other Big Endian processors) +* Fixed GEOIP_CHECK_CACHE mode when used with GEOIP_STANDARD to + only refresh upon file change +* Fixed memory leak when refreshing file in GEOIP_CHECK_CACHE mode +* Updated ltmain.sh to support Debian GNU/k*BSD bug #315425 (Marek Habersack) +* Added lookup functions using IP numeric representation as input (Frank Mather) +* Removed geoipexport +* Replaced Yugoslavia with Serbia and Montenegro +* Updated geoiplookup to only perform country lookup once instead of twice by + using GeoIP_id_by_name + + +1.3.13 2005-8-1 + +* Fixed autoconf weirdness that resulted in libraries being + installed without .so suffix + + +1.3.12 2005-7-19 + +* Removed -lGeoIP from libGeoIPUpdate_la_LIBADD - fixes compilation error + if GeoIP isn't already installed (Thomas Steudten) + + +1.3.11 2005-7-7 + +* Fixed gcc warnings and bug. Use int + instead of char for checking the return value of getopt in geoipupdate.c. + Moved the internal functions to GeoIP_internal.h to get rid + of those 'implicit declaration' warnings. (Ludwig Nussel/SUSE) +* Cleaned up name space by prefixing internal functions with + _GeoIP* (Ludwig Nussel/SUSE) +* Memory Leak fix for GeoIP City if fread error +* Added more verbose error messages for geoipupdate (Frank Mather) +* Added check for zlib.h to configure.in + + +1.3.10 2005-4-17 + +* Added types.h to Makefile.am - fixes compilation error + + +1.3.9 2005-4-14 + +* fixed bug with GEOIP_INDEX_CACHE (Frank Mather) +* fixed segfault issue if GeoIP.dat not found (Frank Mather) +* Updated MD5 checksum code to use GnuPG code which works + on 64bit machines (Frank Mather) +* Fixed memory leak in test-geoip-isp.c and test-geoip-org.c +* Added support for GeoIP Domain Names in geoipupdate + + +1.3.8 2004-11-7 + +* Updated geoipupdate to report invalid userID and productID errors +* Check if gethostbyname_r is version that returns int or is other version + - should fix compile errors on Solaris and FreeBSD +* Updated URL to get license key, userId, and product Ids in conf/GeoIP.conf.default +* Updated test case, removed www.asahi.com +* Added support for GEOIP_INDEX_CACHE - which just caches + the most frequently access index portion of the database, resulting + in faster lookups than GEOIP_STANDARD, but less memory usage than + GEOIP_MEMORY_CACHE (Frank Mather) + + +1.3.7 2004-10-5 + +* Updated test case, removed www.bundesregierung.de added www.asahi.com + + +1.3.6 2004-8-8 + +* Check for gethostbyname_r support in configure (Mac OS X doesn't support gethostbyname_r) +* Made GeoIP City code thread safe +* Fixed bug with geoipupdate reading in product ids +* Added support for GeoIP Netspeed geoipupdate +* Fix memleak in lookupaddress (Ludwig Nussel/SUSE) +* Add prototype for _full_path_to to make 64bit clean + (Ludwig Nussel/SUSE) +* Add return values to test programs (Ludwig Nussel/SUSE) + + +1.3.5 2004-7-5 + +* Added more documentation to README file +* Made GEOIP_CHECK_CACHE work with GEOIP_STANDARD mode - reloads filehandle + in case file changes. +* Added GeoIP_country_code_by_ipnum and GeoIP_id_by_ipnum to use + existing ulong IP Address in numeric form instead of having to + convert it to string (Boris Hajduk) +* Made code thread safe by replacing gethostbyname with gethostbyname_r + + +1.3.4 2004-6-4 + +* Fixed bug where *.gz file(s) didn't get removed after geoipupdate + + +1.3.3 2004-6-2 + +* Added support for NetSpeed lookup to geoiplookup +* inet_addr patch for 64 bit systems (Thomas Steudten) +* Added Support for automated downloads of GeoIP Region, City, ISP and + Organization databases (Frank Mather) +* INADDR_NONE Patch for Solaris 9 (John Young) + + +1.3.2 2004-4-20 + +* Added support for Maxmind NetSpeed + +* MinGW patch from Stanislaw Pusep + + I was re-compiling Geolizer (http://sysd.org/log.php#glzr) on Win32 so I + firstly needed to put up-to-date Win32 compatibility of libGeoIP itself. + Fortunately MinGW plataform evolved a lot since last time I used it to + compile libGeoIP. I'm sending you the patch with changes required for + libGeoIP to work on both Win32 and UN*X. UN*X behavior is unaffected. Now, + detailed explanation of what I did at all: + + 1) Made correct header imports for both Win32 and UN*X. UN*X imports netdb.h + & netinet/in.h and Win32 imports windows.h & winsock.h + 2) Win32 gethostbyname() is only able to resolve hostnames, it can't convert + "127.0.0.1" string to 32-bit IP address. Thus I added lookupaddress() + function that safely resolves any string to IP address and replaced all + gethostbyname() calls by it. + 3) Database files were referenced by pre-compiled static strings. I + malloc()ed buffers for file names so they can be changed "on fly". Thus, + on Win32 version GeoIP.dat & other files are being seeked in the same + directory as executable file or library. + 4) Added README.MinGW file with brief explanation on how to get GeoIP + working under MinGW system. + + +1.3.1 2003-11-11 + +* Check for stdint.h in autoconf (Sean Chittenden) +* prevent the geoipupdate man page from trying to install itself directly in + the system directory (Gyepi Sam) + + +1.3.0 2003-09-29 + +* Fixed includes to compile on Windows (Fabrice Colin) +* Removed the _addr_to_num() calls from GeoIP_*_by_name() +* _seek_record() optimizations (Maurice Cinquini) + 1) Use a single buf ptr inside the loops. + Set to the stack buffer or the cached memory the start of the function. + 2) Unroll the i=0,1 loop to allow constant folding. + 3) Unroll the j loop for the common case of j = STANDARD_RECORD_LENGTH + (I've already done the above changes see attached function.) + With gcc -O2 calculating x[0] and x[1] for STANDARD_RECORD_LENGTH now + only takes 15 (was > 100) i80x86 instructions with 6 byte accesses of RAM. + 4) only calculate x[0], x[1] when needed, may be a bigger win + than the above since all the other optimizations above only reduced + CPU instructions operating on CPU cached RAM. +! IMPORTANT API Change: Changed GeoIPRegion to have region in structure. Saves space and a malloc. + Since GeoIPRegion.region is no longer a pointer but an in-structure + array so test the first byte of region == 0 rather testing if the region + pointer is NULL. (Maurice Cinquini) +* Added GeoIP_assign_region_by_inetaddr which doesn't do any mallocs and made all other region APIs go thru it (Maurice Cinquini) +* Replaced _h_addr_to_num() with ntohl() and removed _h_addr_to_num() (Maurice Cinquini) +* Fixed bug when IP address not found in region rev1 database (Jason Linhart) +* Added added extern "C" to GeoIPCity.h fixes problems when included in C++ library + + +1.2.2 2003-08-10 + +* Added support for GeoIP ISP Edition identifier +* Fixed bug in GeoIP_database_info (Jason Linhart) +* Added support for GeoIP AS Number Edition +! renamed GeoIP_org_by_* functions to GeoIP_name_by_* to reduce confusion + since these functions are used by GeoIP ISP and GeoIP ASNum as well + as GeoIP Organization +* Added support for GeoIP Proxy Edition +! renamed GeoIP_country_id_by_* functions to GeoIP_id_by_* + + +1.2.1 2003-07-12 + +* Added GeoIP_record_id_by_addr and GeoIP_next_record functions +* Added support for new GeoIP Region format, including Canadian Provinces + + +1.2.0 2003-04-26 + +* Added support for GeoIP City format revision 1, including dma code and area code +* geoiplookup returns results from GeoIP Region, City, ISP and Organization databases +* Standardized location for GeoIP Region, City, ISP and Organization databases +* Added GeoIP_open_type to open database from default location for other dbs besides country +* Added check to make sure that the appropriate database is loaded for each lookup method +* Updated update code to check for first 12 characters of license key +* Added GeoIP_country_continent array to lookup continent by country ID + + +1.1.9 2003-03-10 + +* merged windows patch into main code base (Kenneth R. Robinette) +* Changed const int to #define for windows compatibility + + +1.1.8 2003-03-04 + +* Fixed bug with city database introduced in 1.1.6 + + +1.1.7 2003-03-04 + +* Fixed bug introduced in 1.1.6 when run in GEOIP_STANDARD mode +* Added test to test GEOIP_STANDARD + + +1.1.6 2003-03-03 + +* Added spec for building RPMs (Ryan Weaver) +* Added support for 4byte records for Organization database +* Changed Taiwan, Province of China to Taiwan + + +1.1.5 2003-02-10 + +* Added support for GeoIP Organization database + + +1.1.4 2002-12-30 + +* Cast number to int in _num_to_addr in geoipexport (Ralf S. Engelschall) +* Removed printf debug statements from geoipexport +* correct library build ordering (Ralf S. Engelschall) +* ulong -> unsigned long (Sean Chittenden) + + +1.1.3 2002-12-24 + +* Added GeoIPUpdate.h to EXTRA_DISTS +* Compile fixes for Solaris, FreeBSD (Michael McClennen, Corris Randall) +* Handle NULL in printf in test-geoip-region + + +1.1.2 2002-12-16 + +* Added support for postal codes +* Added geoipexport, program to export bit binary file to + binary tree format and csv format +* Split update code into separate library, GeoIPUpdate.la +* Allow passing NULL callback to GeoIP_update_database function + (Sean Chittenden) +* Added geoipexport program, exports to CSV file +* Added GeoIP_database_edition method +* Changed DATADIR to GEOIPDATADIR + + +1.1.1 2002-11-07 + +* Fixed segfault issue with GeoIPRegion_delete +* Handle test failures where lookup returns NULL more gracefully + + +1.1.0 2002-11-06 + +* Perform sanity checking before installing datebase using geoipupdate +* Removed file locking, since we install file by renaming instead of writing to it. +* Fixed geoipupdate to check for NULL return value +* Added constants for different editions +* Added O1 code for "Other country", used in per-country city editions +* fixed multi-line string literals warning in test-geoip.c +* Use enum constants for GeoIP_update_database values +* Added GEOIP_CHECK_CACHE option (not working yet) + + +1.0.10 2002-10-28 + +* IMPORTANT API Change - Return NULL instead of '--' and 'N/A' + Be sure to check the return value for NULL to avoid segmentation faults!!!! +* Added callback to print messages from GeoIP_update_database +* Moved GeoIPConfFile to geoipupdate.c +* Changed databaseSegments to unsigned int (Chris Gibbs) +* Fixed compiler warnings (Chris Gibbs) +* API Change - GeoIPRegion region member set to NULL when no region available +* Change short int to int (Chris Gibbs) +* Added write/read file locking for GeoIPUpdate.c/GeoIP.c + + +1.0.9 2002-10-16 + +* removed -ansi from Makefile.am to avoid compile error on Solaris 8 +* Compile fix for FreeBSD Stable (Kimura Fuyuki) + + +1.0.8 2002-10-05 + +* Included header required for *BSD (Akinori Musha) + + +1.0.7 2002-10-05 + +* Fixed compilation error with GeoIPUpdate.c + + +1.0.6 2002-10-04 + +* Moved update code into separate file +* Added md5 checksums to update code +* Fixed memory leak when running geoiplookup -v +* Moved const RECORD_LENGTH to #define RECORD_LENGTH for Windows compatibility + (Randy Kobes) +* Cleaned up GeoIP_new code + + +1.0.5 2002-09-23 + +* Supports GeoIP Regional Edition +* Macau is now "Macao" per ISO 3166-1 change +* Romania "ROM" is now "ROU" per ISO 3166-1 change +* Added #define for memcpy -> BSD's bcopy (Chris Gibbs) +* Removed "private" functions from GeoIP.h + + +1.0.4 2002-08-27 + +* rewrote _seek_country to use loop instead of recursion for faster performance +* Removed "orphan" nodes from demo database resulting in smaller size (Jason Linhart) +* Moved changes for building windows DLL into separate patch +* Fixed segfaults when passed malformed IP addresses + + +1.0.3 2002-08-26 + +* Added more changes for windows compatibility + (Stanislaw Pusep) +* Added benchmark program + + +1.0.2 2002-08-21 + +* Open database using "rb" for windows compatibility + (Stanislaw Pusep) +* Removed superfluous inet_ntop command (Stanislaw Pusep) + + +1.0.1 2002-08-20 + +* Fixed bug with resolving hostnames +* More fixes for compiler warnings (Chris Gibbs) +* Changed int to unsigned int in _is_ipaddr (Chris Gibbs) + + +1.0.0 2002-08-12 + +* Changed license to GPL +* Don't perform Reverse DNS lookups on IP addresses +* Only include getopt.h on Linux (OpenPKG patch) +* Avoid the_license_key_str warning (OpenPKG patch) +* Added license for March 2002 database + + +0.3.0 2002-08-04 + +* Added support for 'A2', Satellite Providers + + +0.2.8 2002-07-30 + +* Handle malformed input gracefully +* Added section to README on Solaris workarounds +* Added geoipupdate man page + + +0.2.7 2002-07-27 + +* Added section to README on automatic updates +* link to socket library on solaris + + +0.2.6 2002-07-25 + +* optimized GeoIP_open (Chris Gibbs) +* check for partial file read in GeoIP_open (Chris Gibbs) +* optimized _addr_to_num() (Chris Gibbs) +* changed write and read to send and recv for sockets +* Only install GeoIP.conf and GeoIP.dat if not already installed + + +0.2.5 2002-07-22 + +* Added verbose option to GeoIP_update_database + + +0.2.4 2002-07-22 + +* Fix for GeoIP_update_database + + +0.2.3 2002-07-22 + +* Fixes for FreeBSD +* All calls to malloc are checked for NULL pointer (Chris Gibbs) +* Fixed spelling of "Kazakhstan" (Chris Gibbs) +* Initialize cache_buf to NULL (Chris Gibbs) +* More memory leak fixes (Chris Gibbs) + + +0.2.2 2002-07-18 + +* Added update database function +* Fixed memory leak in GeoIP_new (Chris Gibbs) + + +0.2.1 2002-07-03 + +* Added support for anonymous proxies + + +0.2.0 2002-06-23 + +* Added new memory caching option for improved performance + + +0.1.7 2002-05-29 + +* Only add -lnsl for systems that support libnsl +* Added decl for 3 letter country code array to GeoIP.h + + +0.1.6 2002-05-25 + +* Added 3 letter country code + + +0.1.5 2002-05-23 + +* Added -lnsl fixed compile errors + + +0.1.4 2002-05-11 + +* Fixed bugs in demo March 2002 database + + +0.1.3 2002-04-21 + +* Fixed bug related to signed int (Brian Grossman) +* Better error handling when hostname not found +* Fixed bug when netmask=32 for netblock + + +0.1.2 2002-04-20 + +* Added two new functions, GeoIP_country_id_by_addr + and GeoIP_country_id_by_name. +* Made GeoIP_country_code and GeoIP_country_name + viewable outside of library, to be with with + GeoIP_country_id_by_* functions. + + +0.1.1 2002-04-07 + +* GeoIP.h is now installed to includedir +* constructor and destructor are now provided by + GeoIP_new, GeoIP_open, and GeoIP_delete + + +0.1.0 2002-04-07 + +* Initial release diff --git a/GeoIP.spec.in b/GeoIP.spec.in new file mode 100644 index 0000000..9405b6e --- /dev/null +++ b/GeoIP.spec.in @@ -0,0 +1,76 @@ +Name: @PACKAGE@ +Version: @VERSION@ +Summary: GeoIP is a C library finds the location of an IP address. +Release: 1 +Group: System Environment/Libraries +URL: http://dev.maxmind.com/geoip/downloadable +Vendor: MaxMind, Inc. +Source0: http://www.maxmind.com/download/geoip/api/c/GeoIP-latest.tar.gz +License: LGPLv2.1+ +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +GeoIP is a C library that enables the user to find geographical and +network information of an IP address. +Included is a free GeoLite Country database +that is updated at the beginning of every month. +To download the latest free GeoLite databases, go to: +http://dev.maxmind.com/geoip/geolite + +%package devel +Summary: GeoIP headers, libraries +Group: Development/Libraries +Requires: %name = %{version} + +%description devel +This package contain the devel files for GeoIP. + +%prep +%setup -q + +%build +%configure +make +make check + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +%makeinstall +# Fixup permissions on shared libraries so that findreqs will work right. +chmod 755 $RPM_BUILD_ROOT/%{_libdir}/* + +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%doc AUTHORS COPYING ChangeLog README.md TODO +%attr(0755,root,root) %{_libdir}/*.so.*.* +%{_bindir}/* +%{_sysconfdir}/* +%dir %{_datadir}/GeoIP +%{_datadir}/GeoIP/* +%{_libdir}/*.so +%{_mandir}/*/* + +%files devel +%{_includedir}/* +%{_libdir}/*.a +%{_libdir}/*.la + +%changelog +* Fri Apr 14 2006 Thomas Mather <support@maxmind.com> +- Updated description to reference free GeoLite City database + +* Thu Jul 7 2005 Thomas Mather <support@maxmind.com> +- Updated description to reflect monthly updates for free country database. + +* Mon Sep 8 2003 Dr. Peter Bieringer +- Fix for RHL 9, created a new devel package definition. + +* Thu Feb 27 2003 Ryan Weaver <ryanw@falsehope.com> +- Initial RPM Build @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `<wchar.h>' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + @@ -0,0 +1,28 @@ +There are two licenses, one for the C library software, and one for +the GeoLite Country database. + +SOFTWARE LICENSE + +Copyright (C) 2015 MaxMind, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +For a copy of the LGPL License, see the COPYING file. + +DATA LICENSE (GeoLite Country and City Databases) + +The GeoLite databases are distributed under the Creative Commons +Attribution-ShareAlike 3.0 Unported License. The attribution +requirement may be met by including the following in all advertising +and documentation mentioning features of or use of this database: + + This product includes GeoLite data created by MaxMind, available from + <a href="http://www.maxmind.com">http://www.maxmind.com</a>. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..ad9b1ea --- /dev/null +++ b/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = -Wall -ansi +ACLOCAL_AMFLAGS = -I m4 + +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = \ + libGeoIP \ + apps \ + test \ + man + +pkgconfigdir = $(libdir)/pkgconfig/ +nodist_pkgconfig_DATA = geoip.pc + +EXTRA_DIST = LICENSE NEWS.md README.md README.OSX bootstrap GeoIP.spec GeoIP.spec.in Makefile.vc get_ver.awk geoip.ico geoip.pc.in data/GeoIP.dat diff --git a/Makefile.vc b/Makefile.vc new file mode 100644 index 0000000..fde3e48 --- /dev/null +++ b/Makefile.vc @@ -0,0 +1,84 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +################################################################# +# configuration section +################################################################ + +# place to put the GeoIP.dat database file +# !!! Please keep the 2 \\ as directory separators !!! +# +GEOIPDATADIR="C:\\Windows\\SYSTEM32" +# +# System inc, lib, and bin directories +!ifndef INSTDIR +INSTDIR="C:\GeoIP" +!endif + +# Location where GeoIP.lib should be installed my "make install" +INSTALL_LIB=$(INSTDIR)\Lib + +#Location where .h files should be installed by "make install". +INSTALL_INC=$(INSTDIR)\Include + +#Location where programs should be installed by "make install". +INSTALL_BIN=$(INSTDIR)\Bin + +################################################################ +# end configuration section +################################################################ + +DATA_DIR=data + +DATA_FILE=GeoIP.dat + +LIB_DIR = libGeoIP + +TEST_DIR=test + +APP_DIR=apps + +GEOIP_LIB = GeoIP.lib + +APP_PROGRAMS = geoiplookup.exe + +TEST_PROGRAMS = benchmark.exe test-geoip.exe + +all: GeoIP.lib test_progs app_progs + +$(GEOIP_LIB): + cd $(LIB_DIR) + $(MAKE) -nologo -f Makefile.vc GEOIPDATADIR=$(GEOIPDATADIR) + cd .. + +test_progs: + cd $(TEST_DIR) + $(MAKE) -nologo -f Makefile.vc + cd .. + +app_progs: + cd $(APP_DIR) + $(MAKE) -nologo -f Makefile.vc + cd .. + +test: $(GEOIP_LIB) test_progs + cd $(TEST_DIR) + benchmark.exe + test-geoip.exe + cd .. + +install: $(GEOIP_LIB) app_progs + cd $(LIB_DIR) + copy $(GEOIP_LIB) $(INSTALL_LIB) + copy *.h $(INSTALL_INC) + cd ..\$(APP_DIR) + copy $(APP_PROGRAMS) $(INSTALL_BIN) + cd ..\$(DATA_DIR) + copy $(DATA_FILE) $(GEOIPDATADIR) + cd .. + +clean: + del $(LIB_DIR)\*.obj $(LIB_DIR)\*.lib $(LIB_DIR)\*.dll + del $(APP_DIR)\*.obj $(APP_DIR)\*.exe + del $(TEST_DIR)\*.obj $(TEST_DIR)\*.exe + @@ -0,0 +1,50 @@ +## Important Changes ## + +### 1.6.0 ### + +`geoipupdate` is removed from the GeoIP C library. + +Please use the seperate tool [geoipupdate](https://github.com/maxmind/geoipupdate) to download your subscriptions or our +free databases. + +### 1.5.0 ### + +Geoipupdate may be used to download our free databases. + +Put this into the config file /usr/local/etc/GeoIP.conf +to download the free GeoLite databases GeoLiteCountry, GeoLiteCity and GeoLiteASNum + +``` +LicenseKey 000000000000 +UserId 999999 +ProductIds 506 533 517 +``` + +Free users should create symlinks for the GeoIP databases. +For example: + +``` +cd /usr/local/share/GeoIP +ln -s GeoLiteCity.dat GeoIPCity.dat +ln -s GeoLiteCountry.dat GeoIPCountry.dat +ln -s GeoLiteASNum.dat GeoIPASNum.dat +``` + +The lookup functions are thread safe. + +### 1.3.6 ### + +As of version 1.3.6, the GeoIP C library is thread safe, as long as +`GEOIP_CHECK_CACHE` is not used. + +### 1.3.0 ### + +The GeoIP Region database is no longer a pointer but an in-structure array so +test the first byte of region == 0 rather than testing if the region pointer +is `NULL`. + +### 1.1.0 ### + +As of GeoIP 1.1.0 the GeoIP_country_xxx_by_xxx functions return NULL if a +country can not be found. It previously returned `--` or `N/A`. To avoid +segmentation faults, check the return value for `NULL`. diff --git a/README.OSX b/README.OSX new file mode 100644 index 0000000..2cf30a7 --- /dev/null +++ b/README.OSX @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Building OSX fat binaries is easy. +# +# - start in a clean directory. +# - copy the shell script below to a file and edit the file to your needs. +# +# 1.) modify export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc -arch ppc64' +# to include all architectures you need. +# 2.) add whatever you want to the ./configure line. +# 3.) execute the script. +# 4.) do a 'make install' +# +# +# make clean or make distclean before building this +# +# tell systems before leopard that we like to build for 10.5 or higher +# with MACOSX_DEPLOYMENT_TARGET=10.5 +# starting with leopard we have to add -mmacosx-version-min=10.5 +# to the CFLAGS and export MACOSX_DEPLOYMENT_TARGET!? + +## for tiger, leopard and snow leopard you might use this +## export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc -arch ppc64' +## export MACOSX_DEPLOYMENT_TARGET=10.4 +## export LDFLAGS=$GEOIP_ARCH +## export CFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk $GEOIP_ARCH" + +# here we go for leopard and snow leopard +#export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc' +#export MACOSX_DEPLOYMENT_TARGET=10.5 +#export LDFLAGS=$GEOIP_ARCH +#export CFLAGS="-g -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk $GEOIP_ARCH" +#./configure --disable-dependency-tracking +#perl -i.bak -pe'/^archive_cmds=/ and !/\bGEOIP_ARCH\b/ and s/-dynamiclib\b/-dynamiclib \\\$(GEOIP_ARCH)/' ./libtool +#make + +# and this is lion with the new xcode +#P=`xcode-select -print-path` +#export GEOIP_ARCH='-arch i386 -arch x86_64' +#export MACOSX_DEPLOYMENT_TARGET=10.7 +#export LDFLAGS=$GEOIP_ARCH +#export CFLAGS="-g -mmacosx-version-min=10.7 -isysroot $P/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk $GEOIP_ARCH" +#./configure --disable-dependency-tracking +#make + +# and this is lion with the new xcode +P=`xcode-select -print-path` +export GEOIP_ARCH='-arch x86_64' +export MACOSX_DEPLOYMENT_TARGET=10.9 +export LDFLAGS=$GEOIP_ARCH +export CFLAGS="-g -mmacosx-version-min=10.9 -isysroot $P/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk $GEOIP_ARCH" +./configure --disable-dependency-tracking +make diff --git a/README.dev.md b/README.dev.md new file mode 100644 index 0000000..67deef8 --- /dev/null +++ b/README.dev.md @@ -0,0 +1,35 @@ +## Releasing + +* Make sure https://github.com/github/hub is installed and configured. +* Make sure the `ChangeLog` is up to date. +* Run `dev-bin/release.sh` + +## Ubuntu PPA packages + +0. Switch to the `ubuntu-ppa` branch and merge the release tag from above. + +Release script: + +1. run `dev-bin/ppa-release.sh` + +Manual PPA process: + +1. Type `dch -i` and add the appropriate `debian/changelog` entry. +2. Move tarball created above to a temp directory and + name it `geoip_1.?.?.orig.tar.gz`. +3. Unpack tarball. +4. Copy `debian` directory from Git. (We intentionally do not include it in + the tarball so that we don't interfere with Debian's packaging.) +5. Update `debian/changelog` for the dist you are releasing to, e.g., + precise, trusty, vivid, and prefix the version with the a `~` followed + by the dist name, e.g., `1.6.3-1+maxmind1~trusty`. +6. Run `debuild -S -sa -rfakeroot -k<KEY>`. (The key may not be necessary + if your .bashrc is appropriately ) +7. Run `lintian` to make sure everything looks sane. +8. Run `dput ppa:maxmind/ppa ../<source.changes files created above>` to + upload. +9. Repeat 4-8 for remaining distributions. + +## Homebrew + +* Update the [Homebrew formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/geoip.rb). diff --git a/README.md b/README.md new file mode 100644 index 0000000..debdfb1 --- /dev/null +++ b/README.md @@ -0,0 +1,248 @@ +# GeoIP Legacy C Library # + +## Important Note ## + +This library is for the GeoIP Legacy format (dat). To read the MaxMind DB +format (mmdb) used by GeoIP2, please see +[libmaxminddb](https://github.com/maxmind/libmaxminddb). + +## Description ## + +The GeoIP Legacy C library enables the user to find geographical and network +information of an IP address. To use this library, you may download our free +GeoLite Legacy Country or City databases. These are updated at the beginning +of every month. The latest versions are available at: + +https://dev.maxmind.com/geoip/legacy/geolite + +We also offer commercial GeoIP Legacy databases with greater accuracy and +additional network information. For more details, see: + +https://www.maxmind.com/en/geolocation_landing + +If you use GeoIP Legacy to block access from high risk countries, you may wish +to use our proxy detection service to block access from known proxy servers to +reduce fraud and abuse. For more details, see: + +https://www.maxmind.com/en/proxy + +## IP Geolocation Usage ## + +IP geolocation is inherently imprecise. Locations are often near the center of +the population. Any location provided by a GeoIP database should not be used to +identify a particular address or household. + +## Installation ## + +### On Ubuntu Using PPA ### + +MaxMind provides a PPA for recent version of Ubuntu. To add the PPA to your +APT sources, run: + + $ sudo add-apt-repository ppa:maxmind/ppa + +Then install the packages by running: + + $ sudo apt update + $ sudo apt install libgeoip1 libgeoip-dev geoip-bin + +### From Source on Unix/Linux ### + +To install, run: + +``` +./configure +make +make check +make install +``` + +If you are using a GitHub checkout, please run the `bootstrap` script first +to set up the build environment. + +The GeoIP Legacy C library relies on GNU make, not on BSD make + +### From Source with Visual Studio (nmake) ### + +To make a static GeoIP.lib, edit the top level Makefile.vc to reflect where +the GeoIP.dat database file should be placed, as well as the locations of the +lib, include, and bin directories for installation. + +To build and install, issue the following commands from a developer console: + +``` +nmake /f Makefile.vc +nmake /f Makefile.vc test +nmake /f Makefile.vc install +``` + +### From Source with MinGW ### + +``` +./configure +make +cp data/GeoIP.dat test/ +make check +``` + +Note that GeoIP.dat file should be placed in the same place as GeoIP-enabled +executable modules. + +## Memory Caching and Other Options ## + +There are five options available: + +* `GEOIP_STANDARD` - Read database from file system. This uses the least + memory. +* `GEOIP_MEMORY_CACHE` - Load database into memory. Provides faster + performance but uses more memory. +* `GEOIP_CHECK_CACHE` - Check for updated database. If database has been + updated, reload file handle and/or memory cache. +* `GEOIP_INDEX_CACHE` - Cache only the the most frequently accessed index + portion of the database, resulting in faster lookups than `GEOIP_STANDARD`, + but less memory usage than `GEOIP_MEMORY_CACHE`. This is useful for larger + databases such as GeoIP Legacy Organization and GeoIP Legacy City. Note: for + GeoIP Legacy Country, Region and Netspeed databases, `GEOIP_INDEX_CACHE` is + equivalent to `GEOIP_MEMORY_CACHE`. +* `GEOIP_MMAP_CACHE` - Load database into mmap shared memory. MMAP is not + available for 32bit Windows. +* `GEOIP_SILENCE` - Disables diagnostic messages to stderr in the library; + error conditions are detectable via the return values. + +These options can be combined using bit operators. For example you can +use both `GEOIP_MEMORY_CACHE` and `GEOIP_CHECK_CACHE by calling`: + +```c +GeoIP_open("/path/to/GeoIP.dat", GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE); +``` + +By default, the city name is returned in the ISO-8859-1 charset. To obtain +the city name in UTF-8 instead, run: + +```c +GeoIP_set_charset(gi, GEOIP_CHARSET_UTF8); +``` + +To get the netmask of the netblock of the last lookup, use +`GeoIP_last_netmask(gi)`. + +## Examples ## + +See the following files for examples of how to use the API: + +``` +test/ + test-geoip.c + test-geoip-region.c + test-geoip-city.c + test-geoip-isp.c + test-geoip-org.c + test-geoip-netspeed.c +``` + +The test-geoip.c program works with both the GeoLite Legacy and GeoIP Legacy +Country databases. The test-geoip-city.c program works with both the GeoLite +Legacy and GeoIP Legacy City databases. The other example programs require the +paid databases available (https://www.maxmind.com/en/geolocation_landing). + +## Troubleshooting ## + +### Autotool Issues ### +In case of trouble building from source with libtool or autotools, update +the generated configuration files by running: + +``` +./bootstrap +``` +or + +``` +autoreconf -vfi +``` +or +``` +aclocal && autoconf && automake --add-missing +``` + +### Threads + +Lookups are thread safe, but libGeoIP does not guard the functions. Do not +drop or change the GeoIP database if other threads might be using the +database. + +The recommended pattern is: + +1. open database with GEOIP_MEMORY_CACHE +2. create_threads(your_thread_entry_function) +3. use the database +4. join_threads +5. close database + +### Thread Safety on Windows ### + +The Windows build is not thread-safe in STANDARD mode because the `pread` is +not thread-safe. + +### Other Build Issues ### + +If you run into trouble building your application with GeoIP Legacy support, +try adding `-fms-extensions` to your `CFLAGS`. If you use Solaris and the +default C compiler, use `-features=extensions` instead. These options enable +unnamed union support to fix problems like: `improper member use: dma_code` or +`'GeoIPRecord' has no member named 'dma_code'`. + +Note that it is recommended that you use GNU make. Also, if you are using +OpenBSD, this library requires OpenBSD 3.1 or greater. + +If you get a "cannot load shared object file: No such file or directory" +error, add the directory `libGeoIP.so` was installed to the `/etc/ld.so.conf` +file and run `ldconfig`. + +#### Solaris #### + +On Solaris, if you get a `ld: fatal: relocations remain against allocatable +but non-writable sections`, try running: + +``` +make clean +./configure --disable-shared +make +``` + +If you get a `ar : command not found` error, make sure that `ar` is in your +path. On Solaris, `ar` is typically found in `/usr/ccs/bin` + + +#### AIX #### + +If you get a `passing argument 3 of 'gethostbyname_r' from incompatible +pointer type` error on AIX, untar a fresh copy of this library and delete the +following two lines from `./configure`: + +``` +#define HAVE_GETHOSTBYNAME_R 1 + +#define GETHOSTBYNAME_R_RETURNS_INT 1 +``` + +then save the configure script and build it as usual: + +``` +./configure +make +sudo make install +``` + +## Bug Tracker ## + +Please report all issues with this code using the +[GitHub issue tracker](https://github.com/maxmind/geoip-api-c/issues). + +If you are having an issue with a MaxMind database that is not specific to +this API, please +[contact MaxMind support](https://www.maxmind.com/en/support). + +## Contributing ## + +To contribute, please submit a pull request on +[GitHub](https://github.com/maxmind/geoip-api-c/). diff --git a/apps/Makefile.am b/apps/Makefile.am new file mode 100644 index 0000000..6e2a49c --- /dev/null +++ b/apps/Makefile.am @@ -0,0 +1,18 @@ +AM_CPPFLAGS = -I$(top_srcdir)/libGeoIP -DSYSCONFDIR=\"$(sysconfdir)\" -Wall + +DEPS = $(top_builddir)/libGeoIP/libGeoIP.la +LDADDS = $(top_builddir)/libGeoIP/libGeoIP.la + +bin_PROGRAMS = geoiplookup geoiplookup6 + +geoiplookup_SOURCES = geoiplookup.c +geoiplookup_LDFLAGS = +geoiplookup_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la + +geoiplookup6_SOURCES = geoiplookup6.c +geoiplookup6_LDFLAGS = +geoiplookup6_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup6_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la + +EXTRA_DIST = Makefile.vc diff --git a/apps/Makefile.vc b/apps/Makefile.vc new file mode 100644 index 0000000..266a931 --- /dev/null +++ b/apps/Makefile.vc @@ -0,0 +1,25 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +COMPILER=cl + +LINK = link -nologo + +CFLAGS=-DWIN32 -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) + +GEOIPLIB = ..\libGeoIP\GeoIP.lib + +EXTRA_LIBS= advapi32.lib wsock32.lib + +AR=lib + +APPS: geoiplookup.exe + +geoiplookup.exe: geoiplookup.c + $(CC1) -c geoiplookup.c + $(LINK) geoiplookup.obj $(GEOIPLIB) + diff --git a/apps/geoiplookup.c b/apps/geoiplookup.c new file mode 100644 index 0000000..1c412ea --- /dev/null +++ b/apps/geoiplookup.c @@ -0,0 +1,375 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* geoiplookup.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" +#include "GeoIP_internal.h" + +#if defined(_WIN32) +#ifndef uint32_t +typedef unsigned int uint32_t; +#endif +#endif + +void geoiplookup(GeoIP *gi, char *hostname, int i); + +void usage(void) { + fprintf(stderr, + "Usage: geoiplookup [-h] [-?] [-d custom_dir] [-f " + "custom_file] [-v] [-i] [-l] <ipaddress|hostname>\n"); +} + +/* extra info used in _say_range_ip */ +int info_flag = 0; + +int main(int argc, char *argv[]) { + char *hostname = NULL; + char *db_info; + GeoIP *gi; + int i; + char *custom_directory = NULL; + char *custom_file = NULL; + int version_flag = 0; + int charset = GEOIP_CHARSET_UTF8; + + if (argc < 2) { + usage(); + exit(1); + } + i = 1; + while (i < argc) { + if (strcmp(argv[i], "-v") == 0) { + version_flag = 1; + } else if (strcmp(argv[i], "-l") == 0) { + charset = GEOIP_CHARSET_ISO_8859_1; + } else if (strcmp(argv[i], "-i") == 0) { + info_flag = 1; + } else if ((strcmp(argv[i], "-?") == 0) || + (strcmp(argv[i], "-h") == 0)) { + usage(); + exit(0); + } else if (strcmp(argv[i], "-f") == 0) { + if ((i + 1) < argc) { + i++; + custom_file = argv[i]; + } + } else if (strcmp(argv[i], "-d") == 0) { + if ((i + 1) < argc) { + i++; + custom_directory = argv[i]; + } + } else { + hostname = argv[i]; + } + i++; + } + if (hostname == NULL) { + usage(); + exit(1); + } + + if (custom_directory != NULL) { + GeoIP_setup_custom_directory(custom_directory); + } + _GeoIP_setup_dbfilename(); + + if (custom_file != NULL) { + gi = GeoIP_open(custom_file, GEOIP_STANDARD | GEOIP_SILENCE); + + if (NULL == gi) { + printf("%s not available, skipping...\n", custom_file); + } else { + gi->charset = charset; + i = GeoIP_database_edition(gi); + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", + GeoIPDBDescription[i], + db_info == NULL ? "" : db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } else { + /* iterate through different database types */ + for (i = 0; i < NUM_DB_TYPES; ++i) { + if (GeoIP_db_avail(i)) { + gi = GeoIP_open_type(i, GEOIP_STANDARD | GEOIP_SILENCE); + if (NULL == gi) { + /* Ignore these errors. It's possible + * to use the same database name for + * different databases. + */ + ; + } else { + gi->charset = charset; + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", + GeoIPDBDescription[i], + db_info == NULL ? "" : db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } + } + } + return 0; +} + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +static unsigned long __addr_to_num(const char *addr) { + unsigned int c, octet, t; + unsigned long ipnum; + int i = 3; + + octet = ipnum = 0; + while ((c = *addr++)) { + if (c == '.') { + if (octet > 255) { + return 0; + } + ipnum <<= 8; + ipnum += octet; + i--; + octet = 0; + } else { + t = octet; + octet <<= 3; + octet += t; + octet += t; + c -= '0'; + if (c > 9) { + return 0; + } + octet += c; + } + } + if ((octet > 255) || (i != 0)) { + return 0; + } + ipnum <<= 8; + return ipnum + octet; +} + +/* ptr must be a memory area with at least 16 bytes */ +static char *__num_to_addr_r(unsigned long ipnum, char *ptr) { + char *cur_str; + int octet[4]; + int num_chars_written, i; + + cur_str = ptr; + + for (i = 0; i < 4; i++) { + octet[3 - i] = ipnum % 256; + ipnum >>= 8; + } + + for (i = 0; i < 4; i++) { + num_chars_written = sprintf(cur_str, "%d", octet[i]); + cur_str += num_chars_written; + + if (i < 3) { + cur_str[0] = '.'; + cur_str++; + } + } + + return ptr; +} + +void _say_range_by_ip(GeoIP *gi, uint32_t ipnum) { + unsigned long last_nm, mask, low, hi; + char ipaddr[16]; + char tmp[16]; + char **range; + + if (info_flag == 0) { + return; /* noop unless extra information is requested */ + } + range = GeoIP_range_by_ip(gi, __num_to_addr_r(ipnum, ipaddr)); + if (range == NULL) { + return; + } + + printf(" ipaddr: %s\n", ipaddr); + + printf(" range_by_ip: %s - %s\n", range[0], range[1]); + last_nm = GeoIP_last_netmask(gi); + mask = 0xffffffff << (32 - last_nm); + low = ipnum & mask; + hi = low + (0xffffffff & ~mask); + printf(" network: %s - %s ::%ld\n", + __num_to_addr_r(low, ipaddr), + __num_to_addr_r(hi, tmp), + last_nm); + printf(" ipnum: %u\n", ipnum); + printf(" range_by_num: %lu - %lu\n", + __addr_to_num(range[0]), + __addr_to_num(range[1])); + printf(" network num: %lu - %lu ::%lu\n", low, hi, last_nm); + + GeoIP_range_by_ip_delete(range); +} + +void geoiplookup(GeoIP *gi, char *hostname, int i) { + const char *country_code; + const char *country_name; + const char *domain_name; + const char *asnum_name; + int netspeed; + int country_id; + GeoIPRegion *region; + GeoIPRecord *gir; + const char *org; + uint32_t ipnum; + + ipnum = _GeoIP_lookupaddress(hostname); + if (ipnum == 0) { + printf("%s: can't resolve hostname ( %s )\n", + GeoIPDBDescription[i], + hostname); + } else { + if (GEOIP_DOMAIN_EDITION == i) { + domain_name = GeoIP_name_by_ipnum(gi, ipnum); + if (domain_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], domain_name); + _say_range_by_ip(gi, ipnum); + free((void *)domain_name); + } + } else if (GEOIP_LOCATIONA_EDITION == i || + GEOIP_ACCURACYRADIUS_EDITION == i || + GEOIP_ASNUM_EDITION == i || GEOIP_USERTYPE_EDITION == i || + GEOIP_REGISTRAR_EDITION == i || + GEOIP_NETSPEED_EDITION_REV1 == i || + GEOIP_COUNTRYCONF_EDITION == i || + GEOIP_CITYCONF_EDITION == i || + GEOIP_REGIONCONF_EDITION == i || + GEOIP_POSTALCONF_EDITION == i) { + asnum_name = GeoIP_name_by_ipnum(gi, ipnum); + if (asnum_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], asnum_name); + _say_range_by_ip(gi, ipnum); + free((void *)asnum_name); + } + } else if (GEOIP_COUNTRY_EDITION == i) { + country_id = GeoIP_id_by_ipnum(gi, ipnum); + if (country_id < 0 || country_id >= (int)GeoIP_num_countries()) { + printf("%s: Invalid database\n", GeoIPDBDescription[i]); + return; + } + country_code = GeoIP_country_code[country_id]; + country_name = GeoIP_country_name[country_id]; + if (country_id == 0) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s\n", + GeoIPDBDescription[i], + country_code, + country_name); + _say_range_by_ip(gi, ipnum); + } + } else if (GEOIP_REGION_EDITION_REV0 == i || + GEOIP_REGION_EDITION_REV1 == i) { + region = GeoIP_region_by_ipnum(gi, ipnum); + if (NULL == region || region->country_code[0] == '\0') { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s\n", + GeoIPDBDescription[i], + region->country_code, + region->region); + _say_range_by_ip(gi, ipnum); + } + if (region) { + GeoIPRegion_delete(region); + } + } else if (GEOIP_CITY_EDITION_REV0 == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %s, %f, %f\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } else if (GEOIP_CITY_EDITION_REV1 == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %s, %f, %f, %d, %d\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude, + gir->metro_code, + gir->area_code); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } else if (GEOIP_ORG_EDITION == i || GEOIP_ISP_EDITION == i) { + org = GeoIP_org_by_ipnum(gi, ipnum); + if (org == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], org); + _say_range_by_ip(gi, ipnum); + free((void *)org); + } + } else if (GEOIP_NETSPEED_EDITION == i) { + netspeed = GeoIP_id_by_ipnum(gi, ipnum); + if (netspeed == GEOIP_UNKNOWN_SPEED) { + printf("%s: Unknown\n", GeoIPDBDescription[i]); + } else if (netspeed == GEOIP_DIALUP_SPEED) { + printf("%s: Dialup\n", GeoIPDBDescription[i]); + } else if (netspeed == GEOIP_CABLEDSL_SPEED) { + printf("%s: Cable/DSL\n", GeoIPDBDescription[i]); + } else if (netspeed == GEOIP_CORPORATE_SPEED) { + printf("%s: Corporate\n", GeoIPDBDescription[i]); + } + _say_range_by_ip(gi, ipnum); + } + } +} diff --git a/apps/geoiplookup6.c b/apps/geoiplookup6.c new file mode 100644 index 0000000..fe81d98 --- /dev/null +++ b/apps/geoiplookup6.c @@ -0,0 +1,195 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* geoiplookup.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" +#include "GeoIP_internal.h" +void geoiplookup(GeoIP *gi, char *hostname, int i); + +void usage(void) { + fprintf(stderr, + "Usage: geoiplookup [-h] [-d custom_dir] [-f custom_file] " + "[-v] <ipaddress|hostname>\n"); +} + +int main(int argc, char *argv[]) { + char *hostname = NULL; + char *db_info; + GeoIP *gi; + int i; + char *custom_directory = NULL; + char *custom_file = NULL; + int version_flag = 0; + + if (argc < 2) { + usage(); + exit(1); + } + i = 1; + while (i < argc) { + if (strcmp(argv[i], "-v") == 0) { + version_flag = 1; + } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) { + usage(); + exit(0); + } else if (strcmp(argv[i], "-f") == 0) { + if ((i + 1) < argc) { + i++; + custom_file = argv[i]; + } + } else if (strcmp(argv[i], "-d") == 0) { + if ((i + 1) < argc) { + i++; + custom_directory = argv[i]; + } + } else { + hostname = argv[i]; + } + i++; + } + if (hostname == NULL) { + usage(); + exit(1); + } + + if (custom_directory != NULL) { + GeoIP_setup_custom_directory(custom_directory); + } + _GeoIP_setup_dbfilename(); + + if (custom_file != NULL) { + gi = GeoIP_open(custom_file, GEOIP_STANDARD | GEOIP_SILENCE); + if (NULL == gi) { + printf("%s not available, skipping...\n", custom_file); + } else { + i = GeoIP_database_edition(gi); + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", + GeoIPDBDescription[i], + db_info == NULL ? "" : db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } else { + /* iterate through different database types */ + for (i = 0; i < NUM_DB_TYPES; ++i) { + if (GeoIP_db_avail(i)) { + gi = GeoIP_open_type(i, GEOIP_STANDARD | GEOIP_SILENCE); + if (NULL == gi) { + /* Ignore these errors. It's possible + * to use the same database name for + * different databases. + */ + ; + } else { + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", GeoIPDBDescription[i], db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } + } + } + return 0; +} + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +void geoiplookup(GeoIP *gi, char *hostname, int i) { + const char *country_code; + const char *country_name; + const char *asnum_name; + int country_id; + GeoIPRecord *gir; + + geoipv6_t ipnum; + ipnum = _GeoIP_lookupaddress_v6(hostname); + if (__GEOIP_V6_IS_NULL(ipnum)) { + printf("%s: can't resolve hostname ( %s )\n", + GeoIPDBDescription[i], + hostname); + } else { + if (GEOIP_LOCATIONA_EDITION_V6 == i || GEOIP_ASNUM_EDITION_V6 == i || + GEOIP_USERTYPE_EDITION_V6 == i || GEOIP_REGISTRAR_EDITION_V6 == i || + GEOIP_DOMAIN_EDITION_V6 == i || GEOIP_ORG_EDITION_V6 == i || + GEOIP_ISP_EDITION_V6 == i || GEOIP_NETSPEED_EDITION_REV1_V6 == i) { + asnum_name = GeoIP_name_by_ipnum_v6(gi, ipnum); + if (asnum_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], asnum_name); + } + } else if (GEOIP_CITY_EDITION_REV0_V6 == i) { + gir = GeoIP_record_by_ipnum_v6(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %f, %f\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude); + } + } else if (GEOIP_CITY_EDITION_REV1_V6 == i) { + gir = GeoIP_record_by_ipnum_v6(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %f, %f, %d, %d\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude, + gir->metro_code, + gir->area_code); + } + } else if (GEOIP_COUNTRY_EDITION_V6 == i) { + country_id = GeoIP_id_by_ipnum_v6(gi, ipnum); + if (country_id < 0 || country_id >= (int)GeoIP_num_countries()) { + printf("%s: Invalid database\n", GeoIPDBDescription[i]); + return; + } + country_code = GeoIP_country_code[country_id]; + country_name = GeoIP_country_name[country_id]; + if (country_id == 0) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s\n", + GeoIPDBDescription[i], + country_code, + country_name); + } + } + } +} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..ddeb7ca --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,20 @@ +--- +install: + - '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64' +build_script: + - nmake /f Makefile.vc +notifications: + - incoming_webhook: + secure: 8FZP/RE3nS77Yi5UWOB/DQKCRSJxh/BYrLjVPEAkBG6mRojCz3r2mnla4O/5GwzDr7V6XCpxCP0xo1buCcZRIzRN0ZUWJ5hzEQqW5u7R+vM= + channel: ci + on_build_failure: true + on_build_status_changed: true + on_build_success: true + provider: Slack + - on_build_failure: true + on_build_status_changed: true + on_build_success: false + provider: Email + subject: 'AppVeyor build {{status}}' + to: + - dev-ci@maxmind.com diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..30fc0f9 --- /dev/null +++ b/bootstrap @@ -0,0 +1,19 @@ +#!/bin/sh + +# make sure to use the installed libtool +rm -f ltmain.sh +autoreconf -fiv + +################################################### +# the steps below may help with outdated toolsets + +# disable dependency trackeing for OS X with multiply arch option's +# automake -i --gnu --add-missing + + +#aclocal \ +#&& automake -i --gnu --add-missing \ +#&& autoconf + +#LIBTOOLIZE=$( which libtoolize glibtoolize | head -1 ) +#$LIBTOOLIZE -f diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..28d098c --- /dev/null +++ b/configure.ac @@ -0,0 +1,77 @@ +dnl AM_CONFIG_HEADER(config.h) + +AC_PREREQ([2.63]) +AC_INIT([GeoIP], [1.6.12],[support@maxmind.com],[GeoIP]) +AC_CONFIG_AUX_DIR([.]) +AC_CONFIG_SRCDIR([libGeoIP/GeoIP.c]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE(1.10.0) +AC_GNU_SOURCE +GEOIP_VERSION_INFO=`echo $VERSION | awk -F. '{ printf "%d:%d:%d", $1+$2, $3, $2 }'` +AC_SUBST(GEOIP_VERSION_INFO) + +AC_PROG_CC +AC_PROG_LIBTOOL + +AC_CHECK_TYPE(byte,[AC_DEFINE(HAVE_BYTE_TYPEDEF)],[]) +AC_CHECK_TYPE(ushort,[AC_DEFINE(HAVE_USHORT_TYPEDEF)],[]) +AC_CHECK_TYPE(ulong,[AC_DEFINE(HAVE_ULONG_TYPEDEF)],[]) +AC_CHECK_TYPE(u16,[AC_DEFINE(HAVE_U16_TYPEDEF)],[]) +AC_CHECK_TYPE(u32,[AC_DEFINE(HAVE_U32_TYPEDEF)],[]) + +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T + +AC_C_BIGENDIAN([AC_DEFINE(BIG_ENDIAN_HOST,1)],[AC_DEFINE(LITTLE_ENDIAN_HOST,1)]) + +AC_CHECK_FUNC(getopt, AC_DEFINE(HAVE_GETOPT)) +AC_CHECK_FUNC(gettimeofday, AC_DEFINE(HAVE_GETTIMEOFDAY)) +AC_CHECK_FUNC(pread, AC_DEFINE(HAVE_PREAD)) +AC_CHECK_FUNC(vasprintf, AC_DEFINE(HAVE_VASPRINTF)) +AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF)) +AC_CHECK_FUNC(vsprintf, AC_DEFINE(HAVE_VSPRINTF)) + +AC_CHECK_FUNC(gethostbyname, AC_DEFINE(HAVE_GETHOSTBYNAME), + AC_CHECK_LIB(nsl, gethostbyname, AC_DEFINE(HAVE_GETHOSTBYNAME) + LIBS="${LIBS} -lsocket -lnsl")) + +AC_CHECK_FUNC(gethostbyname_r, [ + AC_DEFINE(HAVE_GETHOSTBYNAME_R) + # We look for the one that returns `int'. + # Hopefully this check is robust enough. + AC_EGREP_HEADER(int.*gethostbyname_r, netdb.h, [ + AC_DEFINE(GETHOSTBYNAME_R_RETURNS_INT)]) + ]) + +AC_CHECK_FUNCS([ memset memchr munmap strrchr socket strchr strdup strstr ]) + +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_MMAP + +AC_ARG_ENABLE([data-files], + AS_HELP_STRING([--disable-data-files], [Install library without installing data files])) + +AS_IF([test "x$enable_data_files" != xno], + AC_SUBST([GEOIP_DB_FILE],[GeoIP.dat])) + +case $host_os in + mingw* ) + # To do: Check for and add -Wl,--high-entropy-va if it's supported. + LDFLAGS="$LDFLAGS -lwsock32 -lws2_32 -Wl,--dynamicbase -Wl,--nxcompat" + ;; +esac + + +AC_OUTPUT([ +Makefile +GeoIP.spec +geoip.pc +libGeoIP/Makefile +apps/Makefile +man/Makefile +test/Makefile +]) diff --git a/data/GeoIP.dat b/data/GeoIP.dat Binary files differnew file mode 100644 index 0000000..a092ad7 --- /dev/null +++ b/data/GeoIP.dat diff --git a/dev-bin/clang-format-all.sh b/dev-bin/clang-format-all.sh new file mode 100755 index 0000000..b8bec61 --- /dev/null +++ b/dev-bin/clang-format-all.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +format="clang-format -i -style=file" + +for dir in apps libGeoIP test; do + c_files=`find $dir -maxdepth 1 -name '*.c'` + if [ "$c_files" != "" ]; then + $format $dir/*.c; + fi + + h_files=`find $dir -maxdepth 1 -name '*.h'` + if [ "$h_files" != "" ]; then + $format $dir/*.h; + fi +done diff --git a/dev-bin/release.sh b/dev-bin/release.sh new file mode 100755 index 0000000..ec6ccfa --- /dev/null +++ b/dev-bin/release.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +set -eu -o pipefail + +changelog=$(cat ChangeLog) + +regex='([0-9]+\.[0-9]+\.[0-9]+) ([0-9]{4}-[0-9]{2}-[0-9]{2}) + +((.| +)*) +' + +if [[ ! $changelog =~ $regex ]]; then + echo "Could not find date line in change log!" + exit 1 +fi + +version="${BASH_REMATCH[1]}" +date="${BASH_REMATCH[2]}" +notes="$(echo "${BASH_REMATCH[3]}" | sed -n -e '/^[0-9]\+\.[0-9]\+\.[0-9]\+/,$!p')" + +dist="GeoIP-$version.tar.gz" + +if [[ "$date" != $(date +"%Y-%m-%d") ]]; then + echo "$date is not today!" + exit 1 +fi + +if [ -n "$(git status --porcelain)" ]; then + echo ". is not clean." >&2 + exit 1 +fi + +perl -pi -e "s/(?<=AC_INIT\(\[GeoIP\], \[)(\d+\.\d+\.\d+)(?=])/$version/gsm" configure.ac + +if [ -n "$(git status --porcelain)" ]; then + git add configure.ac + git commit -m "Bumped version to $version" +fi + +./bootstrap +./configure +make +make check +make clean +make dist + +read -p "Push to origin? (y/n) " should_push + +if [ "$should_push" != "y" ]; then + echo "Aborting" + exit 1 +fi + +git push + +message="$version + +$notes" + +hub release create -a "$dist" -m "$message" "v$version" diff --git a/geoip.ico b/geoip.ico Binary files differnew file mode 100644 index 0000000..ac13353 --- /dev/null +++ b/geoip.ico diff --git a/geoip.pc.in b/geoip.pc.in new file mode 100644 index 0000000..31b8fff --- /dev/null +++ b/geoip.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@prefix@ +libdir=@libdir@ +includedir=@includedir@ +datadir=@datarootdir@ + +Name: geoip +Description: A non-DNS IP-to-country resolver library. +Version: @VERSION@ +Libs: -L${libdir} -lGeoIP +Cflags: -I${includedir}/ +databasedir=${datadir}/GeoIP diff --git a/get_ver.awk b/get_ver.awk new file mode 100644 index 0000000..0314881 --- /dev/null +++ b/get_ver.awk @@ -0,0 +1,14 @@ +# fetch version number from input file and write them to STDOUT
+BEGIN {
+ while ((getline < ARGV[1]) > 0) {
+ if (match ($0, /^VERSION=/)) {
+ split($1, t, "=");
+ my_ver_str = t[2];
+ split(my_ver_str, v, ".");
+ gsub("[^0-9].*$", "", v[3]);
+ my_ver = v[1] "," v[2] "," v[3];
+ }
+ }
+ print "GEOIP_VERSION = " my_ver "";
+ print "GEOIP_VERSION_STR = " my_ver_str "";
+}
diff --git a/libGeoIP/GeoIP.c b/libGeoIP/GeoIP.c new file mode 100644 index 0000000..587326a --- /dev/null +++ b/libGeoIP/GeoIP.c @@ -0,0 +1,2766 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIP_internal.h" + +static geoipv6_t IPV6_NULL; + +#if defined(_WIN32) +#include <io.h> + +#ifdef _MSC_VER +#if _MSC_VER < 1900 // VS 2015 supports snprintf +#define snprintf _snprintf +#endif +#if _MSC_VER >= 1400 // VS 2005+ deprecates fileno, lseek and read +#define fileno _fileno +#define read _read +#define lseek _lseek +#endif +#endif +#else +#include <netdb.h> +#include <sys/mman.h> +#include <unistd.h> +#endif /* defined(_WIN32) */ + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> /* for fstat */ +#include <sys/types.h> /* for fstat */ + +#ifdef HAVE_GETTIMEOFDAY +#include <sys/time.h> /* for gettimeofday */ +#endif + +#ifdef HAVE_STDINT_H +#include <stdint.h> /* For uint32_t */ +#endif + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "pread.h" +#endif + +#ifdef _UNUSED +#elif defined(__GNUC__) +#define _UNUSED __attribute__((unused)) +#else +#define _UNUSED +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif + +#define COUNTRY_BEGIN 16776960 +#define LARGE_COUNTRY_BEGIN 16515072 +#define STATE_BEGIN_REV0 16700000 +#define STATE_BEGIN_REV1 16000000 +#define STRUCTURE_INFO_MAX_SIZE 20 +#define DATABASE_INFO_MAX_SIZE 100 +#define MAX_ORG_RECORD_LENGTH 300 +#define US_OFFSET 1 +#define CANADA_OFFSET 677 +#define WORLD_OFFSET 1353 +#define FIPS_RANGE 360 + +#define DEBUG_MSGF(flags, fmt, ...) \ + { \ + if (((flags)&GEOIP_SILENCE) == 0) { \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + } \ + } + +#ifndef HAVE_PREAD +#define pread(fd, buf, count, offset) \ + (lseek(fd, offset, SEEK_SET) == offset ? read(fd, buf, count) : -1) +#endif /* HAVE_PREAD */ + +const char GeoIP_country_code[256][3] = { + "--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "CW", "AO", + "AQ", "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", + "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", + "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", + "CN", "CO", "CR", "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", + "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", + "FM", "FO", "FR", "SX", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", + "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", + "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", + "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", + "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", + "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", "MO", + "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", + "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", + "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", + "PW", "PY", "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", + "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", + "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", + "TL", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", + "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "RS", + "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", "AX", "GG", "IM", "JE", "BL", + "MF", "BQ", "SS", "O1"}; + +static const unsigned num_GeoIP_countries = + (unsigned)(sizeof(GeoIP_country_code) / sizeof(GeoIP_country_code[0])); + +const char GeoIP_country_code3[256][4] = { + "--", "AP", "EU", "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", "CUW", + "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "AZE", "BIH", "BRB", "BGD", + "BEL", "BFA", "BGR", "BHR", "BDI", "BEN", "BMU", "BRN", "BOL", "BRA", "BHS", + "BTN", "BVT", "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", "CHE", + "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", "CUB", "CPV", "CXR", "CYP", + "CZE", "DEU", "DJI", "DNK", "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", + "ERI", "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", "SXM", "GAB", + "GBR", "GRD", "GEO", "GUF", "GHA", "GIB", "GRL", "GMB", "GIN", "GLP", "GNQ", + "GRC", "SGS", "GTM", "GUM", "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", + "HUN", "IDN", "IRL", "ISR", "IND", "IOT", "IRQ", "IRN", "ISL", "ITA", "JAM", + "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", "COM", "KNA", "PRK", "KOR", "KWT", + "CYM", "KAZ", "LAO", "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX", + "LVA", "LBY", "MAR", "MCO", "MDA", "MDG", "MHL", "MKD", "MLI", "MMR", "MNG", + "MAC", "MNP", "MTQ", "MRT", "MSR", "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", + "MOZ", "NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", "NRU", + "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", "PHL", "PAK", "POL", "SPM", + "PCN", "PRI", "PSE", "PRT", "PLW", "PRY", "QAT", "REU", "ROU", "RUS", "RWA", + "SAU", "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", "SVK", "SLE", + "SMR", "SEN", "SOM", "SUR", "STP", "SLV", "SYR", "SWZ", "TCA", "TCD", "ATF", + "TGO", "THA", "TJK", "TKL", "TKM", "TUN", "TON", "TLS", "TUR", "TTO", "TUV", + "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", "VAT", "VCT", "VEN", + "VGB", "VIR", "VNM", "VUT", "WLF", "WSM", "YEM", "MYT", "SRB", "ZAF", "ZMB", + "MNE", "ZWE", "A1", "A2", "O1", "ALA", "GGY", "IMN", "JEY", "BLM", "MAF", + "BES", "SSD", "O1"}; + +const char *GeoIP_utf8_country_name[256] = { + "N/A", + "Asia/Pacific Region", + "Europe", + "Andorra", + "United Arab Emirates", + "Afghanistan", + "Antigua and Barbuda", + "Anguilla", + "Albania", + "Armenia", + "Cura" + "\xc3\xa7" + "ao", + "Angola", + "Antarctica", + "Argentina", + "American Samoa", + "Austria", + "Australia", + "Aruba", + "Azerbaijan", + "Bosnia and Herzegovina", + "Barbados", + "Bangladesh", + "Belgium", + "Burkina Faso", + "Bulgaria", + "Bahrain", + "Burundi", + "Benin", + "Bermuda", + "Brunei Darussalam", + "Bolivia", + "Brazil", + "Bahamas", + "Bhutan", + "Bouvet Island", + "Botswana", + "Belarus", + "Belize", + "Canada", + "Cocos (Keeling) Islands", + "Congo, The Democratic Republic of the", + "Central African Republic", + "Congo", + "Switzerland", + "Cote D'Ivoire", + "Cook Islands", + "Chile", + "Cameroon", + "China", + "Colombia", + "Costa Rica", + "Cuba", + "Cape Verde", + "Christmas Island", + "Cyprus", + "Czech Republic", + "Germany", + "Djibouti", + "Denmark", + "Dominica", + "Dominican Republic", + "Algeria", + "Ecuador", + "Estonia", + "Egypt", + "Western Sahara", + "Eritrea", + "Spain", + "Ethiopia", + "Finland", + "Fiji", + "Falkland Islands (Malvinas)", + "Micronesia, Federated States of", + "Faroe Islands", + "France", + "Sint Maarten (Dutch part)", + "Gabon", + "United Kingdom", + "Grenada", + "Georgia", + "French Guiana", + "Ghana", + "Gibraltar", + "Greenland", + "Gambia", + "Guinea", + "Guadeloupe", + "Equatorial Guinea", + "Greece", + "South Georgia and the South Sandwich Islands", + "Guatemala", + "Guam", + "Guinea-Bissau", + "Guyana", + "Hong Kong", + "Heard Island and McDonald Islands", + "Honduras", + "Croatia", + "Haiti", + "Hungary", + "Indonesia", + "Ireland", + "Israel", + "India", + "British Indian Ocean Territory", + "Iraq", + "Iran, Islamic Republic of", + "Iceland", + "Italy", + "Jamaica", + "Jordan", + "Japan", + "Kenya", + "Kyrgyzstan", + "Cambodia", + "Kiribati", + "Comoros", + "Saint Kitts and Nevis", + "Korea, Democratic People's Republic of", + "Korea, Republic of", + "Kuwait", + "Cayman Islands", + "Kazakhstan", + "Lao People's Democratic Republic", + "Lebanon", + "Saint Lucia", + "Liechtenstein", + "Sri Lanka", + "Liberia", + "Lesotho", + "Lithuania", + "Luxembourg", + "Latvia", + "Libya", + "Morocco", + "Monaco", + "Moldova, Republic of", + "Madagascar", + "Marshall Islands", + "Macedonia", + "Mali", + "Myanmar", + "Mongolia", + "Macau", + "Northern Mariana Islands", + "Martinique", + "Mauritania", + "Montserrat", + "Malta", + "Mauritius", + "Maldives", + "Malawi", + "Mexico", + "Malaysia", + "Mozambique", + "Namibia", + "New Caledonia", + "Niger", + "Norfolk Island", + "Nigeria", + "Nicaragua", + "Netherlands", + "Norway", + "Nepal", + "Nauru", + "Niue", + "New Zealand", + "Oman", + "Panama", + "Peru", + "French Polynesia", + "Papua New Guinea", + "Philippines", + "Pakistan", + "Poland", + "Saint Pierre and Miquelon", + "Pitcairn Islands", + "Puerto Rico", + "Palestinian Territory", + "Portugal", + "Palau", + "Paraguay", + "Qatar", + "Reunion", + "Romania", + "Russian Federation", + "Rwanda", + "Saudi Arabia", + "Solomon Islands", + "Seychelles", + "Sudan", + "Sweden", + "Singapore", + "Saint Helena", + "Slovenia", + "Svalbard and Jan Mayen", + "Slovakia", + "Sierra Leone", + "San Marino", + "Senegal", + "Somalia", + "Suriname", + "Sao Tome and Principe", + "El Salvador", + "Syrian Arab Republic", + "Swaziland", + "Turks and Caicos Islands", + "Chad", + "French Southern Territories", + "Togo", + "Thailand", + "Tajikistan", + "Tokelau", + "Turkmenistan", + "Tunisia", + "Tonga", + "Timor-Leste", + "Turkey", + "Trinidad and Tobago", + "Tuvalu", + "Taiwan", + "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", + "Virgin Islands, British", + "Virgin Islands, U.S.", + "Vietnam", + "Vanuatu", + "Wallis and Futuna", + "Samoa", + "Yemen", + "Mayotte", + "Serbia", + "South Africa", + "Zambia", + "Montenegro", + "Zimbabwe", + "Anonymous Proxy", + "Satellite Provider", + "Other", + "Aland Islands", + "Guernsey", + "Isle of Man", + "Jersey", + "Saint Barthelemy", + "Saint Martin", + "Bonaire, Saint Eustatius and Saba", + "South Sudan", + "Other"}; + +const char *GeoIP_country_name[256] = { + "N/A", + "Asia/Pacific Region", + "Europe", + "Andorra", + "United Arab Emirates", + "Afghanistan", + "Antigua and Barbuda", + "Anguilla", + "Albania", + "Armenia", + "Curacao", + "Angola", + "Antarctica", + "Argentina", + "American Samoa", + "Austria", + "Australia", + "Aruba", + "Azerbaijan", + "Bosnia and Herzegovina", + "Barbados", + "Bangladesh", + "Belgium", + "Burkina Faso", + "Bulgaria", + "Bahrain", + "Burundi", + "Benin", + "Bermuda", + "Brunei Darussalam", + "Bolivia", + "Brazil", + "Bahamas", + "Bhutan", + "Bouvet Island", + "Botswana", + "Belarus", + "Belize", + "Canada", + "Cocos (Keeling) Islands", + "Congo, The Democratic Republic of the", + "Central African Republic", + "Congo", + "Switzerland", + "Cote D'Ivoire", + "Cook Islands", + "Chile", + "Cameroon", + "China", + "Colombia", + "Costa Rica", + "Cuba", + "Cape Verde", + "Christmas Island", + "Cyprus", + "Czech Republic", + "Germany", + "Djibouti", + "Denmark", + "Dominica", + "Dominican Republic", + "Algeria", + "Ecuador", + "Estonia", + "Egypt", + "Western Sahara", + "Eritrea", + "Spain", + "Ethiopia", + "Finland", + "Fiji", + "Falkland Islands (Malvinas)", + "Micronesia, Federated States of", + "Faroe Islands", + "France", + "Sint Maarten (Dutch part)", + "Gabon", + "United Kingdom", + "Grenada", + "Georgia", + "French Guiana", + "Ghana", + "Gibraltar", + "Greenland", + "Gambia", + "Guinea", + "Guadeloupe", + "Equatorial Guinea", + "Greece", + "South Georgia and the South Sandwich Islands", + "Guatemala", + "Guam", + "Guinea-Bissau", + "Guyana", + "Hong Kong", + "Heard Island and McDonald Islands", + "Honduras", + "Croatia", + "Haiti", + "Hungary", + "Indonesia", + "Ireland", + "Israel", + "India", + "British Indian Ocean Territory", + "Iraq", + "Iran, Islamic Republic of", + "Iceland", + "Italy", + "Jamaica", + "Jordan", + "Japan", + "Kenya", + "Kyrgyzstan", + "Cambodia", + "Kiribati", + "Comoros", + "Saint Kitts and Nevis", + "Korea, Democratic People's Republic of", + "Korea, Republic of", + "Kuwait", + "Cayman Islands", + "Kazakhstan", + "Lao People's Democratic Republic", + "Lebanon", + "Saint Lucia", + "Liechtenstein", + "Sri Lanka", + "Liberia", + "Lesotho", + "Lithuania", + "Luxembourg", + "Latvia", + "Libya", + "Morocco", + "Monaco", + "Moldova, Republic of", + "Madagascar", + "Marshall Islands", + "Macedonia", + "Mali", + "Myanmar", + "Mongolia", + "Macau", + "Northern Mariana Islands", + "Martinique", + "Mauritania", + "Montserrat", + "Malta", + "Mauritius", + "Maldives", + "Malawi", + "Mexico", + "Malaysia", + "Mozambique", + "Namibia", + "New Caledonia", + "Niger", + "Norfolk Island", + "Nigeria", + "Nicaragua", + "Netherlands", + "Norway", + "Nepal", + "Nauru", + "Niue", + "New Zealand", + "Oman", + "Panama", + "Peru", + "French Polynesia", + "Papua New Guinea", + "Philippines", + "Pakistan", + "Poland", + "Saint Pierre and Miquelon", + "Pitcairn Islands", + "Puerto Rico", + "Palestinian Territory", + "Portugal", + "Palau", + "Paraguay", + "Qatar", + "Reunion", + "Romania", + "Russian Federation", + "Rwanda", + "Saudi Arabia", + "Solomon Islands", + "Seychelles", + "Sudan", + "Sweden", + "Singapore", + "Saint Helena", + "Slovenia", + "Svalbard and Jan Mayen", + "Slovakia", + "Sierra Leone", + "San Marino", + "Senegal", + "Somalia", + "Suriname", + "Sao Tome and Principe", + "El Salvador", + "Syrian Arab Republic", + "Swaziland", + "Turks and Caicos Islands", + "Chad", + "French Southern Territories", + "Togo", + "Thailand", + "Tajikistan", + "Tokelau", + "Turkmenistan", + "Tunisia", + "Tonga", + "Timor-Leste", + "Turkey", + "Trinidad and Tobago", + "Tuvalu", + "Taiwan", + "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", + "Virgin Islands, British", + "Virgin Islands, U.S.", + "Vietnam", + "Vanuatu", + "Wallis and Futuna", + "Samoa", + "Yemen", + "Mayotte", + "Serbia", + "South Africa", + "Zambia", + "Montenegro", + "Zimbabwe", + "Anonymous Proxy", + "Satellite Provider", + "Other", + "Aland Islands", + "Guernsey", + "Isle of Man", + "Jersey", + "Saint Barthelemy", + "Saint Martin", + "Bonaire, Saint Eustatius and Saba", + "South Sudan", + "Other"}; + +/* Possible continent codes are AF, AS, EU, NA, OC, SA for Africa, Asia, Europe, + North America, Oceania + and South America. */ + +const char GeoIP_country_continent[256][3] = { + "--", "AS", "EU", "EU", "AS", "AS", "NA", "NA", "EU", "AS", "NA", "AF", + "AN", "SA", "OC", "EU", "OC", "NA", "AS", "EU", "NA", "AS", "EU", "AF", + "EU", "AS", "AF", "AF", "NA", "AS", "SA", "SA", "NA", "AS", "AN", "AF", + "EU", "NA", "NA", "AS", "AF", "AF", "AF", "EU", "AF", "OC", "SA", "AF", + "AS", "SA", "NA", "NA", "AF", "AS", "AS", "EU", "EU", "AF", "EU", "NA", + "NA", "AF", "SA", "EU", "AF", "AF", "AF", "EU", "AF", "EU", "OC", "SA", + "OC", "EU", "EU", "NA", "AF", "EU", "NA", "AS", "SA", "AF", "EU", "NA", + "AF", "AF", "NA", "AF", "EU", "AN", "NA", "OC", "AF", "SA", "AS", "AN", + "NA", "EU", "NA", "EU", "AS", "EU", "AS", "AS", "AS", "AS", "AS", "EU", + "EU", "NA", "AS", "AS", "AF", "AS", "AS", "OC", "AF", "NA", "AS", "AS", + "AS", "NA", "AS", "AS", "AS", "NA", "EU", "AS", "AF", "AF", "EU", "EU", + "EU", "AF", "AF", "EU", "EU", "AF", "OC", "EU", "AF", "AS", "AS", "AS", + "OC", "NA", "AF", "NA", "EU", "AF", "AS", "AF", "NA", "AS", "AF", "AF", + "OC", "AF", "OC", "AF", "NA", "EU", "EU", "AS", "OC", "OC", "OC", "AS", + "NA", "SA", "OC", "OC", "AS", "AS", "EU", "NA", "OC", "NA", "AS", "EU", + "OC", "SA", "AS", "AF", "EU", "EU", "AF", "AS", "OC", "AF", "AF", "EU", + "AS", "AF", "EU", "EU", "EU", "AF", "EU", "AF", "AF", "SA", "AF", "NA", + "AS", "AF", "NA", "AF", "AN", "AF", "AS", "AS", "OC", "AS", "AF", "OC", + "AS", "EU", "NA", "OC", "AS", "AF", "EU", "AF", "OC", "NA", "SA", "AS", + "EU", "NA", "SA", "NA", "NA", "AS", "OC", "OC", "OC", "AS", "AF", "EU", + "AF", "AF", "EU", "AF", "--", "--", "--", "EU", "EU", "EU", "EU", "NA", + "NA", "NA", "AF", "--"}; + +static const char *get_db_description(int dbtype) { + const char *ptr; + if (dbtype >= NUM_DB_TYPES || dbtype < 0) { + return "Unknown"; + } + ptr = GeoIPDBDescription[dbtype]; + return ptr == NULL ? "Unknown" : ptr; +} + +geoipv6_t _GeoIP_lookupaddress_v6(const char *host); + +#if defined(_WIN32) +/* http://www.mail-archive.com/users@ipv6.org/msg02107.html */ +static const char * +_GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { + if (af == AF_INET) { + struct sockaddr_in in; + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + memcpy(&in.sin_addr, src, sizeof(struct in_addr)); + getnameinfo((struct sockaddr *)&in, + sizeof(struct sockaddr_in), + dst, + cnt, + NULL, + 0, + NI_NUMERICHOST); + return dst; + } else if (af == AF_INET6) { + struct sockaddr_in6 in; + memset(&in, 0, sizeof(in)); + in.sin6_family = AF_INET6; + memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); + getnameinfo((struct sockaddr *)&in, + sizeof(struct sockaddr_in6), + dst, + cnt, + NULL, + 0, + NI_NUMERICHOST); + return dst; + } + return NULL; +} + +static int _GeoIP_inet_pton(int af, const char *src, void *dst) { + struct addrinfo hints, *res, *ressave; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + + if (getaddrinfo(src, NULL, &hints, &res) != 0) { + return -1; + } + + ressave = res; + + while (res) { + memcpy(dst, res->ai_addr, res->ai_addrlen); + res = res->ai_next; + } + + freeaddrinfo(ressave); + return 0; +} +#else +static int _GeoIP_inet_pton(int af, const char *src, void *dst) { + return inet_pton(af, src, dst); +} +static const char * +_GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { + return inet_ntop(af, src, dst, cnt); +} +#endif /* defined(_WIN32) */ + +int __GEOIP_V6_IS_NULL(geoipv6_t v6) { + int i; + for (i = 0; i < 16; i++) { + if (v6.s6_addr[i]) { + return 0; + } + } + return 1; +} + +void __GEOIP_PREPARE_TEREDO(geoipv6_t *v6) { + int i; + if ((v6->s6_addr[0]) != 0x20) { + return; + } + if ((v6->s6_addr[1]) != 0x01) { + return; + } + if ((v6->s6_addr[2]) != 0x00) { + return; + } + if ((v6->s6_addr[3]) != 0x00) { + return; + } + + for (i = 0; i < 12; i++) { + v6->s6_addr[i] = 0; + } + for (; i < 16; i++) { + v6->s6_addr[i] ^= 0xff; + } +} + +const char *GeoIPDBDescription[NUM_DB_TYPES] = { + NULL, + "GeoIP Country Edition", + "GeoIP City Edition, Rev 1", + "GeoIP Region Edition, Rev 1", + "GeoIP ISP Edition", + "GeoIP Organization Edition", + "GeoIP City Edition, Rev 0", + "GeoIP Region Edition, Rev 0", + "GeoIP Proxy Edition", + "GeoIP ASNum Edition", + "GeoIP Netspeed Edition", + "GeoIP Domain Name Edition", + "GeoIP Country V6 Edition", + "GeoIP LocationID ASCII Edition", + "GeoIP Accuracy Radius Edition", + NULL, + NULL, + "GeoIP Large Country Edition", + "GeoIP Large Country V6 Edition", + NULL, + "GeoIP CCM Edition", + "GeoIP ASNum V6 Edition", + "GeoIP ISP V6 Edition", + "GeoIP Organization V6 Edition", + "GeoIP Domain Name V6 Edition", + "GeoIP LocationID ASCII V6 Edition", + "GeoIP Registrar Edition", + "GeoIP Registrar V6 Edition", + "GeoIP UserType Edition", + "GeoIP UserType V6 Edition", + "GeoIP City Edition V6, Rev 1", + "GeoIP City Edition V6, Rev 0", + "GeoIP Netspeed Edition, Rev 1", + "GeoIP Netspeed Edition V6, Rev1", + "GeoIP Country Confidence Edition", + "GeoIP City Confidence Edition", + "GeoIP Region Confidence Edition", + "GeoIP Postal Confidence Edition", + "GeoIP Accuracy Radius Edition V6"}; + +char *GeoIP_custom_directory = NULL; + +void GeoIP_setup_custom_directory(char *dir) { GeoIP_custom_directory = dir; } + +char *_GeoIP_full_path_to(const char *file_name) { + int len; + char *path = malloc(sizeof(char) * 1024); + + if (GeoIP_custom_directory == NULL) { +#if !defined(_WIN32) + memset(path, 0, sizeof(char) * 1024); + snprintf( + path, sizeof(char) * 1024 - 1, "%s/%s", GEOIPDATADIR, file_name); +#else + char buf[MAX_PATH], *p, *q = NULL; + memset(buf, 0, sizeof(buf)); + len = GetModuleFileNameA(GetModuleHandle(NULL), buf, sizeof(buf) - 1); + for (p = buf + len; p > buf; p--) { + if (*p == '\\') { + if (!q) { + q = p; + } else { + *p = '/'; + } + } + } + *q = 0; + memset(path, 0, sizeof(char) * 1024); + snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", buf, file_name); +#endif + } else { + len = strlen(GeoIP_custom_directory); + if (GeoIP_custom_directory[len - 1] != '/') { + snprintf(path, + sizeof(char) * 1024 - 1, + "%s/%s", + GeoIP_custom_directory, + file_name); + } else { + snprintf(path, + sizeof(char) * 1024 - 1, + "%s%s", + GeoIP_custom_directory, + file_name); + } + } + return path; +} + +char **GeoIPDBFileName = NULL; + +void _GeoIP_setup_dbfilename(void) { + if (NULL == GeoIPDBFileName) { + GeoIPDBFileName = malloc(sizeof(char *) * NUM_DB_TYPES); + memset(GeoIPDBFileName, 0, sizeof(char *) * NUM_DB_TYPES); + + GeoIPDBFileName[GEOIP_COUNTRY_EDITION] = + _GeoIP_full_path_to("GeoIP.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV0] = + _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV1] = + _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV0] = + _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV1] = + _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_ISP_EDITION] = + _GeoIP_full_path_to("GeoIPISP.dat"); + GeoIPDBFileName[GEOIP_ORG_EDITION] = + _GeoIP_full_path_to("GeoIPOrg.dat"); + GeoIPDBFileName[GEOIP_PROXY_EDITION] = + _GeoIP_full_path_to("GeoIPProxy.dat"); + GeoIPDBFileName[GEOIP_ASNUM_EDITION] = + _GeoIP_full_path_to("GeoIPASNum.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION] = + _GeoIP_full_path_to("GeoIPNetSpeed.dat"); + GeoIPDBFileName[GEOIP_DOMAIN_EDITION] = + _GeoIP_full_path_to("GeoIPDomain.dat"); + GeoIPDBFileName[GEOIP_COUNTRY_EDITION_V6] = + _GeoIP_full_path_to("GeoIPv6.dat"); + GeoIPDBFileName[GEOIP_LOCATIONA_EDITION] = + _GeoIP_full_path_to("GeoIPLocA.dat"); + GeoIPDBFileName[GEOIP_ACCURACYRADIUS_EDITION] = + _GeoIP_full_path_to("GeoIPDistance.dat"); + GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION] = + _GeoIP_full_path_to("GeoIP.dat"); + GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION_V6] = + _GeoIP_full_path_to("GeoIPv6.dat"); + GeoIPDBFileName[GEOIP_ASNUM_EDITION_V6] = + _GeoIP_full_path_to("GeoIPASNumv6.dat"); + GeoIPDBFileName[GEOIP_ISP_EDITION_V6] = + _GeoIP_full_path_to("GeoIPISPv6.dat"); + GeoIPDBFileName[GEOIP_ORG_EDITION_V6] = + _GeoIP_full_path_to("GeoIPOrgv6.dat"); + GeoIPDBFileName[GEOIP_DOMAIN_EDITION_V6] = + _GeoIP_full_path_to("GeoIPDomainv6.dat"); + GeoIPDBFileName[GEOIP_LOCATIONA_EDITION_V6] = + _GeoIP_full_path_to("GeoIPLocAv6.dat"); + GeoIPDBFileName[GEOIP_REGISTRAR_EDITION] = + _GeoIP_full_path_to("GeoIPRegistrar.dat"); + GeoIPDBFileName[GEOIP_REGISTRAR_EDITION_V6] = + _GeoIP_full_path_to("GeoIPRegistrarv6.dat"); + GeoIPDBFileName[GEOIP_USERTYPE_EDITION] = + _GeoIP_full_path_to("GeoIPUserType.dat"); + GeoIPDBFileName[GEOIP_USERTYPE_EDITION_V6] = + _GeoIP_full_path_to("GeoIPUserTypev6.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV0_V6] = + _GeoIP_full_path_to("GeoIPCityv6.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV1_V6] = + _GeoIP_full_path_to("GeoIPCityv6.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1] = + _GeoIP_full_path_to("GeoIPNetSpeedCell.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1_V6] = + _GeoIP_full_path_to("GeoIPNetSpeedCellv6.dat"); + GeoIPDBFileName[GEOIP_COUNTRYCONF_EDITION] = + _GeoIP_full_path_to("GeoIPCountryConf.dat"); + GeoIPDBFileName[GEOIP_CITYCONF_EDITION] = + _GeoIP_full_path_to("GeoIPCityConf.dat"); + GeoIPDBFileName[GEOIP_REGIONCONF_EDITION] = + _GeoIP_full_path_to("GeoIPRegionConf.dat"); + GeoIPDBFileName[GEOIP_POSTALCONF_EDITION] = + _GeoIP_full_path_to("GeoIPPostalConf.dat"); + GeoIPDBFileName[GEOIP_ACCURACYRADIUS_EDITION_V6] = + _GeoIP_full_path_to("GeoIPDistancev6.dat"); + } +} + +static int _file_exists(const char *file_name) { + struct stat file_stat; + return (stat(file_name, &file_stat) == 0) ? 1 : 0; +} + +char *_GeoIP_iso_8859_1__utf8(const char *iso) { + signed char c; + char k; + char *p; + char *t = (char *)iso; + int len = 0; + while ((c = *t++)) { + if (c < 0) { + len++; + } + } + len += t - iso; + t = p = malloc(len); + + if (p) { + while ((c = *iso++)) { + if (c < 0) { + k = (char)0xc2; + if (c >= -64) { + k++; + } + *t++ = k; + c &= ~0x40; + } + *t++ = c; + } + *t++ = 0x00; + } + return p; +} + +int GeoIP_is_private_ipnum_v4(unsigned long ipnum) { + return ((ipnum >= 167772160U && ipnum <= 184549375U) || + (ipnum >= 2851995648U && ipnum <= 2852061183U) || + (ipnum >= 2886729728U && ipnum <= 2887778303U) || + (ipnum >= 3232235520U && ipnum <= 3232301055U) || + (ipnum >= 2130706432U && ipnum <= 2147483647U)) + ? 1 + : 0; +} + +int GeoIP_is_private_v4(const char *addr) { + unsigned long ipnum = GeoIP_addr_to_num(addr); + return GeoIP_is_private_ipnum_v4(ipnum); +} + +int GeoIP_db_avail(int type) { + const char *filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + return 0; + } + _GeoIP_setup_dbfilename(); + filePath = GeoIPDBFileName[type]; + if (NULL == filePath) { + return 0; + } + return _file_exists(filePath); +} + +static int _database_has_content(int database_type) { + return (database_type != GEOIP_COUNTRY_EDITION && + database_type != GEOIP_PROXY_EDITION && + database_type != GEOIP_NETSPEED_EDITION && + database_type != GEOIP_COUNTRY_EDITION_V6 && + database_type != GEOIP_LARGE_COUNTRY_EDITION && + database_type != GEOIP_LARGE_COUNTRY_EDITION_V6 && + database_type != GEOIP_REGION_EDITION_REV0 && + database_type != GEOIP_REGION_EDITION_REV1) + ? 1 + : 0; +} + +static ssize_t get_index_size(GeoIP *gi, struct stat *buf) { + ssize_t index_size; + unsigned int segment; + + if (!_database_has_content(gi->databaseType)) { + return buf->st_size; + } + + segment = gi->databaseSegments[0]; + index_size = segment * (ssize_t)gi->record_length * 2; + + /* check for overflow in multiplication */ + if (segment != 0 && + index_size / segment != (ssize_t)gi->record_length * 2) { + return -1; + } + + /* Index size should never exceed the size of the file */ + if (index_size > buf->st_size) { + return -1; + } + + return index_size; +} + +static void _setup_segments(GeoIP *gi) { + int i, j, segment_record_length; + unsigned char delim[3]; + unsigned char buf[LARGE_SEGMENT_RECORD_LENGTH]; + off_t offset = gi->size - 3; + int fno = fileno(gi->GeoIPDatabase); + + gi->databaseSegments = NULL; + + /* default to GeoIP Country Edition */ + gi->databaseType = GEOIP_COUNTRY_EDITION; + gi->record_length = STANDARD_RECORD_LENGTH; + + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + if (pread(fno, delim, 3, offset) != 3) { + return; + } + offset += 3; + if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) { + if (pread(fno, &gi->databaseType, 1, offset) != 1) { + return; + } + offset++; + if (gi->databaseType >= 106) { + /* backwards compatibility with databases from April 2003 and + * earlier */ + gi->databaseType -= 105; + } + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = STATE_BEGIN_REV0; + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = STATE_BEGIN_REV1; + } else if (gi->databaseType == GEOIP_CITY_EDITION_REV0 || + gi->databaseType == GEOIP_CITY_EDITION_REV1 || + gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ORG_EDITION_V6 || + gi->databaseType == GEOIP_DOMAIN_EDITION || + gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || + gi->databaseType == GEOIP_ISP_EDITION || + gi->databaseType == GEOIP_ISP_EDITION_V6 || + gi->databaseType == GEOIP_REGISTRAR_EDITION || + gi->databaseType == GEOIP_REGISTRAR_EDITION_V6 || + gi->databaseType == GEOIP_USERTYPE_EDITION || + gi->databaseType == GEOIP_USERTYPE_EDITION_V6 || + gi->databaseType == GEOIP_ASNUM_EDITION || + gi->databaseType == GEOIP_ASNUM_EDITION_V6 || + gi->databaseType == GEOIP_NETSPEED_EDITION_REV1 || + gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6 || + gi->databaseType == GEOIP_LOCATIONA_EDITION || + gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION || + gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION_V6 || + gi->databaseType == GEOIP_CITY_EDITION_REV0_V6 || + gi->databaseType == GEOIP_CITY_EDITION_REV1_V6 || + gi->databaseType == GEOIP_CITYCONF_EDITION || + gi->databaseType == GEOIP_COUNTRYCONF_EDITION || + gi->databaseType == GEOIP_REGIONCONF_EDITION || + gi->databaseType == GEOIP_POSTALCONF_EDITION) { + /* City/Org Editions have two segments, read offset of second + * segment */ + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = 0; + segment_record_length = SEGMENT_RECORD_LENGTH; + + if (pread(fno, buf, segment_record_length, offset) != + segment_record_length) { + free(gi->databaseSegments); + gi->databaseSegments = NULL; + return; + } + + for (j = 0; j < segment_record_length; j++) { + gi->databaseSegments[0] += (buf[j] << (j * 8)); + } + + /* the record_length must be correct from here on */ + if (gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ORG_EDITION_V6 || + gi->databaseType == GEOIP_DOMAIN_EDITION || + gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || + gi->databaseType == GEOIP_ISP_EDITION || + gi->databaseType == GEOIP_ISP_EDITION_V6) { + gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + offset -= 4; + if (offset < 0) { + gi->databaseSegments = NULL; + return; + } + } + } + if (gi->databaseType == GEOIP_COUNTRY_EDITION || + gi->databaseType == GEOIP_PROXY_EDITION || + gi->databaseType == GEOIP_NETSPEED_EDITION || + gi->databaseType == GEOIP_COUNTRY_EDITION_V6) { + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = COUNTRY_BEGIN; + } else if (gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION || + gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION_V6) { + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = LARGE_COUNTRY_BEGIN; + } +} + +static void _check_mtime(GeoIP *gi) { + struct stat buf; + ssize_t idx_size; + +#if !defined(_WIN32) + struct timeval t; +#else /* !defined(_WIN32) */ + FILETIME ft; + ULONGLONG t; +#endif /* !defined(_WIN32) */ + + if (gi->flags & GEOIP_CHECK_CACHE) { + +#if !defined(_WIN32) + /* stat only has second granularity, so don't + * call it more than once a second */ + if (0 != gettimeofday(&t, NULL)) { + DEBUG_MSGF( + gi->flags, "Error calling gettimeofday: %s\n", strerror(errno)); + return; + } + + if (t.tv_sec == gi->last_mtime_check) { + return; + } + gi->last_mtime_check = t.tv_sec; + +#else /* !defined(_WIN32) */ + + /* stat only has second granularity, so don't + call it more than once a second */ + GetSystemTimeAsFileTime(&ft); + t = FILETIME_TO_USEC(ft) / 1000 / 1000; + if (t == gi->last_mtime_check) { + return; + } + gi->last_mtime_check = t; + +#endif /* !defined(_WIN32) */ + + if (stat(gi->file_path, &buf) != -1) { + /* make sure that the database file is at least 60 + * seconds untouched. Otherwise we might load the + * database only partly and crash + */ + if (buf.st_mtime != gi->mtime && + (buf.st_mtime + 60 < gi->last_mtime_check)) { + /* GeoIP Database file updated */ + if (gi->flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) { + if (gi->cache && (gi->flags & GEOIP_MMAP_CACHE)) { +#if !defined(_WIN32) + /* MMAP is only avail on UNIX */ + munmap(gi->cache, gi->size); + gi->cache = NULL; +#endif + } else { + /* reload database into memory cache */ + if ((gi->cache = (unsigned char *)realloc( + gi->cache, buf.st_size)) == NULL) { + DEBUG_MSGF(gi->flags, + "Out of memory when reloading %s\n", + gi->file_path); + return; + } + } + } + /* refresh filehandle */ + fclose(gi->GeoIPDatabase); + gi->GeoIPDatabase = fopen(gi->file_path, "rb"); + if (gi->GeoIPDatabase == NULL) { + DEBUG_MSGF(gi->flags, + "Error Opening file %s when reloading\n", + gi->file_path); + return; + } + gi->mtime = buf.st_mtime; + gi->size = buf.st_size; + + if (gi->flags & GEOIP_MMAP_CACHE) { +#if defined(_WIN32) + DEBUG_MSGF(gi->flags, + "GEOIP_MMAP_CACHE is not supported on WIN32\n"); + gi->cache = 0; + return; +#else + gi->cache = mmap(NULL, + buf.st_size, + PROT_READ, + MAP_PRIVATE, + fileno(gi->GeoIPDatabase), + 0); + if (gi->cache == MAP_FAILED) { + + DEBUG_MSGF(gi->flags, + "Error remapping file %s when reloading\n", + gi->file_path); + + gi->cache = NULL; + return; + } +#endif + } else if (gi->flags & GEOIP_MEMORY_CACHE) { + if (pread(fileno(gi->GeoIPDatabase), + gi->cache, + buf.st_size, + 0) != (ssize_t)buf.st_size) { + DEBUG_MSGF(gi->flags, + "Error reading file %s when reloading\n", + gi->file_path); + return; + } + } + + if (gi->databaseSegments != NULL) { + free(gi->databaseSegments); + gi->databaseSegments = NULL; + } + _setup_segments(gi); + if (gi->databaseSegments == NULL) { + DEBUG_MSGF(gi->flags, + "Error reading file %s -- corrupt\n", + gi->file_path); + return; + } + + idx_size = get_index_size(gi, &buf); + if (idx_size < 0) { + DEBUG_MSGF( + gi->flags, "Error file %s -- corrupt\n", gi->file_path); + return; + } + + if (gi->flags & GEOIP_INDEX_CACHE) { + gi->index_cache = (unsigned char *)realloc( + gi->index_cache, sizeof(unsigned char) * idx_size); + if (gi->index_cache != NULL) { + if (pread(fileno(gi->GeoIPDatabase), + gi->index_cache, + idx_size, + 0) != idx_size) { + DEBUG_MSGF( + gi->flags, + "Error reading file %s where reloading\n", + gi->file_path); + return; + } + } + } + } + } + } + return; +} + +#define ADDR_STR_LEN (8 * 4 + 7 + 1) +unsigned int +_GeoIP_seek_record_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int depth; + char paddr[ADDR_STR_LEN]; + unsigned int x; + unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; + const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; + unsigned int offset = 0; + + const unsigned char *p; + int j; + int fno = fileno(gi->GeoIPDatabase); + + unsigned int record_pair_length = gi->record_length * 2; + + _check_mtime(gi); + if (GeoIP_teredo(gi)) { + __GEOIP_PREPARE_TEREDO(&ipnum); + } + for (depth = 127; depth >= 0; depth--) { + unsigned int byte_offset = record_pair_length * offset; + if (byte_offset > gi->size - record_pair_length) { + /* The pointer is invalid */ + break; + } + if (gi->cache == NULL && gi->index_cache == NULL) { + /* read from disk */ + if (pread( + fno, stack_buffer, record_pair_length, (long)byte_offset) != + record_pair_length) { + break; + } + } else if (gi->index_cache == NULL) { + /* simply point to record in memory */ + buf = gi->cache + (long)byte_offset; + } else { + buf = gi->index_cache + (long)byte_offset; + } + + if (GEOIP_CHKBIT_V6(depth, ipnum.s6_addr)) { + /* Take the right-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 1 + 0] << (0 * 8)) + (buf[3 * 1 + 1] << (1 * 8)) + + (buf[3 * 1 + 2] << (2 * 8)); + + } else { + /* General case */ + j = gi->record_length; + p = &buf[2 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + + } else { + /* Take the left-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 0 + 0] << (0 * 8)) + (buf[3 * 0 + 1] << (1 * 8)) + + (buf[3 * 0 + 2] << (2 * 8)); + } else { + /* General case */ + j = gi->record_length; + p = &buf[1 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + } + + if (x >= gi->databaseSegments[0]) { + gi->netmask = gl->netmask = 128 - depth; + return x; + } + offset = x; + } + + /* shouldn't reach here */ + _GeoIP_inet_ntop(AF_INET6, &ipnum.s6_addr[0], paddr, ADDR_STR_LEN); + DEBUG_MSGF(gi->flags, + "Error Traversing Database for ipnum = %s - Perhaps database is " + "corrupt?\n", + paddr); + return 0; +} + +geoipv6_t _GeoIP_addr_to_num_v6(const char *addr) { + geoipv6_t ipnum; + if (1 == _GeoIP_inet_pton(AF_INET6, addr, &ipnum.s6_addr[0])) { + return ipnum; + } + return IPV6_NULL; +} + +unsigned int +_GeoIP_seek_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + int depth; + unsigned int x; + unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; + const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; + unsigned int offset = 0; + + const unsigned char *p; + int j; + int fno = fileno(gi->GeoIPDatabase); + + unsigned int record_pair_length = gi->record_length * 2; + + _check_mtime(gi); + for (depth = 31; depth >= 0; depth--) { + unsigned int byte_offset = record_pair_length * offset; + if (byte_offset > gi->size - record_pair_length) { + /* The pointer is invalid */ + break; + } + if (gi->cache == NULL && gi->index_cache == NULL) { + /* read from disk */ + if (pread(fno, stack_buffer, record_pair_length, byte_offset) != + record_pair_length) { + break; + } + } else if (gi->index_cache == NULL) { + /* simply point to record in memory */ + buf = gi->cache + (long)byte_offset; + } else { + buf = gi->index_cache + (long)byte_offset; + } + + if (ipnum & (1 << depth)) { + /* Take the right-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 1 + 0] << (0 * 8)) + (buf[3 * 1 + 1] << (1 * 8)) + + (buf[3 * 1 + 2] << (2 * 8)); + + } else { + /* General case */ + j = gi->record_length; + p = &buf[2 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + + } else { + /* Take the left-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 0 + 0] << (0 * 8)) + (buf[3 * 0 + 1] << (1 * 8)) + + (buf[3 * 0 + 2] << (2 * 8)); + } else { + /* General case */ + j = gi->record_length; + p = &buf[1 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + } + + if (x >= gi->databaseSegments[0]) { + gi->netmask = gl->netmask = 32 - depth; + return x; + } + offset = x; + } + /* shouldn't reach here */ + DEBUG_MSGF(gi->flags, + "Error Traversing Database for ipnum = %lu - Perhaps database " + "is corrupt?\n", + ipnum); + return 0; +} + +unsigned long GeoIP_addr_to_num(const char *addr) { + unsigned int c, octet, t; + unsigned long ipnum; + int i = 3; + + octet = ipnum = 0; + while ((c = *addr++)) { + if (c == '.') { + if (octet > 255) { + return 0; + } + ipnum <<= 8; + ipnum += octet; + i--; + octet = 0; + } else { + t = octet; + octet <<= 3; + octet += t; + octet += t; + c -= '0'; + if (c > 9) { + return 0; + } + octet += c; + } + } + if ((octet > 255) || (i != 0)) { + return 0; + } + ipnum <<= 8; + return ipnum + octet; +} + +GeoIP *GeoIP_open_type(int type, int flags) { + GeoIP *gi; + const char *filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + printf("Invalid database type %d\n", type); + return NULL; + } + _GeoIP_setup_dbfilename(); + filePath = GeoIPDBFileName[type]; + if (filePath == NULL) { + printf("Invalid database type %d\n", type); + return NULL; + } + gi = GeoIP_open(filePath, flags); + + if (gi) { + /* make sure this is the requested database type */ + int database_type = gi->databaseType; + if (database_type > 105) { + database_type -= 105; + } + /* type must match, but we accept org and asnum, + * since domain and *conf database have always the wrong type + * for historical reason. Maybe we fix it at some point. + */ + if (database_type == type || database_type == GEOIP_ASNUM_EDITION || + database_type == GEOIP_ORG_EDITION) { + return gi; + } + GeoIP_delete(gi); + } + + return NULL; +} + +GeoIP *GeoIP_new(int flags) { + GeoIP *gi; + _GeoIP_setup_dbfilename(); + gi = GeoIP_open(GeoIPDBFileName[GEOIP_COUNTRY_EDITION], flags); + return gi; +} + +GeoIP *GeoIP_open(const char *filename, int flags) { + struct stat buf; + ssize_t idx_size; + GeoIP *gi; + size_t len; + + gi = (GeoIP *)calloc(1, sizeof(GeoIP)); + if (gi == NULL) { + return NULL; + } + len = sizeof(char) * (strlen(filename) + 1); + gi->file_path = malloc(len); + if (gi->file_path == NULL) { + free(gi); + return NULL; + } + strncpy(gi->file_path, filename, len); + gi->GeoIPDatabase = fopen(filename, "rb"); + if (gi->GeoIPDatabase == NULL) { + DEBUG_MSGF(flags, "Error Opening file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + DEBUG_MSGF(flags, "Error stating file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + + gi->size = buf.st_size; + if (flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) { + gi->mtime = buf.st_mtime; + + /* MMAP added my Peter Shipley */ + if (flags & GEOIP_MMAP_CACHE) { +#if !defined(_WIN32) + gi->cache = mmap(NULL, + buf.st_size, + PROT_READ, + MAP_PRIVATE, + fileno(gi->GeoIPDatabase), + 0); + if (gi->cache == MAP_FAILED) { + DEBUG_MSGF(flags, "Error mmaping file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } +#endif + } else { + gi->cache = + (unsigned char *)malloc(sizeof(unsigned char) * buf.st_size); + + if (gi->cache != NULL) { + if (pread( + fileno(gi->GeoIPDatabase), gi->cache, buf.st_size, 0) != + (ssize_t)buf.st_size) { + DEBUG_MSGF(flags, "Error reading file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + } + } + } else { + if (flags & GEOIP_CHECK_CACHE) { + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + DEBUG_MSGF(flags, "Error stating file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + gi->mtime = buf.st_mtime; + } + gi->cache = NULL; + } + gi->flags = flags; + gi->charset = GEOIP_CHARSET_ISO_8859_1; + gi->ext_flags = 1U << GEOIP_TEREDO_BIT; + _setup_segments(gi); + if (gi->databaseSegments == NULL) { + DEBUG_MSGF( + gi->flags, "Error reading file %s -- corrupt\n", gi->file_path); + GeoIP_delete(gi); + return NULL; + } + + idx_size = get_index_size(gi, &buf); + + if (idx_size < 0) { + DEBUG_MSGF(gi->flags, "Error file %s -- corrupt\n", gi->file_path); + GeoIP_delete(gi); + return NULL; + } + + if (flags & GEOIP_INDEX_CACHE) { + gi->index_cache = + (unsigned char *)malloc(sizeof(unsigned char) * idx_size); + if (gi->index_cache != NULL) { + if (pread( + fileno(gi->GeoIPDatabase), gi->index_cache, idx_size, 0) != + idx_size) { + DEBUG_MSGF(gi->flags, "Error reading file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + } + } else { + gi->index_cache = NULL; + } + + gi->last_mtime_check = 0; + + return gi; +} + +void GeoIP_delete(GeoIP *gi) { + if (gi == NULL) { + return; + } + if (gi->GeoIPDatabase != NULL) { + fclose(gi->GeoIPDatabase); + } + if (gi->cache != NULL) { + if (gi->flags & GEOIP_MMAP_CACHE) { +#if !defined(_WIN32) + if (gi->cache) { + munmap(gi->cache, gi->size); + } +#endif + } else { + free(gi->cache); + } + gi->cache = NULL; + } + free(gi->index_cache); + free(gi->file_path); + free(gi->databaseSegments); + free(gi); +} + +const char * +GeoIP_country_code_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char *GeoIP_country_code3_by_name_v6_gl(GeoIP *gi, + const char *name, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code3_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char * +GeoIP_country_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_gl(gi, name, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +unsigned long _GeoIP_lookupaddress(const char *host) { + unsigned long addr = inet_addr(host); + struct hostent phe2; + struct hostent *phe = &phe2; + char *buf = NULL; +#ifdef HAVE_GETHOSTBYNAME_R + int buflength = 16384; + int herr = 0; +#endif + int result = 0; +#ifdef HAVE_GETHOSTBYNAME_R + buf = malloc(buflength); +#endif + if (addr == INADDR_NONE) { +#ifdef HAVE_GETHOSTBYNAME_R + while (1) { +/* we use gethostbyname_r here because it is thread-safe and gethostbyname is + * not */ +#ifdef GETHOSTBYNAME_R_RETURNS_INT + result = gethostbyname_r(host, &phe2, buf, buflength, &phe, &herr); +#else + phe = gethostbyname_r(host, &phe2, buf, buflength, &herr); +#endif + if (herr != ERANGE) { + break; + } + if (result == 0) { + break; + } + /* double the buffer if the buffer is too small */ + buflength = buflength * 2; + buf = realloc(buf, buflength); + } +#else + /* Some systems do not support gethostbyname_r, such as Mac OS X */ + phe = gethostbyname(host); +#endif + if (!phe || result != 0) { + free(buf); + return 0; + } +#if !defined(_WIN32) + addr = *((in_addr_t *)phe->h_addr_list[0]); +#else + addr = ((IN_ADDR *)phe->h_addr_list[0])->S_un.S_addr; +#endif + } +#ifdef HAVE_GETHOSTBYNAME_R + free(buf); +#endif + return ntohl(addr); +} + +geoipv6_t _GeoIP_lookupaddress_v6(const char *host) { + geoipv6_t ipnum; + int gaierr; + struct addrinfo hints, *aifirst; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + /* hints.ai_flags = AI_V4MAPPED; */ + hints.ai_socktype = SOCK_STREAM; + + if ((gaierr = getaddrinfo(host, NULL, &hints, &aifirst)) != 0) { + /* DEBUG_MSGF("Err: %s (%d %s)\n", host, gaierr, gai_strerror(gaierr)); + */ + return IPV6_NULL; + } + memcpy(ipnum.s6_addr, + ((struct sockaddr_in6 *)aifirst->ai_addr)->sin6_addr.s6_addr, + sizeof(geoipv6_t)); + freeaddrinfo(aifirst); + /* inet_pton(AF_INET6, host, ipnum.s6_addr); */ + + return ipnum; +} + +int GeoIP_id_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + unsigned long ipnum; + int ret; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION)); + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) { + return 0; + } + ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + geoipv6_t ipnum; + int ret; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6 && + gi->databaseType != GEOIP_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION_V6)); + return 0; + } + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) { + return 0; + } + + ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +const char * +GeoIP_country_code_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} +const char *GeoIP_country_code3_by_addr_v6_gl(GeoIP *gi, + const char *addr, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code3_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char * +GeoIP_country_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_gl(gi, addr, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char *GeoIP_country_name_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char * +GeoIP_country_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char *GeoIP_country_code_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char *GeoIP_country_code3_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char *GeoIP_country_code3_by_ipnum_v6_gl(GeoIP *gi, + geoipv6_t ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +int GeoIP_country_id_by_addr_v6_gl(GeoIP *gi, + const char *addr, + GeoIPLookup *gl) { + return GeoIP_id_by_addr_v6_gl(gi, addr, gl); +} + +int GeoIP_country_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + return GeoIP_id_by_addr_gl(gi, addr, gl); +} + +int GeoIP_country_id_by_name_v6_gl(GeoIP *gi, + const char *host, + GeoIPLookup *gl) { + return GeoIP_id_by_name_v6_gl(gi, host, gl); +} + +int GeoIP_country_id_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl) { + return GeoIP_id_by_name_gl(gi, host, gl); +} + +int GeoIP_id_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + geoipv6_t ipnum; + int ret; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION_V6)); + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + int ret; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION)); + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int ret; + if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION_V6)); + return 0; + } + ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + int ret; + if (ipnum == 0) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION)); + return 0; + } + ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +char *GeoIP_database_info(GeoIP *gi) { + int i; + unsigned char buf[3]; + char *retval; + int has_structure_info = 0; + off_t offset = gi->size - 3; + int fno; + + if (gi == NULL) { + return NULL; + } + + fno = fileno(gi->GeoIPDatabase); + + _check_mtime(gi); + + /* first get past the database structure information */ + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + if (pread(fno, buf, 3, offset) != 3) { + return NULL; + } + offset += 3; + if (buf[0] == 255 && buf[1] == 255 && buf[2] == 255) { + has_structure_info = 1; + break; + } + offset -= 4; + if (offset < 0) { + return NULL; + } + } + if (has_structure_info) { + offset -= 6; + if (offset < 0) { + return NULL; + } + } else { + /* no structure info, must be pre Sep 2002 database, go back to end */ + offset = gi->size - 3; + if (offset < 0) { + return NULL; + } + } + + for (i = 0; i < DATABASE_INFO_MAX_SIZE; i++) { + if (pread(fno, buf, 3, offset) != 3) { + return NULL; + } + offset += 3; + if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) { + retval = malloc(sizeof(char) * (i + 1)); + if (retval == NULL) { + return NULL; + } + if (pread(fno, retval, i, offset) != i) { + return NULL; + } + retval[i] = '\0'; + return retval; + } + offset -= 4; + if (offset < 0) { + return NULL; + } + } + return NULL; +} + +/* GeoIP Region Edition functions */ + +void GeoIP_assign_region_by_inetaddr_gl(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *region, + GeoIPLookup *gl) { + unsigned int seek_region; + + /* This also writes in the terminating NULs (if you decide to + * keep them) and clear any fields that are not set. */ + memset(region, 0, sizeof(GeoIPRegion)); + + seek_region = _GeoIP_seek_record_gl(gi, ntohl(inetaddr), gl); + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + seek_region -= STATE_BEGIN_REV0; + if (seek_region >= 1000) { + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - 1000) / 26 + 65); + region->region[1] = (char)((seek_region - 1000) % 26 + 65); + } else { + const char *code = GeoIP_code_by_id(seek_region); + if (code != NULL) { + memcpy(region->country_code, code, 2); + } + } + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + seek_region -= STATE_BEGIN_REV1; + if (seek_region < US_OFFSET) { + /* Unknown */ + /* we don't need to do anything here b/c we memset region to 0 */ + } else if (seek_region < CANADA_OFFSET) { + /* USA State */ + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - US_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - US_OFFSET) % 26 + 65); + } else if (seek_region < WORLD_OFFSET) { + /* Canada Province */ + region->country_code[0] = 'C'; + region->country_code[1] = 'A'; + region->region[0] = (char)((seek_region - CANADA_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - CANADA_OFFSET) % 26 + 65); + } else { + /* Not US or Canada ( cc_id is always cc_id * FIPS_RANGE ) */ + const char *code = + GeoIP_code_by_id((seek_region - WORLD_OFFSET) / FIPS_RANGE); + if (code != NULL) { + /* coverity[dont_call] */ + memcpy(region->country_code, code, 2); + } + } + } +} + +void GeoIP_assign_region_by_inetaddr_v6_gl(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *region, + GeoIPLookup *gl) { + unsigned int seek_region; + + /* This also writes in the terminating NULs (if you decide to + * keep them) and clear any fields that are not set. */ + memset(region, 0, sizeof(GeoIPRegion)); + + seek_region = _GeoIP_seek_record_v6_gl(gi, inetaddr, gl); + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + seek_region -= STATE_BEGIN_REV0; + if (seek_region >= 1000) { + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - 1000) / 26 + 65); + region->region[1] = (char)((seek_region - 1000) % 26 + 65); + } else { + const char *code = GeoIP_code_by_id(seek_region); + if (code != NULL) { + /* coverity[dont_call] */ + memcpy(region->country_code, code, 2); + } + } + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + seek_region -= STATE_BEGIN_REV1; + if (seek_region < US_OFFSET) { + /* Unknown */ + /* we don't need to do anything here b/c we memset region to 0 */ + } else if (seek_region < CANADA_OFFSET) { + /* USA State */ + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - US_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - US_OFFSET) % 26 + 65); + } else if (seek_region < WORLD_OFFSET) { + /* Canada Province */ + region->country_code[0] = 'C'; + region->country_code[1] = 'A'; + region->region[0] = (char)((seek_region - CANADA_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - CANADA_OFFSET) % 26 + 65); + } else { + /* Not US or Canada ( cc_id is always cc_id * FIPS_RANGE ) */ + const char *code = + GeoIP_code_by_id((seek_region - WORLD_OFFSET) / FIPS_RANGE); + if (code != NULL) { + /* coverity[dont_call] */ + memcpy(region->country_code, code, 2); + } + } + } +} + +static GeoIPRegion * +_get_region_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + GeoIPRegion *region; + + region = malloc(sizeof(GeoIPRegion)); + if (region) { + GeoIP_assign_region_by_inetaddr_gl(gi, htonl(ipnum), region, gl); + } + return region; +} + +static GeoIPRegion * +_get_region_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + GeoIPRegion *region; + + region = malloc(sizeof(GeoIPRegion)); + if (region) { + GeoIP_assign_region_by_inetaddr_v6_gl(gi, ipnum, region, gl); + } + return region; +} + +GeoIPRegion * +GeoIP_region_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + if (addr == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_region_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (addr == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_region_v6_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + unsigned long ipnum; + if (name == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) { + return NULL; + } + return _get_region_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (name == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) { + return NULL; + } + return _get_region_v6_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + return _get_region_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + return _get_region_v6_gl(gi, ipnum, gl); +} + +void GeoIPRegion_delete(GeoIPRegion *gir) { free(gir); } + +/* GeoIP Organization, ISP and AS Number Edition private method */ +static char *_get_name_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + unsigned int seek_org; + char buf[MAX_ORG_RECORD_LENGTH]; + char *org_buf, *buf_pointer; + int record_pointer; + size_t len; + + if (gi->databaseType != GEOIP_ORG_EDITION && + gi->databaseType != GEOIP_ISP_EDITION && + gi->databaseType != GEOIP_DOMAIN_EDITION && + gi->databaseType != GEOIP_ASNUM_EDITION && + gi->databaseType != GEOIP_ACCURACYRADIUS_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION_REV1 && + gi->databaseType != GEOIP_USERTYPE_EDITION && + gi->databaseType != GEOIP_REGISTRAR_EDITION && + gi->databaseType != GEOIP_LOCATIONA_EDITION && + gi->databaseType != GEOIP_CITYCONF_EDITION && + gi->databaseType != GEOIP_COUNTRYCONF_EDITION && + gi->databaseType != GEOIP_REGIONCONF_EDITION && + gi->databaseType != GEOIP_POSTALCONF_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_ORG_EDITION)); + return NULL; + } + + seek_org = _GeoIP_seek_record_gl(gi, ipnum, gl); + if (seek_org == gi->databaseSegments[0]) { + return NULL; + } + + record_pointer = + seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + if (pread(fileno(gi->GeoIPDatabase), + buf, + MAX_ORG_RECORD_LENGTH, + record_pointer) == -1) { + return NULL; + } + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf); + } else { + len = sizeof(char) * (strlen(buf) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf, len); + } + } else { + buf_pointer = (char *)(gi->cache + (long)record_pointer); + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf_pointer); + } else { + len = sizeof(char) * (strlen(buf_pointer) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf_pointer, len); + } + } + return org_buf; +} + +static char *_get_name_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + unsigned int seek_org; + char buf[MAX_ORG_RECORD_LENGTH + 1]; + char *org_buf, *buf_pointer; + int record_pointer; + size_t len; + + if (gi->databaseType != GEOIP_ORG_EDITION_V6 && + gi->databaseType != GEOIP_ISP_EDITION_V6 && + gi->databaseType != GEOIP_DOMAIN_EDITION_V6 && + gi->databaseType != GEOIP_ASNUM_EDITION_V6 && + gi->databaseType != GEOIP_ACCURACYRADIUS_EDITION_V6 && + gi->databaseType != GEOIP_NETSPEED_EDITION_REV1_V6 && + gi->databaseType != GEOIP_USERTYPE_EDITION_V6 && + gi->databaseType != GEOIP_REGISTRAR_EDITION_V6 && + gi->databaseType != GEOIP_LOCATIONA_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_ORG_EDITION)); + return NULL; + } + + seek_org = _GeoIP_seek_record_v6_gl(gi, ipnum, gl); + if (seek_org == gi->databaseSegments[0]) { + return NULL; + } + + record_pointer = + seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + if (pread(fileno(gi->GeoIPDatabase), + buf, + MAX_ORG_RECORD_LENGTH, + record_pointer) == -1) { + return NULL; + } + buf[MAX_ORG_RECORD_LENGTH] = 0; + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf); + } else { + len = sizeof(char) * (strlen(buf) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf, len); + } + } else { + buf_pointer = (char *)(gi->cache + (long)record_pointer); + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf_pointer); + } else { + len = sizeof(char) * (strlen(buf_pointer) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf_pointer, len); + } + } + return org_buf; +} + +char *GeoIP_num_to_addr(unsigned long ipnum) { + char *ret_str; + char *cur_str; + int octet[4]; + int num_chars_written, i; + + ret_str = malloc(sizeof(char) * 16); + cur_str = ret_str; + + for (i = 0; i < 4; i++) { + octet[3 - i] = ipnum % 256; + ipnum >>= 8; + } + + for (i = 0; i < 4; i++) { + num_chars_written = sprintf(cur_str, "%d", octet[i]); + cur_str += num_chars_written; + + if (i < 3) { + cur_str[0] = '.'; + cur_str++; + } + } + + return ret_str; +} + +char **GeoIP_range_by_ip_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + unsigned long left_seek; + unsigned long right_seek; + unsigned long mask; + int orig_netmask; + unsigned int target_value; + char **ret; + GeoIPLookup t; + + if (addr == NULL) { + return NULL; + } + + ret = malloc(sizeof(char *) * 2); + + ipnum = GeoIP_addr_to_num(addr); + target_value = _GeoIP_seek_record_gl(gi, ipnum, gl); + orig_netmask = gl->netmask; + mask = 0xffffffff << (32 - orig_netmask); + left_seek = ipnum & mask; + right_seek = left_seek + (0xffffffff & ~mask); + + while (left_seek != 0 && + target_value == _GeoIP_seek_record_gl(gi, left_seek - 1, &t)) { + + /* Go to beginning of netblock defined by netmask */ + mask = 0xffffffff << (32 - t.netmask); + left_seek = (left_seek - 1) & mask; + } + ret[0] = GeoIP_num_to_addr(left_seek); + + while (right_seek != 0xffffffff && + target_value == _GeoIP_seek_record_gl(gi, right_seek + 1, &t)) { + + /* Go to end of netblock defined by netmask */ + mask = 0xffffffff << (32 - t.netmask); + right_seek = (right_seek + 1) & mask; + right_seek += 0xffffffff & ~mask; + } + ret[1] = GeoIP_num_to_addr(right_seek); + + gi->netmask = orig_netmask; + + return ret; +} +void GeoIP_range_by_ip_delete(char **ptr) { + if (ptr) { + if (ptr[0]) { + free(ptr[0]); + } + if (ptr[1]) { + free(ptr[1]); + } + free(ptr); + } +} + +char *GeoIP_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + return _get_name_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + return _get_name_v6_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + if (addr == NULL) { + return NULL; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_name_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (addr == NULL) { + return NULL; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_name_v6_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + unsigned long ipnum; + if (name == NULL) { + return NULL; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) { + return NULL; + } + return _get_name_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (name == NULL) { + return NULL; + } + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) { + return NULL; + } + return _get_name_v6_gl(gi, ipnum, gl); +} + +unsigned char GeoIP_database_edition(GeoIP *gi) { return gi->databaseType; } + +int GeoIP_enable_teredo(GeoIP *gi, int true_false) { + unsigned int mask = (1U << GEOIP_TEREDO_BIT); + int b = (gi->ext_flags & mask) ? 1 : 0; + gi->ext_flags &= ~mask; + if (true_false) { + gi->ext_flags |= true_false; + } + return b; +} + +int GeoIP_teredo(GeoIP *gi) { + unsigned int mask = (1U << GEOIP_TEREDO_BIT); + return (gi->ext_flags & mask) ? 1 : 0; +} + +int GeoIP_charset(GeoIP *gi) { return gi->charset; } + +int GeoIP_set_charset(GeoIP *gi, int charset) { + int old_charset = gi->charset; + gi->charset = charset; + return old_charset; +} + +/** return two letter country code */ +const char *GeoIP_code_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_code[id]; +} + +/** return three letter country code */ +const char *GeoIP_code3_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_code3[id]; +} + +/** return full name of country in utf8 or iso-8859-1 */ +const char *GeoIP_country_name_by_id(GeoIP *gi, int id) { + /* return NULL also even for index 0 for backward compatibility */ + if (id <= 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + return (gi->charset == GEOIP_CHARSET_UTF8) ? GeoIP_utf8_country_name[id] + : GeoIP_country_name[id]; +} + +/** return full name of country in iso-8859-1 */ +const char *GeoIP_name_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_name[id]; +} + +/** return continent of country */ +const char *GeoIP_continent_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_continent[id]; +} + +/** return id by country code **/ +int GeoIP_id_by_code(const char *country) { + unsigned i; + + for (i = 0; i < num_GeoIP_countries; ++i) { + if (strcmp(country, GeoIP_country_code[i]) == 0) { + return i; + } + } + + return 0; +} + +unsigned GeoIP_num_countries(void) { return num_GeoIP_countries; } + +const char *GeoIP_lib_version(void) { return PACKAGE_VERSION; } + +int GeoIP_cleanup(void) { + int i, result = 0; + char **tmpGeoIPDBFileName = GeoIPDBFileName; + + GeoIPDBFileName = NULL; + + if (tmpGeoIPDBFileName) { + for (i = 0; i < NUM_DB_TYPES; i++) { + if (tmpGeoIPDBFileName[i]) { + free(tmpGeoIPDBFileName[i]); + } + } + + free(tmpGeoIPDBFileName); + result = 1; + } + + return result; +} diff --git a/libGeoIP/GeoIP.h b/libGeoIP/GeoIP.h new file mode 100644 index 0000000..2852595 --- /dev/null +++ b/libGeoIP/GeoIP.h @@ -0,0 +1,444 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.h + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GEOIP_H +#define GEOIP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/types.h> +#if !defined(_WIN32) +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/socket.h> +#else /* !defined(_WIN32) */ +#include <winsock2.h> +#include <ws2tcpip.h> +#define FILETIME_TO_USEC(ft) \ + (((unsigned __int64)ft.dwHighDateTime << 32 | ft.dwLowDateTime) / 10) +#endif /* !defined(_WIN32) */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> /* for fstat */ +#include <sys/types.h> /* for fstat */ + +#define SEGMENT_RECORD_LENGTH 3 +#define LARGE_SEGMENT_RECORD_LENGTH 4 +#define STANDARD_RECORD_LENGTH 3 +#define ORG_RECORD_LENGTH 4 +#define MAX_RECORD_LENGTH 4 +#define NUM_DB_TYPES (38 + 1) + +/* 128 bit address in network order */ +typedef struct in6_addr geoipv6_t; + +#define GEOIP_CHKBIT_V6(bit, ptr) \ + (ptr[((127UL - bit) >> 3)] & (1UL << (~(127 - bit) & 7))) + +typedef struct GeoIPTag { + FILE *GeoIPDatabase; + char *file_path; + unsigned char *cache; + unsigned char *index_cache; + unsigned int *databaseSegments; + char databaseType; + time_t mtime; + int flags; + off_t size; + char record_length; + int charset; /* 0 iso-8859-1 1 utf8 */ + int record_iter; /* used in GeoIP_next_record */ + int netmask; /* netmask of last lookup - set using depth in + _GeoIP_seek_record */ + time_t last_mtime_check; + off_t dyn_seg_size; /* currently only used by the cityconfidence database */ + unsigned int ext_flags; /* bit 0 teredo support enabled */ +} GeoIP; + +typedef struct GeoIPLookup { int netmask; } GeoIPLookup; + +typedef enum { GEOIP_TEREDO_BIT = 0 } GeoIPExtFlags; + +typedef enum { + GEOIP_CHARSET_ISO_8859_1 = 0, + GEOIP_CHARSET_UTF8 = 1 +} GeoIPCharset; + +typedef struct GeoIPRegionTag { + char country_code[3]; + char region[3]; +} GeoIPRegion; + +typedef enum { + GEOIP_STANDARD = 0, + GEOIP_MEMORY_CACHE = 1, + GEOIP_CHECK_CACHE = 2, + GEOIP_INDEX_CACHE = 4, + GEOIP_MMAP_CACHE = 8, + GEOIP_SILENCE = 16, +} GeoIPOptions; + +typedef enum { + GEOIP_COUNTRY_EDITION = 1, + GEOIP_REGION_EDITION_REV0 = 7, + GEOIP_CITY_EDITION_REV0 = 6, + GEOIP_ORG_EDITION = 5, + GEOIP_ISP_EDITION = 4, + GEOIP_CITY_EDITION_REV1 = 2, + GEOIP_REGION_EDITION_REV1 = 3, + GEOIP_PROXY_EDITION = 8, + GEOIP_ASNUM_EDITION = 9, + GEOIP_NETSPEED_EDITION = 10, + GEOIP_DOMAIN_EDITION = 11, + GEOIP_COUNTRY_EDITION_V6 = 12, + GEOIP_LOCATIONA_EDITION = 13, + GEOIP_ACCURACYRADIUS_EDITION = 14, + GEOIP_CITYCONFIDENCE_EDITION = 15, /* unsupported */ + GEOIP_CITYCONFIDENCEDIST_EDITION = 16, /* unsupported */ + GEOIP_LARGE_COUNTRY_EDITION = 17, + GEOIP_LARGE_COUNTRY_EDITION_V6 = 18, + GEOIP_CITYCONFIDENCEDIST_ISP_ORG_EDITION = + 19, /* unused, but gaps are not allowed */ + GEOIP_CCM_COUNTRY_EDITION = 20, /* unused, but gaps are not allowed */ + GEOIP_ASNUM_EDITION_V6 = 21, + GEOIP_ISP_EDITION_V6 = 22, + GEOIP_ORG_EDITION_V6 = 23, + GEOIP_DOMAIN_EDITION_V6 = 24, + GEOIP_LOCATIONA_EDITION_V6 = 25, + GEOIP_REGISTRAR_EDITION = 26, + GEOIP_REGISTRAR_EDITION_V6 = 27, + GEOIP_USERTYPE_EDITION = 28, + GEOIP_USERTYPE_EDITION_V6 = 29, + GEOIP_CITY_EDITION_REV1_V6 = 30, + GEOIP_CITY_EDITION_REV0_V6 = 31, + GEOIP_NETSPEED_EDITION_REV1 = 32, + GEOIP_NETSPEED_EDITION_REV1_V6 = 33, + GEOIP_COUNTRYCONF_EDITION = 34, + GEOIP_CITYCONF_EDITION = 35, + GEOIP_REGIONCONF_EDITION = 36, + GEOIP_POSTALCONF_EDITION = 37, + GEOIP_ACCURACYRADIUS_EDITION_V6 = 38 +} GeoIPDBTypes; + +typedef enum { + GEOIP_ANON_PROXY = 1, + GEOIP_HTTP_X_FORWARDED_FOR_PROXY = 2, + GEOIP_HTTP_CLIENT_IP_PROXY = 3, +} GeoIPProxyTypes; + +typedef enum { + GEOIP_UNKNOWN_SPEED = 0, + GEOIP_DIALUP_SPEED = 1, + GEOIP_CABLEDSL_SPEED = 2, + GEOIP_CORPORATE_SPEED = 3, +} GeoIPNetspeedValues; + +#if defined(_WIN32) && !defined(__MINGW32__) +#ifdef GEOIP_EXPORTS +#define GEOIP_API __declspec(dllexport) +#define GEOIP_DATA __declspec(dllexport) +#else +#define GEOIP_DATA __declspec(dllimport) +#define GEOIP_API +#endif /* GEOIP_EXPORTS */ +#else +#define GEOIP_API +#define GEOIP_DATA +#endif + +extern char **GeoIPDBFileName; +extern GEOIP_DATA const char *GeoIPDBDescription[NUM_DB_TYPES]; +extern GEOIP_DATA const char *GeoIPCountryDBFileName; +extern GEOIP_DATA const char *GeoIPRegionDBFileName; +extern GEOIP_DATA const char *GeoIPCityDBFileName; +extern GEOIP_DATA const char *GeoIPOrgDBFileName; +extern GEOIP_DATA const char *GeoIPISPDBFileName; +extern GEOIP_DATA const char *GeoIPLocationADBFileName; +extern GEOIP_DATA const char *GeoIPAccuracyRadiusFileName; +extern GEOIP_DATA const char *GeoIPCityConfidenceFileName; +extern char *GeoIP_custom_directory; + +/* Warning: do not use those arrays as doing so may break your + * program with newer GeoIP versions */ +extern GEOIP_DATA const char GeoIP_country_code[256][3]; +extern GEOIP_DATA const char GeoIP_country_code3[256][4]; +extern GEOIP_DATA const char *GeoIP_country_name[256]; +extern GEOIP_DATA const char *GeoIP_utf8_country_name[256]; +extern GEOIP_DATA const char GeoIP_country_continent[256][3]; + +GEOIP_API void GeoIP_setup_custom_directory(char *dir); +GEOIP_API GeoIP *GeoIP_open_type(int type, int flags); +GEOIP_API GeoIP *GeoIP_new(int flags); +GEOIP_API GeoIP *GeoIP_open(const char *filename, int flags); +/* + * WARNING: GeoIP_db_avail() checks for the existence of a database + * file but does not check that it has the requested database revision. + * For database types which have more than one revision (including Region, + * City, and Cityv6), this can lead to unexpected results. Check the + * return value of GeoIP_open_type() to find out whether a particular + * database type is really available. + */ +GEOIP_API int GeoIP_db_avail(int type); +GEOIP_API void GeoIP_delete(GeoIP *gi); + +GEOIP_API const char * +GeoIP_country_code_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API const char *GeoIP_country_code3_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl); + +/* */ +GEOIP_API const char * +GeoIP_country_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); + +GEOIP_API const char * +GeoIP_country_code_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); + +GEOIP_API int GeoIP_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API int GeoIP_id_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API int +GeoIP_id_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); + +GEOIP_API int +GeoIP_id_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API int +GeoIP_id_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API int +GeoIP_id_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); + +GEOIP_API GeoIPRegion * +GeoIP_region_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); + +GEOIP_API GeoIPRegion * +GeoIP_region_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); + +/* Warning - don't call this after GeoIP_assign_region_by_inetaddr calls */ +GEOIP_API void GeoIPRegion_delete(GeoIPRegion *gir); + +GEOIP_API void GeoIP_assign_region_by_inetaddr_gl(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *gir, + GeoIPLookup *gl); +GEOIP_API void GeoIP_assign_region_by_inetaddr_v6_gl(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *gir, + GeoIPLookup *gl); + +/* Used to query GeoIP Organization, ISP and AS Number databases */ +GEOIP_API char * +GeoIP_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); + +GEOIP_API char * +GeoIP_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl); + +/** return two letter country code */ +GEOIP_API const char *GeoIP_code_by_id(int id); + +/** return three letter country code */ +GEOIP_API const char *GeoIP_code3_by_id(int id); + +/** return full name of country in utf8 or iso-8859-1 */ +GEOIP_API const char *GeoIP_country_name_by_id(GeoIP *gi, int id); + +/** return full name of country */ +GEOIP_API const char *GeoIP_name_by_id(int id); + +/** return continent of country */ +GEOIP_API const char *GeoIP_continent_by_id(int id); + +/** return id by country code **/ +GEOIP_API int GeoIP_id_by_code(const char *country); + +/** return return number of known countries */ +GEOIP_API unsigned GeoIP_num_countries(void); + +GEOIP_API char *GeoIP_database_info(GeoIP *gi); +GEOIP_API unsigned char GeoIP_database_edition(GeoIP *gi); + +GEOIP_API int GeoIP_charset(GeoIP *gi); +GEOIP_API int GeoIP_set_charset(GeoIP *gi, int charset); +GEOIP_API int GeoIP_enable_teredo(GeoIP *gi, int true_false); +GEOIP_API int GeoIP_teredo(GeoIP *gi); + +GEOIP_API char ** +GeoIP_range_by_ip_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API void GeoIP_range_by_ip_delete(char **ptr); + +/* Convert region code to region name */ +GEOIP_API const char *GeoIP_region_name_by_code(const char *country_code, + const char *region_code); + +/* Get timezone from country and region code */ +GEOIP_API const char * +GeoIP_time_zone_by_country_and_region(const char *country_code, + const char *region_code); + +/* some v4 helper functions as of 1.4.7 exported to the public API */ +GEOIP_API unsigned long GeoIP_addr_to_num(const char *addr); +GEOIP_API char *GeoIP_num_to_addr(unsigned long ipnum); + +/* Internal function -- convert iso to utf8; return a malloced utf8 string. */ +char *_GeoIP_iso_8859_1__utf8(const char *iso); + +/* Cleans up memory used to hold file name paths. Returns 1 if successful; + * otherwise 0. + * */ +GEOIP_API int GeoIP_cleanup(void); + +/* Returns the library version in use. Helpful if you're loading dynamically. */ +GEOIP_API const char *GeoIP_lib_version(void); + +/* deprecated */ +GEOIP_API const char *GeoIP_country_code_by_addr(GeoIP *gi, const char *addr); +GEOIP_API const char *GeoIP_country_code_by_name(GeoIP *gi, const char *host); +GEOIP_API const char *GeoIP_country_code3_by_addr(GeoIP *gi, const char *addr); +GEOIP_API const char *GeoIP_country_code3_by_name(GeoIP *gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_addr(GeoIP *gi, const char *addr); +GEOIP_API const char *GeoIP_country_name_by_name(GeoIP *gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_ipnum(GeoIP *gi, + unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code_by_ipnum(GeoIP *gi, + unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code3_by_ipnum(GeoIP *gi, + unsigned long ipnum); + +GEOIP_API const char *GeoIP_country_name_by_ipnum_v6(GeoIP *gi, + geoipv6_t ipnum); +GEOIP_API const char *GeoIP_country_code_by_ipnum_v6(GeoIP *gi, + geoipv6_t ipnum); +GEOIP_API const char *GeoIP_country_code3_by_ipnum_v6(GeoIP *gi, + geoipv6_t ipnum); + +GEOIP_API const char *GeoIP_country_code_by_addr_v6(GeoIP *gi, + const char *addr); +GEOIP_API const char *GeoIP_country_code_by_name_v6(GeoIP *gi, + const char *host); +GEOIP_API const char *GeoIP_country_code3_by_addr_v6(GeoIP *gi, + const char *addr); +GEOIP_API const char *GeoIP_country_code3_by_name_v6(GeoIP *gi, + const char *host); +GEOIP_API const char *GeoIP_country_name_by_addr_v6(GeoIP *gi, + const char *addr); +GEOIP_API const char *GeoIP_country_name_by_name_v6(GeoIP *gi, + const char *host); + +GEOIP_API int GeoIP_id_by_addr(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_id_by_name(GeoIP *gi, const char *host); +GEOIP_API int GeoIP_id_by_ipnum(GeoIP *gi, unsigned long ipnum); + +GEOIP_API int GeoIP_id_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_id_by_name_v6(GeoIP *gi, const char *host); +GEOIP_API int GeoIP_id_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); + +GEOIP_API GeoIPRegion *GeoIP_region_by_addr(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRegion *GeoIP_region_by_name(GeoIP *gi, const char *host); +GEOIP_API GeoIPRegion *GeoIP_region_by_ipnum(GeoIP *gi, unsigned long ipnum); + +GEOIP_API GeoIPRegion *GeoIP_region_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRegion *GeoIP_region_by_name_v6(GeoIP *gi, const char *host); +GEOIP_API GeoIPRegion *GeoIP_region_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); + +GEOIP_API void GeoIP_assign_region_by_inetaddr(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *gir); +GEOIP_API void GeoIP_assign_region_by_inetaddr_v6(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *gir); + +GEOIP_API char *GeoIP_name_by_ipnum(GeoIP *gi, unsigned long ipnum); +GEOIP_API char *GeoIP_name_by_addr(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_name_by_name(GeoIP *gi, const char *host); + +GEOIP_API char *GeoIP_name_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); +GEOIP_API char *GeoIP_name_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_name_by_name_v6(GeoIP *gi, const char *name); + +/** GeoIP_last_netmask is deprecated - it is not thread safe */ +GEOIP_API int GeoIP_last_netmask(GeoIP *gi); +GEOIP_API char **GeoIP_range_by_ip(GeoIP *gi, const char *addr); + +/* Deprecated - for backwards compatibility only */ +GEOIP_API int GeoIP_country_id_by_addr(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_country_id_by_name(GeoIP *gi, const char *host); +GEOIP_API char *GeoIP_org_by_addr(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_org_by_name(GeoIP *gi, const char *host); +GEOIP_API char *GeoIP_org_by_ipnum(GeoIP *gi, unsigned long ipnum); + +GEOIP_API int GeoIP_country_id_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_org_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); +GEOIP_API char *GeoIP_org_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_org_by_name_v6(GeoIP *gi, const char *name); + +/* End deprecated */ + +# +#ifdef __cplusplus +} +#endif + +#endif /* GEOIP_H */ diff --git a/libGeoIP/GeoIPCity.c b/libGeoIP/GeoIPCity.c new file mode 100644 index 0000000..543f829 --- /dev/null +++ b/libGeoIP/GeoIPCity.c @@ -0,0 +1,330 @@ + +/* + * GeoIPCity.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIPCity.h" +#include "GeoIP.h" +#include "GeoIP_internal.h" +#if !defined(_WIN32) +#include <netdb.h> +#include <netinet/in.h> /* For ntohl */ +#include <unistd.h> +#else +#include <windows.h> +#include <winsock.h> + +#if defined(_MSC_VER) && \ + _MSC_VER >= 1400 // VS 2005+ deprecates fileno, lseek and read +#define fileno _fileno +#define read _read +#define lseek _lseek +#endif +#endif +#include <sys/types.h> /* For uint32_t */ +#ifdef HAVE_STDINT_H +#include <stdint.h> /* For uint32_t */ +#endif + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "pread.h" +#endif + +#ifndef HAVE_PREAD +#define pread(fd, buf, count, offset) \ + (lseek(fd, offset, SEEK_SET) == offset ? read(fd, buf, count) : -1) +#endif /* HAVE_PREAD */ + +static const int FULL_RECORD_LENGTH = 50; + +static GeoIPRecord * +_extract_record(GeoIP *gi, unsigned int seek_record, int *next_record_ptr) { + int record_pointer; + unsigned char *record_buf = NULL; + unsigned char *begin_record_buf = NULL; + GeoIPRecord *record; + int str_length = 0; + int j; + double latitude = 0, longitude = 0; + int metroarea_combo = 0; + int bytes_read = 0; + if (seek_record == gi->databaseSegments[0]) { + return NULL; + } + + record = malloc(sizeof(GeoIPRecord)); + memset(record, 0, sizeof(GeoIPRecord)); + record->charset = gi->charset; + + record_pointer = + seek_record + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + begin_record_buf = record_buf = + malloc(sizeof(unsigned char) * FULL_RECORD_LENGTH); + bytes_read = pread(fileno(gi->GeoIPDatabase), + record_buf, + FULL_RECORD_LENGTH, + record_pointer); + if (bytes_read <= 0) { + /* eof or other error */ + free(begin_record_buf); + free(record); + return NULL; + } + } else { + if (gi->size <= record_pointer) { + /* record does not exist in the cache */ + free(record); + return NULL; + } + record_buf = gi->cache + (long)record_pointer; + } + + /* get country */ + record->continent_code = (char *)GeoIP_country_continent[record_buf[0]]; + record->country_code = (char *)GeoIP_country_code[record_buf[0]]; + record->country_code3 = (char *)GeoIP_country_code3[record_buf[0]]; + record->country_name = (char *)GeoIP_country_name_by_id(gi, record_buf[0]); + record_buf++; + + /* get region */ + while (record_buf[str_length] != '\0') { + str_length++; + } + if (str_length > 0) { + record->region = malloc(str_length + 1); + strncpy(record->region, (char *)record_buf, str_length + 1); + } + record_buf += str_length + 1; + str_length = 0; + + /* get city */ + while (record_buf[str_length] != '\0') { + str_length++; + } + if (str_length > 0) { + if (gi->charset == GEOIP_CHARSET_UTF8) { + record->city = _GeoIP_iso_8859_1__utf8((const char *)record_buf); + } else { + record->city = malloc(str_length + 1); + strncpy(record->city, (const char *)record_buf, str_length + 1); + } + } + record_buf += (str_length + 1); + str_length = 0; + + /* get postal code */ + while (record_buf[str_length] != '\0') { + str_length++; + } + if (str_length > 0) { + record->postal_code = malloc(str_length + 1); + strncpy(record->postal_code, (char *)record_buf, str_length + 1); + } + record_buf += (str_length + 1); + + /* get latitude */ + for (j = 0; j < 3; ++j) { + latitude += (record_buf[j] << (j * 8)); + } + record->latitude = (float)(latitude / 10000 - 180); + record_buf += 3; + + /* get longitude */ + for (j = 0; j < 3; ++j) { + longitude += (record_buf[j] << (j * 8)); + } + record->longitude = (float)(longitude / 10000 - 180); + + /* + * get area code and metro code for post April 2002 databases and for US + * locations + */ + if (gi->databaseType == GEOIP_CITY_EDITION_REV1 || + gi->databaseType == GEOIP_CITY_EDITION_REV1_V6) { + if (!strcmp(record->country_code, "US")) { + record_buf += 3; + for (j = 0; j < 3; ++j) { + metroarea_combo += (record_buf[j] << (j * 8)); + } + record->metro_code = metroarea_combo / 1000; + record->area_code = metroarea_combo % 1000; + } + } + + if (begin_record_buf != NULL) { + free(begin_record_buf); + } + + /* Used for GeoIP_next_record */ + if (next_record_ptr != NULL) { + *next_record_ptr = seek_record + record_buf - begin_record_buf + 3; + } + + return record; +} + +static GeoIPRecord * +_get_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + unsigned int seek_record; + GeoIPRecord *r; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0 && + gi->databaseType != GEOIP_CITY_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return NULL; + } + + seek_record = _GeoIP_seek_record_gl(gi, ipnum, gl); + r = _extract_record(gi, seek_record, NULL); + if (r) { + r->netmask = gl->netmask; + } + return r; +} + +static GeoIPRecord *_get_record(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return _get_record_gl(gi, ipnum, &gl); +} + +static GeoIPRecord * +_get_record_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + GeoIPRecord *r; + unsigned int seek_record; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0_V6 && + gi->databaseType != GEOIP_CITY_EDITION_REV1_V6) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1_V6]); + return NULL; + } + + seek_record = _GeoIP_seek_record_v6_gl(gi, ipnum, gl); + r = _extract_record(gi, seek_record, NULL); + if (r) { + r->netmask = gl->netmask; + } + return r; +} + +static GeoIPRecord *_get_record_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return _get_record_v6_gl(gi, ipnum, &gl); +} + +GeoIPRecord *GeoIP_record_by_ipnum(GeoIP *gi, unsigned long ipnum) { + return _get_record(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + return _get_record_v6(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_addr(GeoIP *gi, const char *addr) { + unsigned long ipnum; + GeoIPLookup gl; + if (addr == NULL) { + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_record_gl(gi, ipnum, &gl); +} + +GeoIPRecord *GeoIP_record_by_addr_v6(GeoIP *gi, const char *addr) { + geoipv6_t ipnum; + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_record_v6(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_name(GeoIP *gi, const char *name) { + unsigned long ipnum; + if (name == NULL) { + return 0; + } + ipnum = _GeoIP_lookupaddress(name); + return _get_record(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_name_v6(GeoIP *gi, const char *name) { + geoipv6_t ipnum; + if (name == NULL) { + return 0; + } + ipnum = _GeoIP_lookupaddress_v6(name); + return _get_record_v6(gi, ipnum); +} + +int GeoIP_record_id_by_addr(GeoIP *gi, const char *addr) { + unsigned long ipnum; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0 && + gi->databaseType != GEOIP_CITY_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return 0; + } + if (addr == NULL) { + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _GeoIP_seek_record(gi, ipnum); +} + +int GeoIP_record_id_by_addr_v6(GeoIP *gi, const char *addr) { + geoipv6_t ipnum; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0_V6 && + gi->databaseType != GEOIP_CITY_EDITION_REV1_V6) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return 0; + } + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _GeoIP_seek_record_v6(gi, ipnum); +} + +int GeoIP_init_record_iter(GeoIP *gi) { return gi->databaseSegments[0] + 1; } + +int GeoIP_next_record(GeoIP *gi, GeoIPRecord **gir, int *record_iter) { + if (gi->cache != NULL) { + printf("GeoIP_next_record not supported in memory cache mode\n"); + return 1; + } + *gir = _extract_record(gi, *record_iter, record_iter); + return 0; +} + +void GeoIPRecord_delete(GeoIPRecord *gir) { + if (gir == NULL) { + return; + } + free(gir->region); + free(gir->city); + free(gir->postal_code); + free(gir); +} diff --git a/libGeoIP/GeoIPCity.h b/libGeoIP/GeoIPCity.h new file mode 100644 index 0000000..259fd1e --- /dev/null +++ b/libGeoIP/GeoIPCity.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIPCity.h + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GEOIPCITY_H +#define GEOIPCITY_H + +#include "GeoIP.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GEOIP_UNKNOWN_CONF (0x7f) + +typedef struct GeoIPRecordTag { + char *country_code; + char *country_code3; + char *country_name; + char *region; + char *city; + char *postal_code; + float latitude; + float longitude; + union { + int metro_code; /* metro_code is an alias for dma_code */ + int dma_code; + }; + int area_code; + int charset; + char *continent_code; + int netmask; +} GeoIPRecord; + +GEOIP_API GeoIPRecord *GeoIP_record_by_ipnum(GeoIP *gi, unsigned long ipnum); +GEOIP_API GeoIPRecord *GeoIP_record_by_addr(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRecord *GeoIP_record_by_name(GeoIP *gi, const char *host); + +GEOIP_API GeoIPRecord *GeoIP_record_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); +GEOIP_API GeoIPRecord *GeoIP_record_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRecord *GeoIP_record_by_name_v6(GeoIP *gi, const char *host); + +GEOIP_API int GeoIP_record_id_by_addr(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_record_id_by_addr_v6(GeoIP *gi, const char *addr); + +GEOIP_API int GeoIP_init_record_iter(GeoIP *gi); +/* returns 0 on success, 1 on failure */ +GEOIP_API int GeoIP_next_record(GeoIP *gi, GeoIPRecord **gir, int *record_iter); + +GEOIP_API void GeoIPRecord_delete(GeoIPRecord *gir); + +#ifdef __cplusplus +} +#endif + +#endif /* GEOIPCITY_H */ diff --git a/libGeoIP/GeoIP_deprecated.c b/libGeoIP/GeoIP_deprecated.c new file mode 100644 index 0000000..aae3685 --- /dev/null +++ b/libGeoIP/GeoIP_deprecated.c @@ -0,0 +1,248 @@ + +#include "GeoIP_internal.h" + +char *GeoIP_org_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_gl(gi, ipnum, &gl); +} + +char *GeoIP_org_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +char *GeoIP_org_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_gl(gi, addr, &gl); +} + +char *GeoIP_org_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_v6_gl(gi, addr, &gl); +} + +char *GeoIP_org_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_gl(gi, name, &gl); +} + +char *GeoIP_org_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_v6_gl(gi, name, &gl); +} + +int GeoIP_last_netmask(GeoIP *gi) { return gi->netmask; } + +unsigned int _GeoIP_seek_record_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return _GeoIP_seek_record_v6_gl(gi, ipnum, &gl); +} + +unsigned int _GeoIP_seek_record(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return _GeoIP_seek_record_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_code_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code_by_name_gl(gi, name, &gl); +} + +const char *GeoIP_country_code3_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code3_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_code3_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code3_by_name_gl(gi, name, &gl); +} + +const char *GeoIP_country_name_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_name_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_name_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_name_by_name_gl(gi, name, &gl); +} + +int GeoIP_id_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_id_by_name_gl(gi, name, &gl); +} +int GeoIP_id_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_id_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_code_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code_by_addr_v6_gl(gi, addr, &gl); +} +const char *GeoIP_country_code_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code_by_addr_gl(gi, addr, &gl); +} + +const char *GeoIP_country_code3_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code3_by_addr_v6_gl(gi, addr, &gl); +} + +const char *GeoIP_country_code3_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code3_by_addr_gl(gi, addr, &gl); +} + +const char *GeoIP_country_name_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_name_by_addr_v6_gl(gi, addr, &gl); +} +const char *GeoIP_country_name_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_name_by_addr_gl(gi, addr, &gl); +} + +const char *GeoIP_country_name_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_country_name_by_ipnum_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_name_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_country_name_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_country_code_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_country_code_by_ipnum_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code3_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_country_code3_by_ipnum_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code3_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_country_code3_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +int GeoIP_country_id_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_v6_gl(gi, addr, &gl); +} + +int GeoIP_country_id_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_gl(gi, addr, &gl); +} +int GeoIP_country_id_by_name_v6(GeoIP *gi, const char *host) { + GeoIPLookup gl; + return GeoIP_id_by_name_v6_gl(gi, host, &gl); +} +int GeoIP_country_id_by_name(GeoIP *gi, const char *host) { + GeoIPLookup gl; + return GeoIP_id_by_name_gl(gi, host, &gl); +} +int GeoIP_id_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_v6_gl(gi, addr, &gl); +} +int GeoIP_id_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_gl(gi, addr, &gl); +} + +int GeoIP_id_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_id_by_ipnum_v6_gl(gi, ipnum, &gl); +} +int GeoIP_id_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_id_by_ipnum_gl(gi, ipnum, &gl); +} +void GeoIP_assign_region_by_inetaddr(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *region) { + GeoIPLookup gl; + GeoIP_assign_region_by_inetaddr_gl(gi, inetaddr, region, &gl); +} + +void GeoIP_assign_region_by_inetaddr_v6(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *region) { + GeoIPLookup gl; + GeoIP_assign_region_by_inetaddr_v6_gl(gi, inetaddr, region, &gl); +} + +GeoIPRegion *GeoIP_region_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_region_by_addr_gl(gi, addr, &gl); +} +GeoIPRegion *GeoIP_region_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_region_by_addr_v6_gl(gi, addr, &gl); +} + +GeoIPRegion *GeoIP_region_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_region_by_name_gl(gi, name, &gl); +} +GeoIPRegion *GeoIP_region_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_region_by_name_v6_gl(gi, name, &gl); +} + +GeoIPRegion *GeoIP_region_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_region_by_ipnum_gl(gi, ipnum, &gl); +} +GeoIPRegion *GeoIP_region_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_region_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +char **GeoIP_range_by_ip(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_range_by_ip_gl(gi, addr, &gl); +} + +char *GeoIP_name_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_gl(gi, ipnum, &gl); +} +char *GeoIP_name_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_v6_gl(gi, ipnum, &gl); +} +char *GeoIP_name_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_gl(gi, addr, &gl); +} +char *GeoIP_name_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_v6_gl(gi, addr, &gl); +} + +char *GeoIP_name_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_gl(gi, name, &gl); +} + +char *GeoIP_name_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_v6_gl(gi, name, &gl); +} diff --git a/libGeoIP/GeoIP_internal.h b/libGeoIP/GeoIP_internal.h new file mode 100644 index 0000000..2c96587 --- /dev/null +++ b/libGeoIP/GeoIP_internal.h @@ -0,0 +1,23 @@ +#ifndef GEOIP_INTERNAL_H +#define GEOIP_INTERNAL_H + +#include "GeoIP.h" + +GEOIP_API unsigned int +_GeoIP_seek_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API unsigned int +_GeoIP_seek_record_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API geoipv6_t _GeoIP_addr_to_num_v6(const char *addr); + +GEOIP_API unsigned long _GeoIP_lookupaddress(const char *host); +GEOIP_API geoipv6_t _GeoIP_lookupaddress_v6(const char *host); +GEOIP_API int __GEOIP_V6_IS_NULL(geoipv6_t v6); + +GEOIP_API void _GeoIP_setup_dbfilename(void); +GEOIP_API char *_GeoIP_full_path_to(const char *file_name); + +/* deprecated */ +GEOIP_API unsigned int _GeoIP_seek_record(GeoIP *gi, unsigned long ipnum); +GEOIP_API unsigned int _GeoIP_seek_record_v6(GeoIP *gi, geoipv6_t ipnum); + +#endif diff --git a/libGeoIP/Makefile.am b/libGeoIP/Makefile.am new file mode 100644 index 0000000..f85cd00 --- /dev/null +++ b/libGeoIP/Makefile.am @@ -0,0 +1,19 @@ +lib_LTLIBRARIES = libGeoIP.la + +EXTRA_DIST = Makefile.vc GeoIP_internal.h pread.c pread.h + +AM_CPPFLAGS = -DGEOIPDATADIR=\"$(pkgdatadir)\" -Wall + +libGeoIP_la_SOURCES = GeoIP.c GeoIP_deprecated.c GeoIPCity.c regionName.c timeZone.c +include_HEADERS = GeoIP.h GeoIPCity.h + +libGeoIP_la_LDFLAGS = -no-undefined -version-info @GEOIP_VERSION_INFO@ + +GeoIP.lo GeoIP.o: GeoIP.c GeoIP_deprecated.c GeoIP.h + +GeoIPCity.lo GeoIPCity.o: GeoIPCity.c GeoIP.h + +regionName.lo regionName.o: regionName.c + +timeZone.lo timeZone.o: timeZone.c + diff --git a/libGeoIP/Makefile.vc b/libGeoIP/Makefile.vc new file mode 100644 index 0000000..157e014 --- /dev/null +++ b/libGeoIP/Makefile.vc @@ -0,0 +1,47 @@ +#NMAKE makefile for Windows developers. +##Produces a static library (GeoIP.lib). +#Produces a DLL (GeoIP.dll) and library (GeoIP.lib). + +COMPILER=cl + +CFLAGS=-DWIN32 -DGEOIP_EXPORTS -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DGEOIPDATADIR=\"$(GEOIPDATADIR)\" -DPACKAGE_VERSION=\"1.6.3\" + +LINKER=link + +LDFLAGS=/DLL /nologo /subsystem:console + +LD1 = $(LINKER) $(LDFLAGS) + +OBJS=GeoIP.obj GeoIPCity.obj GeoIP_deprecated.obj regionName.obj timeZone.obj pread.obj + +EXTRA_LIBS= ws2_32.lib + +AR=lib + +#GeoIP.lib: GeoIP.obj GeoIPCity.obj regionName.obj md5.obj timeZone.obj +# $(AR) -nologo $(OBJS) $(EXTRA_LIBS) /OUT:GeoIP.lib + +GeoIP.dll GeoIP.lib: $(OBJS) + $(LD1) $(OBJS) $(EXTRA_LIBS) /out:GeoIP.dll /implib:GeoIP.lib + +GeoIP.obj: GeoIP.c + $(CC1) -c GeoIP.c $(GEOIPINC) + +GeoIPCity.obj: GeoIPCity.c + $(CC1) -c GeoIPCity.c $(GEOIPINC) + +GeoIP_deprecated.obj: GeoIP_deprecated.c + $(CC1) -c GeoIP_deprecated.c $(GEOIPINC) + +regionName.obj: regionName.c + $(CC1) -c regionName.c $(GEOIPINC) + +timeZone.obj: timeZone.c + $(CC1) -c timeZone.c $(GEOIPINC) + +pread.obj: pread.c + $(CC1) -c pread.c $(GEOIPINC) diff --git a/libGeoIP/pread.c b/libGeoIP/pread.c new file mode 100644 index 0000000..ae5f462 --- /dev/null +++ b/libGeoIP/pread.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include <io.h> +#include <stdio.h> +#include <windows.h> + +#include "pread.h" + +static CRITICAL_SECTION preadsc; + +/* http://stackoverflow.com/a/2390626/1392778 */ + +#ifdef _MSC_VER +#pragma section(".CRT$XCU", read) +#define INITIALIZER2_(f, p) \ + static void __cdecl f(void); \ + __declspec(allocate(".CRT$XCU")) void(__cdecl * f##_)(void) = f; \ + __pragma(comment(linker, "/include:" p #f "_")) static void __cdecl f(void) +#ifdef _WIN64 +#define INITIALIZER(f) INITIALIZER2_(f, "") +#else +#define INITIALIZER(f) INITIALIZER2_(f, "_") +#endif +#elif defined(__GNUC__) +#define INITIALIZER(f) \ + static void f(void) __attribute__((constructor)); \ + static void f(void) +#endif + +#ifdef _WIN64 +int pread(int fd, void *buf, unsigned int nbyte, __int64 offset) { + int cc = -1; + __int64 prev = (__int64)-1L; + + EnterCriticalSection(&preadsc); + prev = _lseeki64(fd, 0L, SEEK_CUR); + if (prev == (__int64)-1L) { + goto done; + } + if (_lseeki64(fd, offset, SEEK_SET) != offset) { + goto done; + } + cc = _read(fd, buf, nbyte); + +done: + if (prev != (__int64)-1L) { + (void)_lseeki64(fd, prev, SEEK_SET); + } + LeaveCriticalSection(&preadsc); + + return cc; +} +#else +int pread(int fd, void *buf, unsigned int nbyte, long offset) { + int cc = -1; + long prev = -1L; + + EnterCriticalSection(&preadsc); + prev = _lseek(fd, 0L, SEEK_CUR); + if (prev == -1L) { + goto done; + } + if (_lseek(fd, offset, SEEK_SET) != offset) { + goto done; + } + cc = _read(fd, buf, nbyte); + +done: + if (prev != -1L) { + (void)_lseek(fd, prev, SEEK_SET); + } + LeaveCriticalSection(&preadsc); + + return cc; +} +#endif + +static void deinitialize(void) { DeleteCriticalSection(&preadsc); } + +INITIALIZER(initialize) { + InitializeCriticalSection(&preadsc); + atexit(deinitialize); +} diff --git a/libGeoIP/pread.h b/libGeoIP/pread.h new file mode 100644 index 0000000..4e48949 --- /dev/null +++ b/libGeoIP/pread.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef _WIN64 +typedef __int64 ssize_t; + +int pread(int fd, void *buf, unsigned int nbyte, __int64 offset); +#else +typedef int ssize_t; + +int pread(int fd, void *buf, unsigned int nbyte, long offset); +#endif + +#define HAVE_PREAD diff --git a/libGeoIP/regionName.c b/libGeoIP/regionName.c new file mode 100644 index 0000000..60f6260 --- /dev/null +++ b/libGeoIP/regionName.c @@ -0,0 +1,10197 @@ +#include "GeoIP.h" +#include <stdio.h> +#include <string.h> + +static const char *get_region_name_AD(int region_code) { + switch (region_code) { + case 3: + return "Encamp"; + case 4: + return "La Massana"; + case 5: + return "Ordino"; + case 6: + return "Sant Julia de Loria"; + case 7: + return "Andorra la Vella"; + case 8: + return "Escaldes-Engordany"; + default: + return NULL; + } +} + +static const char *get_region_name_AE(int region_code) { + switch (region_code) { + case 1: + return "Abu Dhabi"; + case 2: + return "Ajman"; + case 3: + return "Dubai"; + case 4: + return "Fujairah"; + case 5: + return "Ras Al Khaimah"; + case 6: + return "Sharjah"; + case 7: + return "Umm Al Quwain"; + default: + return NULL; + } +} + +static const char *get_region_name_AF(int region_code) { + switch (region_code) { + case 1: + return "Badakhshan"; + case 2: + return "Badghis"; + case 3: + return "Baghlan"; + case 5: + return "Bamian"; + case 6: + return "Farah"; + case 7: + return "Faryab"; + case 8: + return "Ghazni"; + case 9: + return "Ghowr"; + case 10: + return "Helmand"; + case 11: + return "Herat"; + case 13: + return "Kabol"; + case 14: + return "Kapisa"; + case 17: + return "Lowgar"; + case 18: + return "Nangarhar"; + case 19: + return "Nimruz"; + case 23: + return "Kandahar"; + case 24: + return "Kondoz"; + case 26: + return "Takhar"; + case 27: + return "Vardak"; + case 28: + return "Zabol"; + case 29: + return "Paktika"; + case 30: + return "Balkh"; + case 31: + return "Jowzjan"; + case 32: + return "Samangan"; + case 33: + return "Sar-e Pol"; + case 34: + return "Konar"; + case 35: + return "Laghman"; + case 36: + return "Paktia"; + case 37: + return "Khowst"; + case 38: + return "Nurestan"; + case 39: + return "Oruzgan"; + case 40: + return "Parvan"; + case 41: + return "Daykondi"; + case 42: + return "Panjshir"; + default: + return NULL; + } +} + +static const char *get_region_name_AG(int region_code) { + switch (region_code) { + case 1: + return "Barbuda"; + case 3: + return "Saint George"; + case 4: + return "Saint John"; + case 5: + return "Saint Mary"; + case 6: + return "Saint Paul"; + case 7: + return "Saint Peter"; + case 8: + return "Saint Philip"; + case 9: + return "Redonda"; + default: + return NULL; + } +} + +static const char *get_region_name_AL(int region_code) { + switch (region_code) { + case 40: + return "Berat"; + case 41: + return "Diber"; + case 42: + return "Durres"; + case 43: + return "Elbasan"; + case 44: + return "Fier"; + case 45: + return "Gjirokaster"; + case 46: + return "Korce"; + case 47: + return "Kukes"; + case 48: + return "Lezhe"; + case 49: + return "Shkoder"; + case 50: + return "Tirane"; + case 51: + return "Vlore"; + default: + return NULL; + } +} + +static const char *get_region_name_AM(int region_code) { + switch (region_code) { + case 1: + return "Aragatsotn"; + case 2: + return "Ararat"; + case 3: + return "Armavir"; + case 4: + return "Geghark'unik'"; + case 5: + return "Kotayk'"; + case 6: + return "Lorri"; + case 7: + return "Shirak"; + case 8: + return "Syunik'"; + case 9: + return "Tavush"; + case 10: + return "Vayots' Dzor"; + case 11: + return "Yerevan"; + default: + return NULL; + } +} + +static const char *get_region_name_AO(int region_code) { + switch (region_code) { + case 1: + return "Benguela"; + case 2: + return "Bie"; + case 3: + return "Cabinda"; + case 4: + return "Cuando Cubango"; + case 5: + return "Cuanza Norte"; + case 6: + return "Cuanza Sul"; + case 7: + return "Cunene"; + case 8: + return "Huambo"; + case 9: + return "Huila"; + case 12: + return "Malanje"; + case 13: + return "Namibe"; + case 14: + return "Moxico"; + case 15: + return "Uige"; + case 16: + return "Zaire"; + case 17: + return "Lunda Norte"; + case 18: + return "Lunda Sul"; + case 19: + return "Bengo"; + case 20: + return "Luanda"; + default: + return NULL; + } +} + +static const char *get_region_name_AR(int region_code) { + switch (region_code) { + case 1: + return "Buenos Aires"; + case 2: + return "Catamarca"; + case 3: + return "Chaco"; + case 4: + return "Chubut"; + case 5: + return "Cordoba"; + case 6: + return "Corrientes"; + case 7: + return "Distrito Federal"; + case 8: + return "Entre Rios"; + case 9: + return "Formosa"; + case 10: + return "Jujuy"; + case 11: + return "La Pampa"; + case 12: + return "La Rioja"; + case 13: + return "Mendoza"; + case 14: + return "Misiones"; + case 15: + return "Neuquen"; + case 16: + return "Rio Negro"; + case 17: + return "Salta"; + case 18: + return "San Juan"; + case 19: + return "San Luis"; + case 20: + return "Santa Cruz"; + case 21: + return "Santa Fe"; + case 22: + return "Santiago del Estero"; + case 23: + return "Tierra del Fuego"; + case 24: + return "Tucuman"; + default: + return NULL; + } +} + +static const char *get_region_name_AT(int region_code) { + switch (region_code) { + case 1: + return "Burgenland"; + case 2: + return "Karnten"; + case 3: + return "Niederosterreich"; + case 4: + return "Oberosterreich"; + case 5: + return "Salzburg"; + case 6: + return "Steiermark"; + case 7: + return "Tirol"; + case 8: + return "Vorarlberg"; + case 9: + return "Wien"; + default: + return NULL; + } +} + +static const char *get_region_name_AU(int region_code) { + switch (region_code) { + case 1: + return "Australian Capital Territory"; + case 2: + return "New South Wales"; + case 3: + return "Northern Territory"; + case 4: + return "Queensland"; + case 5: + return "South Australia"; + case 6: + return "Tasmania"; + case 7: + return "Victoria"; + case 8: + return "Western Australia"; + default: + return NULL; + } +} + +static const char *get_region_name_AZ(int region_code) { + switch (region_code) { + case 1: + return "Abseron"; + case 2: + return "Agcabadi"; + case 3: + return "Agdam"; + case 4: + return "Agdas"; + case 5: + return "Agstafa"; + case 6: + return "Agsu"; + case 7: + return "Ali Bayramli"; + case 8: + return "Astara"; + case 9: + return "Baki"; + case 10: + return "Balakan"; + case 11: + return "Barda"; + case 12: + return "Beylaqan"; + case 13: + return "Bilasuvar"; + case 14: + return "Cabrayil"; + case 15: + return "Calilabad"; + case 16: + return "Daskasan"; + case 17: + return "Davaci"; + case 18: + return "Fuzuli"; + case 19: + return "Gadabay"; + case 20: + return "Ganca"; + case 21: + return "Goranboy"; + case 22: + return "Goycay"; + case 23: + return "Haciqabul"; + case 24: + return "Imisli"; + case 25: + return "Ismayilli"; + case 26: + return "Kalbacar"; + case 27: + return "Kurdamir"; + case 28: + return "Lacin"; + case 29: + return "Lankaran"; + case 30: + return "Lankaran"; + case 31: + return "Lerik"; + case 32: + return "Masalli"; + case 33: + return "Mingacevir"; + case 34: + return "Naftalan"; + case 35: + return "Naxcivan"; + case 36: + return "Neftcala"; + case 37: + return "Oguz"; + case 38: + return "Qabala"; + case 39: + return "Qax"; + case 40: + return "Qazax"; + case 41: + return "Qobustan"; + case 42: + return "Quba"; + case 43: + return "Qubadli"; + case 44: + return "Qusar"; + case 45: + return "Saatli"; + case 46: + return "Sabirabad"; + case 47: + return "Saki"; + case 48: + return "Saki"; + case 49: + return "Salyan"; + case 50: + return "Samaxi"; + case 51: + return "Samkir"; + case 52: + return "Samux"; + case 53: + return "Siyazan"; + case 54: + return "Sumqayit"; + case 55: + return "Susa"; + case 56: + return "Susa"; + case 57: + return "Tartar"; + case 58: + return "Tovuz"; + case 59: + return "Ucar"; + case 60: + return "Xacmaz"; + case 61: + return "Xankandi"; + case 62: + return "Xanlar"; + case 63: + return "Xizi"; + case 64: + return "Xocali"; + case 65: + return "Xocavand"; + case 66: + return "Yardimli"; + case 67: + return "Yevlax"; + case 68: + return "Yevlax"; + case 69: + return "Zangilan"; + case 70: + return "Zaqatala"; + case 71: + return "Zardab"; + default: + return NULL; + } +} + +static const char *get_region_name_BA(int region_code) { + switch (region_code) { + case 1: + return "Federation of Bosnia and Herzegovina"; + case 3: + return "Brcko District"; + case 2: + return "Republika Srpska"; + default: + return NULL; + } +} + +static const char *get_region_name_BB(int region_code) { + switch (region_code) { + case 1: + return "Christ Church"; + case 2: + return "Saint Andrew"; + case 3: + return "Saint George"; + case 4: + return "Saint James"; + case 5: + return "Saint John"; + case 6: + return "Saint Joseph"; + case 7: + return "Saint Lucy"; + case 8: + return "Saint Michael"; + case 9: + return "Saint Peter"; + case 10: + return "Saint Philip"; + case 11: + return "Saint Thomas"; + default: + return NULL; + } +} + +static const char *get_region_name_BD(int region_code) { + switch (region_code) { + case 81: + return "Dhaka"; + case 82: + return "Khulna"; + case 83: + return "Rajshahi"; + case 84: + return "Chittagong"; + case 85: + return "Barisal"; + case 86: + return "Sylhet"; + case 87: + return "Rangpur"; + default: + return NULL; + } +} + +static const char *get_region_name_BE(int region_code) { + switch (region_code) { + case 1: + return "Antwerpen"; + case 3: + return "Hainaut"; + case 4: + return "Liege"; + case 5: + return "Limburg"; + case 6: + return "Luxembourg"; + case 7: + return "Namur"; + case 8: + return "Oost-Vlaanderen"; + case 9: + return "West-Vlaanderen"; + case 10: + return "Brabant Wallon"; + case 11: + return "Brussels Hoofdstedelijk Gewest"; + case 12: + return "Vlaams-Brabant"; + case 13: + return "Flanders"; + case 14: + return "Wallonia"; + default: + return NULL; + } +} + +static const char *get_region_name_BF(int region_code) { + switch (region_code) { + case 15: + return "Bam"; + case 19: + return "Boulkiemde"; + case 20: + return "Ganzourgou"; + case 21: + return "Gnagna"; + case 28: + return "Kouritenga"; + case 33: + return "Oudalan"; + case 34: + return "Passore"; + case 36: + return "Sanguie"; + case 40: + return "Soum"; + case 42: + return "Tapoa"; + case 44: + return "Zoundweogo"; + case 45: + return "Bale"; + case 46: + return "Banwa"; + case 47: + return "Bazega"; + case 48: + return "Bougouriba"; + case 49: + return "Boulgou"; + case 50: + return "Gourma"; + case 51: + return "Houet"; + case 52: + return "Ioba"; + case 53: + return "Kadiogo"; + case 54: + return "Kenedougou"; + case 55: + return "Komoe"; + case 56: + return "Komondjari"; + case 57: + return "Kompienga"; + case 58: + return "Kossi"; + case 59: + return "Koulpelogo"; + case 60: + return "Kourweogo"; + case 61: + return "Leraba"; + case 62: + return "Loroum"; + case 63: + return "Mouhoun"; + case 64: + return "Namentenga"; + case 65: + return "Naouri"; + case 66: + return "Nayala"; + case 67: + return "Noumbiel"; + case 68: + return "Oubritenga"; + case 69: + return "Poni"; + case 70: + return "Sanmatenga"; + case 71: + return "Seno"; + case 72: + return "Sissili"; + case 73: + return "Sourou"; + case 74: + return "Tuy"; + case 75: + return "Yagha"; + case 76: + return "Yatenga"; + case 77: + return "Ziro"; + case 78: + return "Zondoma"; + default: + return NULL; + } +} + +static const char *get_region_name_BG(int region_code) { + switch (region_code) { + case 33: + return "Mikhaylovgrad"; + case 38: + return "Blagoevgrad"; + case 39: + return "Burgas"; + case 40: + return "Dobrich"; + case 41: + return "Gabrovo"; + case 42: + return "Grad Sofiya"; + case 43: + return "Khaskovo"; + case 44: + return "Kurdzhali"; + case 45: + return "Kyustendil"; + case 46: + return "Lovech"; + case 47: + return "Montana"; + case 48: + return "Pazardzhik"; + case 49: + return "Pernik"; + case 50: + return "Pleven"; + case 51: + return "Plovdiv"; + case 52: + return "Razgrad"; + case 53: + return "Ruse"; + case 54: + return "Shumen"; + case 55: + return "Silistra"; + case 56: + return "Sliven"; + case 57: + return "Smolyan"; + case 58: + return "Sofiya"; + case 59: + return "Stara Zagora"; + case 60: + return "Turgovishte"; + case 61: + return "Varna"; + case 62: + return "Veliko Turnovo"; + case 63: + return "Vidin"; + case 64: + return "Vratsa"; + case 65: + return "Yambol"; + default: + return NULL; + } +} + +static const char *get_region_name_BH(int region_code) { + switch (region_code) { + case 1: + return "Al Hadd"; + case 2: + return "Al Manamah"; + case 5: + return "Jidd Hafs"; + case 6: + return "Sitrah"; + case 8: + return "Al Mintaqah al Gharbiyah"; + case 9: + return "Mintaqat Juzur Hawar"; + case 10: + return "Al Mintaqah ash Shamaliyah"; + case 11: + return "Al Mintaqah al Wusta"; + case 12: + return "Madinat"; + case 13: + return "Ar Rifa"; + case 14: + return "Madinat Hamad"; + case 15: + return "Al Muharraq"; + case 16: + return "Al Asimah"; + case 17: + return "Al Janubiyah"; + case 18: + return "Ash Shamaliyah"; + case 19: + return "Al Wusta"; + default: + return NULL; + } +} + +static const char *get_region_name_BI(int region_code) { + switch (region_code) { + case 2: + return "Bujumbura"; + case 9: + return "Bubanza"; + case 10: + return "Bururi"; + case 11: + return "Cankuzo"; + case 12: + return "Cibitoke"; + case 13: + return "Gitega"; + case 14: + return "Karuzi"; + case 15: + return "Kayanza"; + case 16: + return "Kirundo"; + case 17: + return "Makamba"; + case 18: + return "Muyinga"; + case 19: + return "Ngozi"; + case 20: + return "Rutana"; + case 21: + return "Ruyigi"; + case 22: + return "Muramvya"; + case 23: + return "Mwaro"; + default: + return NULL; + } +} + +static const char *get_region_name_BJ(int region_code) { + switch (region_code) { + case 7: + return "Alibori"; + case 8: + return "Atakora"; + case 9: + return "Atlanyique"; + case 10: + return "Borgou"; + case 11: + return "Collines"; + case 12: + return "Kouffo"; + case 13: + return "Donga"; + case 14: + return "Littoral"; + case 15: + return "Mono"; + case 16: + return "Oueme"; + case 17: + return "Plateau"; + case 18: + return "Zou"; + default: + return NULL; + } +} + +static const char *get_region_name_BM(int region_code) { + switch (region_code) { + case 1: + return "Devonshire"; + case 2: + return "Hamilton"; + case 3: + return "Hamilton"; + case 4: + return "Paget"; + case 5: + return "Pembroke"; + case 6: + return "Saint George"; + case 7: + return "Saint George's"; + case 8: + return "Sandys"; + case 9: + return "Smiths"; + case 10: + return "Southampton"; + case 11: + return "Warwick"; + default: + return NULL; + } +} + +static const char *get_region_name_BN(int region_code) { + switch (region_code) { + case 7: + return "Alibori"; + case 8: + return "Belait"; + case 9: + return "Brunei and Muara"; + case 10: + return "Temburong"; + case 11: + return "Collines"; + case 12: + return "Kouffo"; + case 13: + return "Donga"; + case 14: + return "Littoral"; + case 15: + return "Tutong"; + case 16: + return "Oueme"; + case 17: + return "Plateau"; + case 18: + return "Zou"; + default: + return NULL; + } +} + +static const char *get_region_name_BO(int region_code) { + switch (region_code) { + case 1: + return "Chuquisaca"; + case 2: + return "Cochabamba"; + case 3: + return "El Beni"; + case 4: + return "La Paz"; + case 5: + return "Oruro"; + case 6: + return "Pando"; + case 7: + return "Potosi"; + case 8: + return "Santa Cruz"; + case 9: + return "Tarija"; + default: + return NULL; + } +} + +static const char *get_region_name_BR(int region_code) { + switch (region_code) { + case 1: + return "Acre"; + case 2: + return "Alagoas"; + case 3: + return "Amapa"; + case 4: + return "Amazonas"; + case 5: + return "Bahia"; + case 6: + return "Ceara"; + case 7: + return "Distrito Federal"; + case 8: + return "Espirito Santo"; + case 11: + return "Mato Grosso do Sul"; + case 13: + return "Maranhao"; + case 14: + return "Mato Grosso"; + case 15: + return "Minas Gerais"; + case 16: + return "Para"; + case 17: + return "Paraiba"; + case 18: + return "Parana"; + case 20: + return "Piaui"; + case 21: + return "Rio de Janeiro"; + case 22: + return "Rio Grande do Norte"; + case 23: + return "Rio Grande do Sul"; + case 24: + return "Rondonia"; + case 25: + return "Roraima"; + case 26: + return "Santa Catarina"; + case 27: + return "Sao Paulo"; + case 28: + return "Sergipe"; + case 29: + return "Goias"; + case 30: + return "Pernambuco"; + case 31: + return "Tocantins"; + default: + return NULL; + } +} + +static const char *get_region_name_BS(int region_code) { + switch (region_code) { + case 5: + return "Bimini"; + case 6: + return "Cat Island"; + case 10: + return "Exuma"; + case 13: + return "Inagua"; + case 15: + return "Long Island"; + case 16: + return "Mayaguana"; + case 18: + return "Ragged Island"; + case 22: + return "Harbour Island"; + case 23: + return "New Providence"; + case 24: + return "Acklins and Crooked Islands"; + case 25: + return "Freeport"; + case 26: + return "Fresh Creek"; + case 27: + return "Governor's Harbour"; + case 28: + return "Green Turtle Cay"; + case 29: + return "High Rock"; + case 30: + return "Kemps Bay"; + case 31: + return "Marsh Harbour"; + case 32: + return "Nichollstown and Berry Islands"; + case 33: + return "Rock Sound"; + case 34: + return "Sandy Point"; + case 35: + return "San Salvador and Rum Cay"; + default: + return NULL; + } +} + +static const char *get_region_name_BT(int region_code) { + switch (region_code) { + case 5: + return "Bumthang"; + case 6: + return "Chhukha"; + case 7: + return "Chirang"; + case 8: + return "Daga"; + case 9: + return "Geylegphug"; + case 10: + return "Ha"; + case 11: + return "Lhuntshi"; + case 12: + return "Mongar"; + case 13: + return "Paro"; + case 14: + return "Pemagatsel"; + case 15: + return "Punakha"; + case 16: + return "Samchi"; + case 17: + return "Samdrup"; + case 18: + return "Shemgang"; + case 19: + return "Tashigang"; + case 20: + return "Thimphu"; + case 21: + return "Tongsa"; + case 22: + return "Wangdi Phodrang"; + default: + return NULL; + } +} + +static const char *get_region_name_BW(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 3: + return "Ghanzi"; + case 4: + return "Kgalagadi"; + case 5: + return "Kgatleng"; + case 6: + return "Kweneng"; + case 8: + return "North-East"; + case 9: + return "South-East"; + case 10: + return "Southern"; + case 11: + return "North-West"; + default: + return NULL; + } +} + +static const char *get_region_name_BY(int region_code) { + switch (region_code) { + case 1: + return "Brestskaya Voblasts'"; + case 2: + return "Homyel'skaya Voblasts'"; + case 3: + return "Hrodzyenskaya Voblasts'"; + case 4: + return "Minsk"; + case 5: + return "Minskaya Voblasts'"; + case 6: + return "Mahilyowskaya Voblasts'"; + case 7: + return "Vitsyebskaya Voblasts'"; + default: + return NULL; + } +} + +static const char *get_region_name_BZ(int region_code) { + switch (region_code) { + case 1: + return "Belize"; + case 2: + return "Cayo"; + case 3: + return "Corozal"; + case 4: + return "Orange Walk"; + case 5: + return "Stann Creek"; + case 6: + return "Toledo"; + default: + return NULL; + } +} + +static const char *get_region_name_CA(int region_code) { + switch (region_code) { + case 849: + return "Alberta"; + case 893: + return "British Columbia"; + case 1365: + return "Manitoba"; + case 1408: + return "New Brunswick"; + case 1418: + return "Newfoundland"; + case 1425: + return "Nova Scotia"; + case 1426: + return "Northwest Territories"; + case 1427: + return "Nunavut"; + case 1463: + return "Ontario"; + case 1497: + return "Prince Edward Island"; + case 1538: + return "Quebec"; + case 1632: + return "Saskatchewan"; + case 1899: + return "Yukon Territory"; + default: + return NULL; + } +} + +static const char *get_region_name_CD(int region_code) { + switch (region_code) { + case 1: + return "Bandundu"; + case 2: + return "Equateur"; + case 4: + return "Kasai-Oriental"; + case 5: + return "Katanga"; + case 6: + return "Kinshasa"; + case 8: + return "Bas-Congo"; + case 9: + return "Orientale"; + case 10: + return "Maniema"; + case 11: + return "Nord-Kivu"; + case 12: + return "Sud-Kivu"; + default: + return NULL; + } +} + +static const char *get_region_name_CF(int region_code) { + switch (region_code) { + case 1: + return "Bamingui-Bangoran"; + case 2: + return "Basse-Kotto"; + case 3: + return "Haute-Kotto"; + case 4: + return "Mambere-Kadei"; + case 5: + return "Haut-Mbomou"; + case 6: + return "Kemo"; + case 7: + return "Lobaye"; + case 8: + return "Mbomou"; + case 9: + return "Nana-Mambere"; + case 11: + return "Ouaka"; + case 12: + return "Ouham"; + case 13: + return "Ouham-Pende"; + case 14: + return "Cuvette-Ouest"; + case 15: + return "Nana-Grebizi"; + case 16: + return "Sangha-Mbaere"; + case 17: + return "Ombella-Mpoko"; + case 18: + return "Bangui"; + default: + return NULL; + } +} + +static const char *get_region_name_CG(int region_code) { + switch (region_code) { + case 1: + return "Bouenza"; + case 4: + return "Kouilou"; + case 5: + return "Lekoumou"; + case 6: + return "Likouala"; + case 7: + return "Niari"; + case 8: + return "Plateaux"; + case 10: + return "Sangha"; + case 11: + return "Pool"; + case 12: + return "Brazzaville"; + case 13: + return "Cuvette"; + case 14: + return "Cuvette-Ouest"; + default: + return NULL; + } +} + +static const char *get_region_name_CH(int region_code) { + switch (region_code) { + case 1: + return "Aargau"; + case 2: + return "Ausser-Rhoden"; + case 3: + return "Basel-Landschaft"; + case 4: + return "Basel-Stadt"; + case 5: + return "Bern"; + case 6: + return "Fribourg"; + case 7: + return "Geneve"; + case 8: + return "Glarus"; + case 9: + return "Graubunden"; + case 10: + return "Inner-Rhoden"; + case 11: + return "Luzern"; + case 12: + return "Neuchatel"; + case 13: + return "Nidwalden"; + case 14: + return "Obwalden"; + case 15: + return "Sankt Gallen"; + case 16: + return "Schaffhausen"; + case 17: + return "Schwyz"; + case 18: + return "Solothurn"; + case 19: + return "Thurgau"; + case 20: + return "Ticino"; + case 21: + return "Uri"; + case 22: + return "Valais"; + case 23: + return "Vaud"; + case 24: + return "Zug"; + case 25: + return "Zurich"; + case 26: + return "Jura"; + default: + return NULL; + } +} + +static const char *get_region_name_CI(int region_code) { + switch (region_code) { + case 74: + return "Agneby"; + case 75: + return "Bafing"; + case 76: + return "Bas-Sassandra"; + case 77: + return "Denguele"; + case 78: + return "Dix-Huit Montagnes"; + case 79: + return "Fromager"; + case 80: + return "Haut-Sassandra"; + case 81: + return "Lacs"; + case 82: + return "Lagunes"; + case 83: + return "Marahoue"; + case 84: + return "Moyen-Cavally"; + case 85: + return "Moyen-Comoe"; + case 86: + return "N'zi-Comoe"; + case 87: + return "Savanes"; + case 88: + return "Sud-Bandama"; + case 89: + return "Sud-Comoe"; + case 90: + return "Vallee du Bandama"; + case 91: + return "Worodougou"; + case 92: + return "Zanzan"; + default: + return NULL; + } +} + +static const char *get_region_name_CL(int region_code) { + switch (region_code) { + case 1: + return "Valparaiso"; + case 2: + return "Aisen del General Carlos Ibanez del Campo"; + case 3: + return "Antofagasta"; + case 4: + return "Araucania"; + case 5: + return "Atacama"; + case 6: + return "Bio-Bio"; + case 7: + return "Coquimbo"; + case 8: + return "Libertador General Bernardo O'Higgins"; + case 9: + return "Los Lagos"; + case 10: + return "Magallanes y de la Antartica Chilena"; + case 11: + return "Maule"; + case 12: + return "Region Metropolitana"; + case 13: + return "Tarapaca"; + case 14: + return "Los Lagos"; + case 15: + return "Tarapaca"; + case 16: + return "Arica y Parinacota"; + case 17: + return "Los Rios"; + default: + return NULL; + } +} + +static const char *get_region_name_CM(int region_code) { + switch (region_code) { + case 4: + return "Est"; + case 5: + return "Littoral"; + case 7: + return "Nord-Ouest"; + case 8: + return "Ouest"; + case 9: + return "Sud-Ouest"; + case 10: + return "Adamaoua"; + case 11: + return "Centre"; + case 12: + return "Extreme-Nord"; + case 13: + return "Nord"; + case 14: + return "Sud"; + default: + return NULL; + } +} + +static const char *get_region_name_CN(int region_code) { + switch (region_code) { + case 1: + return "Anhui"; + case 2: + return "Zhejiang"; + case 3: + return "Jiangxi"; + case 4: + return "Jiangsu"; + case 5: + return "Jilin"; + case 6: + return "Qinghai"; + case 7: + return "Fujian"; + case 8: + return "Heilongjiang"; + case 9: + return "Henan"; + case 10: + return "Hebei"; + case 11: + return "Hunan"; + case 12: + return "Hubei"; + case 13: + return "Xinjiang"; + case 14: + return "Xizang"; + case 15: + return "Gansu"; + case 16: + return "Guangxi"; + case 18: + return "Guizhou"; + case 19: + return "Liaoning"; + case 20: + return "Nei Mongol"; + case 21: + return "Ningxia"; + case 22: + return "Beijing"; + case 23: + return "Shanghai"; + case 24: + return "Shanxi"; + case 25: + return "Shandong"; + case 26: + return "Shaanxi"; + case 28: + return "Tianjin"; + case 29: + return "Yunnan"; + case 30: + return "Guangdong"; + case 31: + return "Hainan"; + case 32: + return "Sichuan"; + case 33: + return "Chongqing"; + default: + return NULL; + } +} + +static const char *get_region_name_CO(int region_code) { + switch (region_code) { + case 1: + return "Amazonas"; + case 2: + return "Antioquia"; + case 3: + return "Arauca"; + case 4: + return "Atlantico"; + case 8: + return "Caqueta"; + case 9: + return "Cauca"; + case 10: + return "Cesar"; + case 11: + return "Choco"; + case 12: + return "Cordoba"; + case 14: + return "Guaviare"; + case 15: + return "Guainia"; + case 16: + return "Huila"; + case 17: + return "La Guajira"; + case 19: + return "Meta"; + case 20: + return "Narino"; + case 21: + return "Norte de Santander"; + case 22: + return "Putumayo"; + case 23: + return "Quindio"; + case 24: + return "Risaralda"; + case 25: + return "San Andres y Providencia"; + case 26: + return "Santander"; + case 27: + return "Sucre"; + case 28: + return "Tolima"; + case 29: + return "Valle del Cauca"; + case 30: + return "Vaupes"; + case 31: + return "Vichada"; + case 32: + return "Casanare"; + case 33: + return "Cundinamarca"; + case 34: + return "Distrito Especial"; + case 35: + return "Bolivar"; + case 36: + return "Boyaca"; + case 37: + return "Caldas"; + case 38: + return "Magdalena"; + default: + return NULL; + } +} + +static const char *get_region_name_CR(int region_code) { + switch (region_code) { + case 1: + return "Alajuela"; + case 2: + return "Cartago"; + case 3: + return "Guanacaste"; + case 4: + return "Heredia"; + case 6: + return "Limon"; + case 7: + return "Puntarenas"; + case 8: + return "San Jose"; + default: + return NULL; + } +} + +static const char *get_region_name_CU(int region_code) { + switch (region_code) { + case 1: + return "Pinar del Rio"; + case 2: + return "Ciudad de la Habana"; + case 3: + return "Matanzas"; + case 4: + return "Isla de la Juventud"; + case 5: + return "Camaguey"; + case 7: + return "Ciego de Avila"; + case 8: + return "Cienfuegos"; + case 9: + return "Granma"; + case 10: + return "Guantanamo"; + case 11: + return "La Habana"; + case 12: + return "Holguin"; + case 13: + return "Las Tunas"; + case 14: + return "Sancti Spiritus"; + case 15: + return "Santiago de Cuba"; + case 16: + return "Villa Clara"; + default: + return NULL; + } +} + +static const char *get_region_name_CV(int region_code) { + switch (region_code) { + case 1: + return "Boa Vista"; + case 2: + return "Brava"; + case 4: + return "Maio"; + case 5: + return "Paul"; + case 7: + return "Ribeira Grande"; + case 8: + return "Sal"; + case 10: + return "Sao Nicolau"; + case 11: + return "Sao Vicente"; + case 13: + return "Mosteiros"; + case 14: + return "Praia"; + case 15: + return "Santa Catarina"; + case 16: + return "Santa Cruz"; + case 17: + return "Sao Domingos"; + case 18: + return "Sao Filipe"; + case 19: + return "Sao Miguel"; + case 20: + return "Tarrafal"; + default: + return NULL; + } +} + +static const char *get_region_name_CY(int region_code) { + switch (region_code) { + case 1: + return "Famagusta"; + case 2: + return "Kyrenia"; + case 3: + return "Larnaca"; + case 4: + return "Nicosia"; + case 5: + return "Limassol"; + case 6: + return "Paphos"; + default: + return NULL; + } +} + +static const char *get_region_name_CZ(int region_code) { + switch (region_code) { + case 52: + return "Hlavni mesto Praha"; + case 78: + return "Jihomoravsky kraj"; + case 79: + return "Jihocesky kraj"; + case 80: + return "Vysocina"; + case 81: + return "Karlovarsky kraj"; + case 82: + return "Kralovehradecky kraj"; + case 83: + return "Liberecky kraj"; + case 84: + return "Olomoucky kraj"; + case 85: + return "Moravskoslezsky kraj"; + case 86: + return "Pardubicky kraj"; + case 87: + return "Plzensky kraj"; + case 88: + return "Stredocesky kraj"; + case 89: + return "Ustecky kraj"; + case 90: + return "Zlinsky kraj"; + default: + return NULL; + } +} + +static const char *get_region_name_DE(int region_code) { + switch (region_code) { + case 1: + return "Baden-Wurttemberg"; + case 2: + return "Bayern"; + case 3: + return "Bremen"; + case 4: + return "Hamburg"; + case 5: + return "Hessen"; + case 6: + return "Niedersachsen"; + case 7: + return "Nordrhein-Westfalen"; + case 8: + return "Rheinland-Pfalz"; + case 9: + return "Saarland"; + case 10: + return "Schleswig-Holstein"; + case 11: + return "Brandenburg"; + case 12: + return "Mecklenburg-Vorpommern"; + case 13: + return "Sachsen"; + case 14: + return "Sachsen-Anhalt"; + case 15: + return "Thuringen"; + case 16: + return "Berlin"; + default: + return NULL; + } +} + +static const char *get_region_name_DJ(int region_code) { + switch (region_code) { + case 1: + return "Ali Sabieh"; + case 4: + return "Obock"; + case 5: + return "Tadjoura"; + case 6: + return "Dikhil"; + case 7: + return "Djibouti"; + case 8: + return "Arta"; + default: + return NULL; + } +} + +static const char *get_region_name_DK(int region_code) { + switch (region_code) { + case 17: + return "Hovedstaden"; + case 18: + return "Midtjylland"; + case 19: + return "Nordjylland"; + case 20: + return "Sjelland"; + case 21: + return "Syddanmark"; + default: + return NULL; + } +} + +static const char *get_region_name_DM(int region_code) { + switch (region_code) { + case 2: + return "Saint Andrew"; + case 3: + return "Saint David"; + case 4: + return "Saint George"; + case 5: + return "Saint John"; + case 6: + return "Saint Joseph"; + case 7: + return "Saint Luke"; + case 8: + return "Saint Mark"; + case 9: + return "Saint Patrick"; + case 10: + return "Saint Paul"; + case 11: + return "Saint Peter"; + default: + return NULL; + } +} + +static const char *get_region_name_DO(int region_code) { + switch (region_code) { + case 1: + return "Azua"; + case 2: + return "Baoruco"; + case 3: + return "Barahona"; + case 4: + return "Dajabon"; + case 5: + return "Distrito Nacional"; + case 6: + return "Duarte"; + case 8: + return "Espaillat"; + case 9: + return "Independencia"; + case 10: + return "La Altagracia"; + case 11: + return "Elias Pina"; + case 12: + return "La Romana"; + case 14: + return "Maria Trinidad Sanchez"; + case 15: + return "Monte Cristi"; + case 16: + return "Pedernales"; + case 17: + return "Peravia"; + case 18: + return "Puerto Plata"; + case 19: + return "Salcedo"; + case 20: + return "Samana"; + case 21: + return "Sanchez Ramirez"; + case 23: + return "San Juan"; + case 24: + return "San Pedro De Macoris"; + case 25: + return "Santiago"; + case 26: + return "Santiago Rodriguez"; + case 27: + return "Valverde"; + case 28: + return "El Seibo"; + case 29: + return "Hato Mayor"; + case 30: + return "La Vega"; + case 31: + return "Monsenor Nouel"; + case 32: + return "Monte Plata"; + case 33: + return "San Cristobal"; + case 34: + return "Distrito Nacional"; + case 35: + return "Peravia"; + case 36: + return "San Jose de Ocoa"; + case 37: + return "Santo Domingo"; + default: + return NULL; + } +} + +static const char *get_region_name_DZ(int region_code) { + switch (region_code) { + case 1: + return "Alger"; + case 3: + return "Batna"; + case 4: + return "Constantine"; + case 6: + return "Medea"; + case 7: + return "Mostaganem"; + case 9: + return "Oran"; + case 10: + return "Saida"; + case 12: + return "Setif"; + case 13: + return "Tiaret"; + case 14: + return "Tizi Ouzou"; + case 15: + return "Tlemcen"; + case 18: + return "Bejaia"; + case 19: + return "Biskra"; + case 20: + return "Blida"; + case 21: + return "Bouira"; + case 22: + return "Djelfa"; + case 23: + return "Guelma"; + case 24: + return "Jijel"; + case 25: + return "Laghouat"; + case 26: + return "Mascara"; + case 27: + return "M'sila"; + case 29: + return "Oum el Bouaghi"; + case 30: + return "Sidi Bel Abbes"; + case 31: + return "Skikda"; + case 33: + return "Tebessa"; + case 34: + return "Adrar"; + case 35: + return "Ain Defla"; + case 36: + return "Ain Temouchent"; + case 37: + return "Annaba"; + case 38: + return "Bechar"; + case 39: + return "Bordj Bou Arreridj"; + case 40: + return "Boumerdes"; + case 41: + return "Chlef"; + case 42: + return "El Bayadh"; + case 43: + return "El Oued"; + case 44: + return "El Tarf"; + case 45: + return "Ghardaia"; + case 46: + return "Illizi"; + case 47: + return "Khenchela"; + case 48: + return "Mila"; + case 49: + return "Naama"; + case 50: + return "Ouargla"; + case 51: + return "Relizane"; + case 52: + return "Souk Ahras"; + case 53: + return "Tamanghasset"; + case 54: + return "Tindouf"; + case 55: + return "Tipaza"; + case 56: + return "Tissemsilt"; + default: + return NULL; + } +} + +static const char *get_region_name_EC(int region_code) { + switch (region_code) { + case 1: + return "Galapagos"; + case 2: + return "Azuay"; + case 3: + return "Bolivar"; + case 4: + return "Canar"; + case 5: + return "Carchi"; + case 6: + return "Chimborazo"; + case 7: + return "Cotopaxi"; + case 8: + return "El Oro"; + case 9: + return "Esmeraldas"; + case 10: + return "Guayas"; + case 11: + return "Imbabura"; + case 12: + return "Loja"; + case 13: + return "Los Rios"; + case 14: + return "Manabi"; + case 15: + return "Morona-Santiago"; + case 17: + return "Pastaza"; + case 18: + return "Pichincha"; + case 19: + return "Tungurahua"; + case 20: + return "Zamora-Chinchipe"; + case 22: + return "Sucumbios"; + case 23: + return "Napo"; + case 24: + return "Orellana"; + default: + return NULL; + } +} + +static const char *get_region_name_EE(int region_code) { + switch (region_code) { + case 1: + return "Harjumaa"; + case 2: + return "Hiiumaa"; + case 3: + return "Ida-Virumaa"; + case 4: + return "Jarvamaa"; + case 5: + return "Jogevamaa"; + case 6: + return "Kohtla-Jarve"; + case 7: + return "Laanemaa"; + case 8: + return "Laane-Virumaa"; + case 9: + return "Narva"; + case 10: + return "Parnu"; + case 11: + return "Parnumaa"; + case 12: + return "Polvamaa"; + case 13: + return "Raplamaa"; + case 14: + return "Saaremaa"; + case 15: + return "Sillamae"; + case 16: + return "Tallinn"; + case 17: + return "Tartu"; + case 18: + return "Tartumaa"; + case 19: + return "Valgamaa"; + case 20: + return "Viljandimaa"; + case 21: + return "Vorumaa"; + default: + return NULL; + } +} + +static const char *get_region_name_EG(int region_code) { + switch (region_code) { + case 1: + return "Ad Daqahliyah"; + case 2: + return "Al Bahr al Ahmar"; + case 3: + return "Al Buhayrah"; + case 4: + return "Al Fayyum"; + case 5: + return "Al Gharbiyah"; + case 6: + return "Al Iskandariyah"; + case 7: + return "Al Isma'iliyah"; + case 8: + return "Al Jizah"; + case 9: + return "Al Minufiyah"; + case 10: + return "Al Minya"; + case 11: + return "Al Qahirah"; + case 12: + return "Al Qalyubiyah"; + case 13: + return "Al Wadi al Jadid"; + case 14: + return "Ash Sharqiyah"; + case 15: + return "As Suways"; + case 16: + return "Aswan"; + case 17: + return "Asyut"; + case 18: + return "Bani Suwayf"; + case 19: + return "Bur Sa'id"; + case 20: + return "Dumyat"; + case 21: + return "Kafr ash Shaykh"; + case 22: + return "Matruh"; + case 23: + return "Qina"; + case 24: + return "Suhaj"; + case 26: + return "Janub Sina'"; + case 27: + return "Shamal Sina'"; + case 28: + return "Al Uqsur"; + default: + return NULL; + } +} + +static const char *get_region_name_ER(int region_code) { + switch (region_code) { + case 1: + return "Anseba"; + case 2: + return "Debub"; + case 3: + return "Debubawi K'eyih Bahri"; + case 4: + return "Gash Barka"; + case 5: + return "Ma'akel"; + case 6: + return "Semenawi K'eyih Bahri"; + default: + return NULL; + } +} + +static const char *get_region_name_ES(int region_code) { + switch (region_code) { + case 7: + return "Islas Baleares"; + case 27: + return "La Rioja"; + case 29: + return "Madrid"; + case 31: + return "Murcia"; + case 32: + return "Navarra"; + case 34: + return "Asturias"; + case 39: + return "Cantabria"; + case 51: + return "Andalucia"; + case 52: + return "Aragon"; + case 53: + return "Canarias"; + case 54: + return "Castilla-La Mancha"; + case 55: + return "Castilla y Leon"; + case 56: + return "Catalonia"; + case 57: + return "Extremadura"; + case 58: + return "Galicia"; + case 59: + return "Pais Vasco"; + case 60: + return "Comunidad Valenciana"; + default: + return NULL; + } +} + +static const char *get_region_name_ET(int region_code) { + switch (region_code) { + case 44: + return "Adis Abeba"; + case 45: + return "Afar"; + case 46: + return "Amara"; + case 47: + return "Binshangul Gumuz"; + case 48: + return "Dire Dawa"; + case 49: + return "Gambela Hizboch"; + case 50: + return "Hareri Hizb"; + case 51: + return "Oromiya"; + case 52: + return "Sumale"; + case 53: + return "Tigray"; + case 54: + return "YeDebub Biheroch Bihereseboch na Hizboch"; + default: + return NULL; + } +} + +static const char *get_region_name_FI(int region_code) { + switch (region_code) { + case 1: + return "Aland"; + case 6: + return "Lapland"; + case 8: + return "Oulu"; + case 13: + return "Southern Finland"; + case 14: + return "Eastern Finland"; + case 15: + return "Western Finland"; + default: + return NULL; + } +} + +static const char *get_region_name_FJ(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 2: + return "Eastern"; + case 3: + return "Northern"; + case 4: + return "Rotuma"; + case 5: + return "Western"; + default: + return NULL; + } +} + +static const char *get_region_name_FM(int region_code) { + switch (region_code) { + case 1: + return "Kosrae"; + case 2: + return "Pohnpei"; + case 3: + return "Chuuk"; + case 4: + return "Yap"; + default: + return NULL; + } +} + +static const char *get_region_name_FR(int region_code) { + switch (region_code) { + case 97: + return "Aquitaine"; + case 98: + return "Auvergne"; + case 99: + return "Basse-Normandie"; + case 832: + return "Bourgogne"; + case 833: + return "Bretagne"; + case 834: + return "Centre"; + case 835: + return "Champagne-Ardenne"; + case 836: + return "Corse"; + case 837: + return "Franche-Comte"; + case 838: + return "Haute-Normandie"; + case 839: + return "Ile-de-France"; + case 840: + return "Languedoc-Roussillon"; + case 875: + return "Limousin"; + case 876: + return "Lorraine"; + case 877: + return "Midi-Pyrenees"; + case 878: + return "Nord-Pas-de-Calais"; + case 879: + return "Pays de la Loire"; + case 880: + return "Picardie"; + case 881: + return "Poitou-Charentes"; + case 882: + return "Provence-Alpes-Cote d'Azur"; + case 883: + return "Rhone-Alpes"; + case 918: + return "Alsace"; + default: + return NULL; + } +} + +static const char *get_region_name_GA(int region_code) { + switch (region_code) { + case 1: + return "Estuaire"; + case 2: + return "Haut-Ogooue"; + case 3: + return "Moyen-Ogooue"; + case 4: + return "Ngounie"; + case 5: + return "Nyanga"; + case 6: + return "Ogooue-Ivindo"; + case 7: + return "Ogooue-Lolo"; + case 8: + return "Ogooue-Maritime"; + case 9: + return "Woleu-Ntem"; + default: + return NULL; + } +} + +static const char *get_region_name_GB(int region_code) { + switch (region_code) { + case 832: + return "Barking and Dagenham"; + case 833: + return "Barnet"; + case 834: + return "Barnsley"; + case 835: + return "Bath and North East Somerset"; + case 836: + return "Bedfordshire"; + case 837: + return "Bexley"; + case 838: + return "Birmingham"; + case 839: + return "Blackburn with Darwen"; + case 840: + return "Blackpool"; + case 875: + return "Bolton"; + case 876: + return "Bournemouth"; + case 877: + return "Bracknell Forest"; + case 878: + return "Bradford"; + case 879: + return "Brent"; + case 880: + return "Brighton and Hove"; + case 881: + return "Bristol, City of"; + case 882: + return "Bromley"; + case 883: + return "Buckinghamshire"; + case 918: + return "Bury"; + case 919: + return "Calderdale"; + case 920: + return "Cambridgeshire"; + case 921: + return "Camden"; + case 922: + return "Cheshire"; + case 923: + return "Cornwall"; + case 924: + return "Coventry"; + case 925: + return "Croydon"; + case 926: + return "Cumbria"; + case 961: + return "Darlington"; + case 962: + return "Derby"; + case 963: + return "Derbyshire"; + case 964: + return "Devon"; + case 965: + return "Doncaster"; + case 966: + return "Dorset"; + case 967: + return "Dudley"; + case 968: + return "Durham"; + case 969: + return "Ealing"; + case 1004: + return "East Riding of Yorkshire"; + case 1005: + return "East Sussex"; + case 1006: + return "Enfield"; + case 1007: + return "Essex"; + case 1008: + return "Gateshead"; + case 1009: + return "Gloucestershire"; + case 1010: + return "Greenwich"; + case 1011: + return "Hackney"; + case 1012: + return "Halton"; + case 1047: + return "Hammersmith and Fulham"; + case 1048: + return "Hampshire"; + case 1049: + return "Haringey"; + case 1050: + return "Harrow"; + case 1051: + return "Hartlepool"; + case 1052: + return "Havering"; + case 1053: + return "Herefordshire"; + case 1054: + return "Hertford"; + case 1055: + return "Hillingdon"; + case 1090: + return "Hounslow"; + case 1091: + return "Isle of Wight"; + case 1092: + return "Islington"; + case 1093: + return "Kensington and Chelsea"; + case 1094: + return "Kent"; + case 1095: + return "Kingston upon Hull, City of"; + case 1096: + return "Kingston upon Thames"; + case 1097: + return "Kirklees"; + case 1098: + return "Knowsley"; + case 1133: + return "Lambeth"; + case 1134: + return "Lancashire"; + case 1135: + return "Leeds"; + case 1136: + return "Leicester"; + case 1137: + return "Leicestershire"; + case 1138: + return "Lewisham"; + case 1139: + return "Lincolnshire"; + case 1140: + return "Liverpool"; + case 1141: + return "London, City of"; + case 1176: + return "Luton"; + case 1177: + return "Manchester"; + case 1178: + return "Medway"; + case 1179: + return "Merton"; + case 1180: + return "Middlesbrough"; + case 1181: + return "Milton Keynes"; + case 1182: + return "Newcastle upon Tyne"; + case 1183: + return "Newham"; + case 1184: + return "Norfolk"; + case 1219: + return "Northamptonshire"; + case 1220: + return "North East Lincolnshire"; + case 1221: + return "North Lincolnshire"; + case 1222: + return "North Somerset"; + case 1223: + return "North Tyneside"; + case 1224: + return "Northumberland"; + case 1225: + return "North Yorkshire"; + case 1226: + return "Nottingham"; + case 1227: + return "Nottinghamshire"; + case 1262: + return "Oldham"; + case 1263: + return "Oxfordshire"; + case 1264: + return "Peterborough"; + case 1265: + return "Plymouth"; + case 1266: + return "Poole"; + case 1267: + return "Portsmouth"; + case 1268: + return "Reading"; + case 1269: + return "Redbridge"; + case 1270: + return "Redcar and Cleveland"; + case 1305: + return "Richmond upon Thames"; + case 1306: + return "Rochdale"; + case 1307: + return "Rotherham"; + case 1308: + return "Rutland"; + case 1309: + return "Salford"; + case 1310: + return "Shropshire"; + case 1311: + return "Sandwell"; + case 1312: + return "Sefton"; + case 1313: + return "Sheffield"; + case 1348: + return "Slough"; + case 1349: + return "Solihull"; + case 1350: + return "Somerset"; + case 1351: + return "Southampton"; + case 1352: + return "Southend-on-Sea"; + case 1353: + return "South Gloucestershire"; + case 1354: + return "South Tyneside"; + case 1355: + return "Southwark"; + case 1356: + return "Staffordshire"; + case 1391: + return "St. Helens"; + case 1392: + return "Stockport"; + case 1393: + return "Stockton-on-Tees"; + case 1394: + return "Stoke-on-Trent"; + case 1395: + return "Suffolk"; + case 1396: + return "Sunderland"; + case 1397: + return "Surrey"; + case 1398: + return "Sutton"; + case 1399: + return "Swindon"; + case 1434: + return "Tameside"; + case 1435: + return "Telford and Wrekin"; + case 1436: + return "Thurrock"; + case 1437: + return "Torbay"; + case 1438: + return "Tower Hamlets"; + case 1439: + return "Trafford"; + case 1440: + return "Wakefield"; + case 1441: + return "Walsall"; + case 1442: + return "Waltham Forest"; + case 1477: + return "Wandsworth"; + case 1478: + return "Warrington"; + case 1479: + return "Warwickshire"; + case 1480: + return "West Berkshire"; + case 1481: + return "Westminster"; + case 1482: + return "West Sussex"; + case 1483: + return "Wigan"; + case 1484: + return "Wiltshire"; + case 1485: + return "Windsor and Maidenhead"; + case 1520: + return "Wirral"; + case 1521: + return "Wokingham"; + case 1522: + return "Wolverhampton"; + case 1523: + return "Worcestershire"; + case 1524: + return "York"; + case 1525: + return "Antrim"; + case 1526: + return "Ards"; + case 1527: + return "Armagh"; + case 1528: + return "Ballymena"; + case 1563: + return "Ballymoney"; + case 1564: + return "Banbridge"; + case 1565: + return "Belfast"; + case 1566: + return "Carrickfergus"; + case 1567: + return "Castlereagh"; + case 1568: + return "Coleraine"; + case 1569: + return "Cookstown"; + case 1570: + return "Craigavon"; + case 1571: + return "Down"; + case 1606: + return "Dungannon"; + case 1607: + return "Fermanagh"; + case 1608: + return "Larne"; + case 1609: + return "Limavady"; + case 1610: + return "Lisburn"; + case 1611: + return "Derry"; + case 1612: + return "Magherafelt"; + case 1613: + return "Moyle"; + case 1614: + return "Newry and Mourne"; + case 1649: + return "Newtownabbey"; + case 1650: + return "North Down"; + case 1651: + return "Omagh"; + case 1652: + return "Strabane"; + case 1653: + return "Aberdeen City"; + case 1654: + return "Aberdeenshire"; + case 1655: + return "Angus"; + case 1656: + return "Argyll and Bute"; + case 1657: + return "Scottish Borders, The"; + case 1692: + return "Clackmannanshire"; + case 1693: + return "Dumfries and Galloway"; + case 1694: + return "Dundee City"; + case 1695: + return "East Ayrshire"; + case 1696: + return "East Dunbartonshire"; + case 1697: + return "East Lothian"; + case 1698: + return "East Renfrewshire"; + case 1699: + return "Edinburgh, City of"; + case 1700: + return "Falkirk"; + case 1735: + return "Fife"; + case 1736: + return "Glasgow City"; + case 1737: + return "Highland"; + case 1738: + return "Inverclyde"; + case 1739: + return "Midlothian"; + case 1740: + return "Moray"; + case 1741: + return "North Ayrshire"; + case 1742: + return "North Lanarkshire"; + case 1743: + return "Orkney"; + case 1778: + return "Perth and Kinross"; + case 1779: + return "Renfrewshire"; + case 1780: + return "Shetland Islands"; + case 1781: + return "South Ayrshire"; + case 1782: + return "South Lanarkshire"; + case 1783: + return "Stirling"; + case 1784: + return "West Dunbartonshire"; + case 1785: + return "Eilean Siar"; + case 1786: + return "West Lothian"; + case 1821: + return "Isle of Anglesey"; + case 1822: + return "Blaenau Gwent"; + case 1823: + return "Bridgend"; + case 1824: + return "Caerphilly"; + case 1825: + return "Cardiff"; + case 1826: + return "Ceredigion"; + case 1827: + return "Carmarthenshire"; + case 1828: + return "Conwy"; + case 1829: + return "Denbighshire"; + case 1864: + return "Flintshire"; + case 1865: + return "Gwynedd"; + case 1866: + return "Merthyr Tydfil"; + case 1867: + return "Monmouthshire"; + case 1868: + return "Neath Port Talbot"; + case 1869: + return "Newport"; + case 1870: + return "Pembrokeshire"; + case 1871: + return "Powys"; + case 1872: + return "Rhondda Cynon Taff"; + case 1907: + return "Swansea"; + case 1908: + return "Torfaen"; + case 1909: + return "Vale of Glamorgan, The"; + case 1910: + return "Wrexham"; + case 1911: + return "Bedfordshire"; + case 1912: + return "Central Bedfordshire"; + case 1913: + return "Cheshire East"; + case 1914: + return "Cheshire West and Chester"; + case 1915: + return "Isles of Scilly"; + default: + return NULL; + } +} + +static const char *get_region_name_GD(int region_code) { + switch (region_code) { + case 1: + return "Saint Andrew"; + case 2: + return "Saint David"; + case 3: + return "Saint George"; + case 4: + return "Saint John"; + case 5: + return "Saint Mark"; + case 6: + return "Saint Patrick"; + default: + return NULL; + } +} + +static const char *get_region_name_GE(int region_code) { + switch (region_code) { + case 1: + return "Abashis Raioni"; + case 2: + return "Abkhazia"; + case 3: + return "Adigenis Raioni"; + case 4: + return "Ajaria"; + case 5: + return "Akhalgoris Raioni"; + case 6: + return "Akhalk'alak'is Raioni"; + case 7: + return "Akhalts'ikhis Raioni"; + case 8: + return "Akhmetis Raioni"; + case 9: + return "Ambrolauris Raioni"; + case 10: + return "Aspindzis Raioni"; + case 11: + return "Baghdat'is Raioni"; + case 12: + return "Bolnisis Raioni"; + case 13: + return "Borjomis Raioni"; + case 14: + return "Chiat'ura"; + case 15: + return "Ch'khorotsqus Raioni"; + case 16: + return "Ch'okhatauris Raioni"; + case 17: + return "Dedop'listsqaros Raioni"; + case 18: + return "Dmanisis Raioni"; + case 19: + return "Dushet'is Raioni"; + case 20: + return "Gardabanis Raioni"; + case 21: + return "Gori"; + case 22: + return "Goris Raioni"; + case 23: + return "Gurjaanis Raioni"; + case 24: + return "Javis Raioni"; + case 25: + return "K'arelis Raioni"; + case 26: + return "Kaspis Raioni"; + case 27: + return "Kharagaulis Raioni"; + case 28: + return "Khashuris Raioni"; + case 29: + return "Khobis Raioni"; + case 30: + return "Khonis Raioni"; + case 31: + return "K'ut'aisi"; + case 32: + return "Lagodekhis Raioni"; + case 33: + return "Lanch'khut'is Raioni"; + case 34: + return "Lentekhis Raioni"; + case 35: + return "Marneulis Raioni"; + case 36: + return "Martvilis Raioni"; + case 37: + return "Mestiis Raioni"; + case 38: + return "Mts'khet'is Raioni"; + case 39: + return "Ninotsmindis Raioni"; + case 40: + return "Onis Raioni"; + case 41: + return "Ozurget'is Raioni"; + case 42: + return "P'ot'i"; + case 43: + return "Qazbegis Raioni"; + case 44: + return "Qvarlis Raioni"; + case 45: + return "Rust'avi"; + case 46: + return "Sach'kheris Raioni"; + case 47: + return "Sagarejos Raioni"; + case 48: + return "Samtrediis Raioni"; + case 49: + return "Senakis Raioni"; + case 50: + return "Sighnaghis Raioni"; + case 51: + return "T'bilisi"; + case 52: + return "T'elavis Raioni"; + case 53: + return "T'erjolis Raioni"; + case 54: + return "T'et'ritsqaros Raioni"; + case 55: + return "T'ianet'is Raioni"; + case 56: + return "Tqibuli"; + case 57: + return "Ts'ageris Raioni"; + case 58: + return "Tsalenjikhis Raioni"; + case 59: + return "Tsalkis Raioni"; + case 60: + return "Tsqaltubo"; + case 61: + return "Vanis Raioni"; + case 62: + return "Zestap'onis Raioni"; + case 63: + return "Zugdidi"; + case 64: + return "Zugdidis Raioni"; + default: + return NULL; + } +} + +static const char *get_region_name_GH(int region_code) { + switch (region_code) { + case 1: + return "Greater Accra"; + case 2: + return "Ashanti"; + case 3: + return "Brong-Ahafo"; + case 4: + return "Central"; + case 5: + return "Eastern"; + case 6: + return "Northern"; + case 8: + return "Volta"; + case 9: + return "Western"; + case 10: + return "Upper East"; + case 11: + return "Upper West"; + default: + return NULL; + } +} + +static const char *get_region_name_GL(int region_code) { + switch (region_code) { + case 1: + return "Nordgronland"; + case 2: + return "Ostgronland"; + case 3: + return "Vestgronland"; + default: + return NULL; + } +} + +static const char *get_region_name_GM(int region_code) { + switch (region_code) { + case 1: + return "Banjul"; + case 2: + return "Lower River"; + case 3: + return "Central River"; + case 4: + return "Upper River"; + case 5: + return "Western"; + case 7: + return "North Bank"; + default: + return NULL; + } +} + +static const char *get_region_name_GN(int region_code) { + switch (region_code) { + case 1: + return "Beyla"; + case 2: + return "Boffa"; + case 3: + return "Boke"; + case 4: + return "Conakry"; + case 5: + return "Dabola"; + case 6: + return "Dalaba"; + case 7: + return "Dinguiraye"; + case 9: + return "Faranah"; + case 10: + return "Forecariah"; + case 11: + return "Fria"; + case 12: + return "Gaoual"; + case 13: + return "Gueckedou"; + case 15: + return "Kerouane"; + case 16: + return "Kindia"; + case 17: + return "Kissidougou"; + case 18: + return "Koundara"; + case 19: + return "Kouroussa"; + case 21: + return "Macenta"; + case 22: + return "Mali"; + case 23: + return "Mamou"; + case 25: + return "Pita"; + case 27: + return "Telimele"; + case 28: + return "Tougue"; + case 29: + return "Yomou"; + case 30: + return "Coyah"; + case 31: + return "Dubreka"; + case 32: + return "Kankan"; + case 33: + return "Koubia"; + case 34: + return "Labe"; + case 35: + return "Lelouma"; + case 36: + return "Lola"; + case 37: + return "Mandiana"; + case 38: + return "Nzerekore"; + case 39: + return "Siguiri"; + default: + return NULL; + } +} + +static const char *get_region_name_GQ(int region_code) { + switch (region_code) { + case 3: + return "Annobon"; + case 4: + return "Bioko Norte"; + case 5: + return "Bioko Sur"; + case 6: + return "Centro Sur"; + case 7: + return "Kie-Ntem"; + case 8: + return "Litoral"; + case 9: + return "Wele-Nzas"; + default: + return NULL; + } +} + +static const char *get_region_name_GR(int region_code) { + switch (region_code) { + case 1: + return "Evros"; + case 2: + return "Rodhopi"; + case 3: + return "Xanthi"; + case 4: + return "Drama"; + case 5: + return "Serrai"; + case 6: + return "Kilkis"; + case 7: + return "Pella"; + case 8: + return "Florina"; + case 9: + return "Kastoria"; + case 10: + return "Grevena"; + case 11: + return "Kozani"; + case 12: + return "Imathia"; + case 13: + return "Thessaloniki"; + case 14: + return "Kavala"; + case 15: + return "Khalkidhiki"; + case 16: + return "Pieria"; + case 17: + return "Ioannina"; + case 18: + return "Thesprotia"; + case 19: + return "Preveza"; + case 20: + return "Arta"; + case 21: + return "Larisa"; + case 22: + return "Trikala"; + case 23: + return "Kardhitsa"; + case 24: + return "Magnisia"; + case 25: + return "Kerkira"; + case 26: + return "Levkas"; + case 27: + return "Kefallinia"; + case 28: + return "Zakinthos"; + case 29: + return "Fthiotis"; + case 30: + return "Evritania"; + case 31: + return "Aitolia kai Akarnania"; + case 32: + return "Fokis"; + case 33: + return "Voiotia"; + case 34: + return "Evvoia"; + case 35: + return "Attiki"; + case 36: + return "Argolis"; + case 37: + return "Korinthia"; + case 38: + return "Akhaia"; + case 39: + return "Ilia"; + case 40: + return "Messinia"; + case 41: + return "Arkadhia"; + case 42: + return "Lakonia"; + case 43: + return "Khania"; + case 44: + return "Rethimni"; + case 45: + return "Iraklion"; + case 46: + return "Lasithi"; + case 47: + return "Dhodhekanisos"; + case 48: + return "Samos"; + case 49: + return "Kikladhes"; + case 50: + return "Khios"; + case 51: + return "Lesvos"; + default: + return NULL; + } +} + +static const char *get_region_name_GT(int region_code) { + switch (region_code) { + case 1: + return "Alta Verapaz"; + case 2: + return "Baja Verapaz"; + case 3: + return "Chimaltenango"; + case 4: + return "Chiquimula"; + case 5: + return "El Progreso"; + case 6: + return "Escuintla"; + case 7: + return "Guatemala"; + case 8: + return "Huehuetenango"; + case 9: + return "Izabal"; + case 10: + return "Jalapa"; + case 11: + return "Jutiapa"; + case 12: + return "Peten"; + case 13: + return "Quetzaltenango"; + case 14: + return "Quiche"; + case 15: + return "Retalhuleu"; + case 16: + return "Sacatepequez"; + case 17: + return "San Marcos"; + case 18: + return "Santa Rosa"; + case 19: + return "Solola"; + case 20: + return "Suchitepequez"; + case 21: + return "Totonicapan"; + case 22: + return "Zacapa"; + default: + return NULL; + } +} + +static const char *get_region_name_GW(int region_code) { + switch (region_code) { + case 1: + return "Bafata"; + case 2: + return "Quinara"; + case 4: + return "Oio"; + case 5: + return "Bolama"; + case 6: + return "Cacheu"; + case 7: + return "Tombali"; + case 10: + return "Gabu"; + case 11: + return "Bissau"; + case 12: + return "Biombo"; + default: + return NULL; + } +} + +static const char *get_region_name_GY(int region_code) { + switch (region_code) { + case 10: + return "Barima-Waini"; + case 11: + return "Cuyuni-Mazaruni"; + case 12: + return "Demerara-Mahaica"; + case 13: + return "East Berbice-Corentyne"; + case 14: + return "Essequibo Islands-West Demerara"; + case 15: + return "Mahaica-Berbice"; + case 16: + return "Pomeroon-Supenaam"; + case 17: + return "Potaro-Siparuni"; + case 18: + return "Upper Demerara-Berbice"; + case 19: + return "Upper Takutu-Upper Essequibo"; + default: + return NULL; + } +} + +static const char *get_region_name_HN(int region_code) { + switch (region_code) { + case 1: + return "Atlantida"; + case 2: + return "Choluteca"; + case 3: + return "Colon"; + case 4: + return "Comayagua"; + case 5: + return "Copan"; + case 6: + return "Cortes"; + case 7: + return "El Paraiso"; + case 8: + return "Francisco Morazan"; + case 9: + return "Gracias a Dios"; + case 10: + return "Intibuca"; + case 11: + return "Islas de la Bahia"; + case 12: + return "La Paz"; + case 13: + return "Lempira"; + case 14: + return "Ocotepeque"; + case 15: + return "Olancho"; + case 16: + return "Santa Barbara"; + case 17: + return "Valle"; + case 18: + return "Yoro"; + default: + return NULL; + } +} + +static const char *get_region_name_HR(int region_code) { + switch (region_code) { + case 1: + return "Bjelovarsko-Bilogorska"; + case 2: + return "Brodsko-Posavska"; + case 3: + return "Dubrovacko-Neretvanska"; + case 4: + return "Istarska"; + case 5: + return "Karlovacka"; + case 6: + return "Koprivnicko-Krizevacka"; + case 7: + return "Krapinsko-Zagorska"; + case 8: + return "Licko-Senjska"; + case 9: + return "Medimurska"; + case 10: + return "Osjecko-Baranjska"; + case 11: + return "Pozesko-Slavonska"; + case 12: + return "Primorsko-Goranska"; + case 13: + return "Sibensko-Kninska"; + case 14: + return "Sisacko-Moslavacka"; + case 15: + return "Splitsko-Dalmatinska"; + case 16: + return "Varazdinska"; + case 17: + return "Viroviticko-Podravska"; + case 18: + return "Vukovarsko-Srijemska"; + case 19: + return "Zadarska"; + case 20: + return "Zagrebacka"; + case 21: + return "Grad Zagreb"; + default: + return NULL; + } +} + +static const char *get_region_name_HT(int region_code) { + switch (region_code) { + case 3: + return "Nord-Ouest"; + case 6: + return "Artibonite"; + case 7: + return "Centre"; + case 9: + return "Nord"; + case 10: + return "Nord-Est"; + case 11: + return "Ouest"; + case 12: + return "Sud"; + case 13: + return "Sud-Est"; + case 14: + return "Grand' Anse"; + case 15: + return "Nippes"; + default: + return NULL; + } +} + +static const char *get_region_name_HU(int region_code) { + switch (region_code) { + case 1: + return "Bacs-Kiskun"; + case 2: + return "Baranya"; + case 3: + return "Bekes"; + case 4: + return "Borsod-Abauj-Zemplen"; + case 5: + return "Budapest"; + case 6: + return "Csongrad"; + case 7: + return "Debrecen"; + case 8: + return "Fejer"; + case 9: + return "Gyor-Moson-Sopron"; + case 10: + return "Hajdu-Bihar"; + case 11: + return "Heves"; + case 12: + return "Komarom-Esztergom"; + case 13: + return "Miskolc"; + case 14: + return "Nograd"; + case 15: + return "Pecs"; + case 16: + return "Pest"; + case 17: + return "Somogy"; + case 18: + return "Szabolcs-Szatmar-Bereg"; + case 19: + return "Szeged"; + case 20: + return "Jasz-Nagykun-Szolnok"; + case 21: + return "Tolna"; + case 22: + return "Vas"; + case 23: + return "Veszprem"; + case 24: + return "Zala"; + case 25: + return "Gyor"; + case 26: + return "Bekescsaba"; + case 27: + return "Dunaujvaros"; + case 28: + return "Eger"; + case 29: + return "Hodmezovasarhely"; + case 30: + return "Kaposvar"; + case 31: + return "Kecskemet"; + case 32: + return "Nagykanizsa"; + case 33: + return "Nyiregyhaza"; + case 34: + return "Sopron"; + case 35: + return "Szekesfehervar"; + case 36: + return "Szolnok"; + case 37: + return "Szombathely"; + case 38: + return "Tatabanya"; + case 39: + return "Veszprem"; + case 40: + return "Zalaegerszeg"; + case 41: + return "Salgotarjan"; + case 42: + return "Szekszard"; + case 43: + return "Erd"; + default: + return NULL; + } +} + +static const char *get_region_name_ID(int region_code) { + switch (region_code) { + case 1: + return "Aceh"; + case 2: + return "Bali"; + case 3: + return "Bengkulu"; + case 4: + return "Jakarta Raya"; + case 5: + return "Jambi"; + case 7: + return "Jawa Tengah"; + case 8: + return "Jawa Timur"; + case 10: + return "Yogyakarta"; + case 11: + return "Kalimantan Barat"; + case 12: + return "Kalimantan Selatan"; + case 13: + return "Kalimantan Tengah"; + case 14: + return "Kalimantan Timur"; + case 15: + return "Lampung"; + case 17: + return "Nusa Tenggara Barat"; + case 18: + return "Nusa Tenggara Timur"; + case 21: + return "Sulawesi Tengah"; + case 22: + return "Sulawesi Tenggara"; + case 24: + return "Sumatera Barat"; + case 26: + return "Sumatera Utara"; + case 28: + return "Maluku"; + case 29: + return "Maluku Utara"; + case 30: + return "Jawa Barat"; + case 31: + return "Sulawesi Utara"; + case 32: + return "Sumatera Selatan"; + case 33: + return "Banten"; + case 34: + return "Gorontalo"; + case 35: + return "Kepulauan Bangka Belitung"; + case 36: + return "Papua"; + case 37: + return "Riau"; + case 38: + return "Sulawesi Selatan"; + case 39: + return "Irian Jaya Barat"; + case 40: + return "Kepulauan Riau"; + case 41: + return "Sulawesi Barat"; + default: + return NULL; + } +} + +static const char *get_region_name_IE(int region_code) { + switch (region_code) { + case 1: + return "Carlow"; + case 2: + return "Cavan"; + case 3: + return "Clare"; + case 4: + return "Cork"; + case 6: + return "Donegal"; + case 7: + return "Dublin"; + case 10: + return "Galway"; + case 11: + return "Kerry"; + case 12: + return "Kildare"; + case 13: + return "Kilkenny"; + case 14: + return "Leitrim"; + case 15: + return "Laois"; + case 16: + return "Limerick"; + case 18: + return "Longford"; + case 19: + return "Louth"; + case 20: + return "Mayo"; + case 21: + return "Meath"; + case 22: + return "Monaghan"; + case 23: + return "Offaly"; + case 24: + return "Roscommon"; + case 25: + return "Sligo"; + case 26: + return "Tipperary"; + case 27: + return "Waterford"; + case 29: + return "Westmeath"; + case 30: + return "Wexford"; + case 31: + return "Wicklow"; + default: + return NULL; + } +} + +static const char *get_region_name_IL(int region_code) { + switch (region_code) { + case 1: + return "HaDarom"; + case 2: + return "HaMerkaz"; + case 3: + return "HaZafon"; + case 4: + return "Hefa"; + case 5: + return "Tel Aviv"; + case 6: + return "Yerushalayim"; + default: + return NULL; + } +} + +static const char *get_region_name_IN(int region_code) { + switch (region_code) { + case 1: + return "Andaman and Nicobar Islands"; + case 2: + return "Andhra Pradesh"; + case 3: + return "Assam"; + case 5: + return "Chandigarh"; + case 6: + return "Dadra and Nagar Haveli"; + case 7: + return "Delhi"; + case 9: + return "Gujarat"; + case 10: + return "Haryana"; + case 11: + return "Himachal Pradesh"; + case 12: + return "Jammu and Kashmir"; + case 13: + return "Kerala"; + case 14: + return "Lakshadweep"; + case 16: + return "Maharashtra"; + case 17: + return "Manipur"; + case 18: + return "Meghalaya"; + case 19: + return "Karnataka"; + case 20: + return "Nagaland"; + case 21: + return "Orissa"; + case 22: + return "Puducherry"; + case 23: + return "Punjab"; + case 24: + return "Rajasthan"; + case 25: + return "Tamil Nadu"; + case 26: + return "Tripura"; + case 28: + return "West Bengal"; + case 29: + return "Sikkim"; + case 30: + return "Arunachal Pradesh"; + case 31: + return "Mizoram"; + case 32: + return "Daman and Diu"; + case 33: + return "Goa"; + case 34: + return "Bihar"; + case 35: + return "Madhya Pradesh"; + case 36: + return "Uttar Pradesh"; + case 37: + return "Chhattisgarh"; + case 38: + return "Jharkhand"; + case 39: + return "Uttarakhand"; + default: + return NULL; + } +} + +static const char *get_region_name_IQ(int region_code) { + switch (region_code) { + case 1: + return "Al Anbar"; + case 2: + return "Al Basrah"; + case 3: + return "Al Muthanna"; + case 4: + return "Al Qadisiyah"; + case 5: + return "As Sulaymaniyah"; + case 6: + return "Babil"; + case 7: + return "Baghdad"; + case 8: + return "Dahuk"; + case 9: + return "Dhi Qar"; + case 10: + return "Diyala"; + case 11: + return "Arbil"; + case 12: + return "Karbala'"; + case 13: + return "At Ta'mim"; + case 14: + return "Maysan"; + case 15: + return "Ninawa"; + case 16: + return "Wasit"; + case 17: + return "An Najaf"; + case 18: + return "Salah ad Din"; + default: + return NULL; + } +} + +static const char *get_region_name_IR(int region_code) { + switch (region_code) { + case 1: + return "Azarbayjan-e Bakhtari"; + case 3: + return "Chahar Mahall va Bakhtiari"; + case 4: + return "Sistan va Baluchestan"; + case 5: + return "Kohkiluyeh va Buyer Ahmadi"; + case 7: + return "Fars"; + case 8: + return "Gilan"; + case 9: + return "Hamadan"; + case 10: + return "Ilam"; + case 11: + return "Hormozgan"; + case 12: + return "Kerman"; + case 13: + return "Bakhtaran"; + case 15: + return "Khuzestan"; + case 16: + return "Kordestan"; + case 17: + return "Mazandaran"; + case 18: + return "Semnan Province"; + case 19: + return "Markazi"; + case 21: + return "Zanjan"; + case 22: + return "Bushehr"; + case 23: + return "Lorestan"; + case 24: + return "Markazi"; + case 25: + return "Semnan"; + case 26: + return "Tehran"; + case 27: + return "Zanjan"; + case 28: + return "Esfahan"; + case 29: + return "Kerman"; + case 30: + return "Khorasan"; + case 31: + return "Yazd"; + case 32: + return "Ardabil"; + case 33: + return "East Azarbaijan"; + case 34: + return "Markazi"; + case 35: + return "Mazandaran"; + case 36: + return "Zanjan"; + case 37: + return "Golestan"; + case 38: + return "Qazvin"; + case 39: + return "Qom"; + case 40: + return "Yazd"; + case 41: + return "Khorasan-e Janubi"; + case 42: + return "Khorasan-e Razavi"; + case 43: + return "Khorasan-e Shemali"; + case 44: + return "Alborz"; + default: + return NULL; + } +} + +static const char *get_region_name_IS(int region_code) { + switch (region_code) { + case 3: + return "Arnessysla"; + case 5: + return "Austur-Hunavatnssysla"; + case 6: + return "Austur-Skaftafellssysla"; + case 7: + return "Borgarfjardarsysla"; + case 9: + return "Eyjafjardarsysla"; + case 10: + return "Gullbringusysla"; + case 15: + return "Kjosarsysla"; + case 17: + return "Myrasysla"; + case 20: + return "Nordur-Mulasysla"; + case 21: + return "Nordur-Tingeyjarsysla"; + case 23: + return "Rangarvallasysla"; + case 28: + return "Skagafjardarsysla"; + case 29: + return "Snafellsnes- og Hnappadalssysla"; + case 30: + return "Strandasysla"; + case 31: + return "Sudur-Mulasysla"; + case 32: + return "Sudur-Tingeyjarsysla"; + case 34: + return "Vestur-Bardastrandarsysla"; + case 35: + return "Vestur-Hunavatnssysla"; + case 36: + return "Vestur-Isafjardarsysla"; + case 37: + return "Vestur-Skaftafellssysla"; + case 38: + return "Austurland"; + case 39: + return "Hofuoborgarsvaoio"; + case 40: + return "Norourland Eystra"; + case 41: + return "Norourland Vestra"; + case 42: + return "Suourland"; + case 43: + return "Suournes"; + case 44: + return "Vestfiroir"; + case 45: + return "Vesturland"; + default: + return NULL; + } +} + +static const char *get_region_name_IT(int region_code) { + switch (region_code) { + case 1: + return "Abruzzi"; + case 2: + return "Basilicata"; + case 3: + return "Calabria"; + case 4: + return "Campania"; + case 5: + return "Emilia-Romagna"; + case 6: + return "Friuli-Venezia Giulia"; + case 7: + return "Lazio"; + case 8: + return "Liguria"; + case 9: + return "Lombardia"; + case 10: + return "Marche"; + case 11: + return "Molise"; + case 12: + return "Piemonte"; + case 13: + return "Puglia"; + case 14: + return "Sardegna"; + case 15: + return "Sicilia"; + case 16: + return "Toscana"; + case 17: + return "Trentino-Alto Adige"; + case 18: + return "Umbria"; + case 19: + return "Valle d'Aosta"; + case 20: + return "Veneto"; + default: + return NULL; + } +} + +static const char *get_region_name_JM(int region_code) { + switch (region_code) { + case 1: + return "Clarendon"; + case 2: + return "Hanover"; + case 4: + return "Manchester"; + case 7: + return "Portland"; + case 8: + return "Saint Andrew"; + case 9: + return "Saint Ann"; + case 10: + return "Saint Catherine"; + case 11: + return "Saint Elizabeth"; + case 12: + return "Saint James"; + case 13: + return "Saint Mary"; + case 14: + return "Saint Thomas"; + case 15: + return "Trelawny"; + case 16: + return "Westmoreland"; + case 17: + return "Kingston"; + default: + return NULL; + } +} + +static const char *get_region_name_JO(int region_code) { + switch (region_code) { + case 2: + return "Al Balqa'"; + case 9: + return "Al Karak"; + case 12: + return "At Tafilah"; + case 15: + return "Al Mafraq"; + case 16: + return "Amman"; + case 17: + return "Az Zaraqa"; + case 18: + return "Irbid"; + case 19: + return "Ma'an"; + case 20: + return "Ajlun"; + case 21: + return "Al Aqabah"; + case 22: + return "Jarash"; + case 23: + return "Madaba"; + default: + return NULL; + } +} + +static const char *get_region_name_JP(int region_code) { + switch (region_code) { + case 1: + return "Aichi"; + case 2: + return "Akita"; + case 3: + return "Aomori"; + case 4: + return "Chiba"; + case 5: + return "Ehime"; + case 6: + return "Fukui"; + case 7: + return "Fukuoka"; + case 8: + return "Fukushima"; + case 9: + return "Gifu"; + case 10: + return "Gumma"; + case 11: + return "Hiroshima"; + case 12: + return "Hokkaido"; + case 13: + return "Hyogo"; + case 14: + return "Ibaraki"; + case 15: + return "Ishikawa"; + case 16: + return "Iwate"; + case 17: + return "Kagawa"; + case 18: + return "Kagoshima"; + case 19: + return "Kanagawa"; + case 20: + return "Kochi"; + case 21: + return "Kumamoto"; + case 22: + return "Kyoto"; + case 23: + return "Mie"; + case 24: + return "Miyagi"; + case 25: + return "Miyazaki"; + case 26: + return "Nagano"; + case 27: + return "Nagasaki"; + case 28: + return "Nara"; + case 29: + return "Niigata"; + case 30: + return "Oita"; + case 31: + return "Okayama"; + case 32: + return "Osaka"; + case 33: + return "Saga"; + case 34: + return "Saitama"; + case 35: + return "Shiga"; + case 36: + return "Shimane"; + case 37: + return "Shizuoka"; + case 38: + return "Tochigi"; + case 39: + return "Tokushima"; + case 40: + return "Tokyo"; + case 41: + return "Tottori"; + case 42: + return "Toyama"; + case 43: + return "Wakayama"; + case 44: + return "Yamagata"; + case 45: + return "Yamaguchi"; + case 46: + return "Yamanashi"; + case 47: + return "Okinawa"; + default: + return NULL; + } +} + +static const char *get_region_name_KE(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 2: + return "Coast"; + case 3: + return "Eastern"; + case 5: + return "Nairobi Area"; + case 6: + return "North-Eastern"; + case 7: + return "Nyanza"; + case 8: + return "Rift Valley"; + case 9: + return "Western"; + default: + return NULL; + } +} + +static const char *get_region_name_KG(int region_code) { + switch (region_code) { + case 1: + return "Bishkek"; + case 2: + return "Chuy"; + case 3: + return "Jalal-Abad"; + case 4: + return "Naryn"; + case 5: + return "Osh"; + case 6: + return "Talas"; + case 7: + return "Ysyk-Kol"; + case 8: + return "Osh"; + case 9: + return "Batken"; + default: + return NULL; + } +} + +static const char *get_region_name_KH(int region_code) { + switch (region_code) { + case 1: + return "Batdambang"; + case 2: + return "Kampong Cham"; + case 3: + return "Kampong Chhnang"; + case 4: + return "Kampong Speu"; + case 5: + return "Kampong Thum"; + case 6: + return "Kampot"; + case 7: + return "Kandal"; + case 8: + return "Koh Kong"; + case 9: + return "Kracheh"; + case 10: + return "Mondulkiri"; + case 11: + return "Phnum Penh"; + case 12: + return "Pursat"; + case 13: + return "Preah Vihear"; + case 14: + return "Prey Veng"; + case 15: + return "Ratanakiri Kiri"; + case 16: + return "Siem Reap"; + case 17: + return "Stung Treng"; + case 18: + return "Svay Rieng"; + case 19: + return "Takeo"; + case 22: + return "Phnum Penh"; + case 23: + return "Ratanakiri"; + case 25: + return "Banteay Meanchey"; + case 28: + return "Preah Seihanu"; + case 29: + return "Batdambang"; + case 30: + return "Pailin"; + default: + return NULL; + } +} + +static const char *get_region_name_KI(int region_code) { + switch (region_code) { + case 1: + return "Gilbert Islands"; + case 2: + return "Line Islands"; + case 3: + return "Phoenix Islands"; + default: + return NULL; + } +} + +static const char *get_region_name_KM(int region_code) { + switch (region_code) { + case 1: + return "Anjouan"; + case 2: + return "Grande Comore"; + case 3: + return "Moheli"; + default: + return NULL; + } +} + +static const char *get_region_name_KN(int region_code) { + switch (region_code) { + case 1: + return "Christ Church Nichola Town"; + case 2: + return "Saint Anne Sandy Point"; + case 3: + return "Saint George Basseterre"; + case 4: + return "Saint George Gingerland"; + case 5: + return "Saint James Windward"; + case 6: + return "Saint John Capisterre"; + case 7: + return "Saint John Figtree"; + case 8: + return "Saint Mary Cayon"; + case 9: + return "Saint Paul Capisterre"; + case 10: + return "Saint Paul Charlestown"; + case 11: + return "Saint Peter Basseterre"; + case 12: + return "Saint Thomas Lowland"; + case 13: + return "Saint Thomas Middle Island"; + case 15: + return "Trinity Palmetto Point"; + default: + return NULL; + } +} + +static const char *get_region_name_KP(int region_code) { + switch (region_code) { + case 1: + return "Chagang-do"; + case 3: + return "Hamgyong-namdo"; + case 6: + return "Hwanghae-namdo"; + case 7: + return "Hwanghae-bukto"; + case 8: + return "Kaesong-si"; + case 9: + return "Kangwon-do"; + case 11: + return "P'yongan-bukto"; + case 12: + return "P'yongyang-si"; + case 13: + return "Yanggang-do"; + case 14: + return "Namp'o-si"; + case 15: + return "P'yongan-namdo"; + case 17: + return "Hamgyong-bukto"; + case 18: + return "Najin Sonbong-si"; + default: + return NULL; + } +} + +static const char *get_region_name_KR(int region_code) { + switch (region_code) { + case 1: + return "Cheju-do"; + case 3: + return "Cholla-bukto"; + case 5: + return "Ch'ungch'ong-bukto"; + case 6: + return "Kangwon-do"; + case 10: + return "Pusan-jikhalsi"; + case 11: + return "Seoul-t'ukpyolsi"; + case 12: + return "Inch'on-jikhalsi"; + case 13: + return "Kyonggi-do"; + case 14: + return "Kyongsang-bukto"; + case 15: + return "Taegu-jikhalsi"; + case 16: + return "Cholla-namdo"; + case 17: + return "Ch'ungch'ong-namdo"; + case 18: + return "Kwangju-jikhalsi"; + case 19: + return "Taejon-jikhalsi"; + case 20: + return "Kyongsang-namdo"; + case 21: + return "Ulsan-gwangyoksi"; + default: + return NULL; + } +} + +static const char *get_region_name_KW(int region_code) { + switch (region_code) { + case 1: + return "Al Ahmadi"; + case 2: + return "Al Kuwayt"; + case 5: + return "Al Jahra"; + case 7: + return "Al Farwaniyah"; + case 8: + return "Hawalli"; + case 9: + return "Mubarak al Kabir"; + default: + return NULL; + } +} + +static const char *get_region_name_KY(int region_code) { + switch (region_code) { + case 1: + return "Creek"; + case 2: + return "Eastern"; + case 3: + return "Midland"; + case 4: + return "South Town"; + case 5: + return "Spot Bay"; + case 6: + return "Stake Bay"; + case 7: + return "West End"; + case 8: + return "Western"; + default: + return NULL; + } +} + +static const char *get_region_name_KZ(int region_code) { + switch (region_code) { + case 1: + return "Almaty"; + case 2: + return "Almaty City"; + case 3: + return "Aqmola"; + case 4: + return "Aqtobe"; + case 5: + return "Astana"; + case 6: + return "Atyrau"; + case 7: + return "West Kazakhstan"; + case 8: + return "Bayqonyr"; + case 9: + return "Mangghystau"; + case 10: + return "South Kazakhstan"; + case 11: + return "Pavlodar"; + case 12: + return "Qaraghandy"; + case 13: + return "Qostanay"; + case 14: + return "Qyzylorda"; + case 15: + return "East Kazakhstan"; + case 16: + return "North Kazakhstan"; + case 17: + return "Zhambyl"; + default: + return NULL; + } +} + +static const char *get_region_name_LA(int region_code) { + switch (region_code) { + case 1: + return "Attapu"; + case 2: + return "Champasak"; + case 3: + return "Houaphan"; + case 4: + return "Khammouan"; + case 5: + return "Louang Namtha"; + case 7: + return "Oudomxai"; + case 8: + return "Phongsali"; + case 9: + return "Saravan"; + case 10: + return "Savannakhet"; + case 11: + return "Vientiane"; + case 13: + return "Xaignabouri"; + case 14: + return "Xiangkhoang"; + case 17: + return "Louangphrabang"; + default: + return NULL; + } +} + +static const char *get_region_name_LB(int region_code) { + switch (region_code) { + case 1: + return "Beqaa"; + case 2: + return "Al Janub"; + case 3: + return "Liban-Nord"; + case 4: + return "Beyrouth"; + case 5: + return "Mont-Liban"; + case 6: + return "Liban-Sud"; + case 7: + return "Nabatiye"; + case 8: + return "Beqaa"; + case 9: + return "Liban-Nord"; + case 10: + return "Aakk,r"; + case 11: + return "Baalbek-Hermel"; + default: + return NULL; + } +} + +static const char *get_region_name_LC(int region_code) { + switch (region_code) { + case 1: + return "Anse-la-Raye"; + case 2: + return "Dauphin"; + case 3: + return "Castries"; + case 4: + return "Choiseul"; + case 5: + return "Dennery"; + case 6: + return "Gros-Islet"; + case 7: + return "Laborie"; + case 8: + return "Micoud"; + case 9: + return "Soufriere"; + case 10: + return "Vieux-Fort"; + case 11: + return "Praslin"; + default: + return NULL; + } +} + +static const char *get_region_name_LI(int region_code) { + switch (region_code) { + case 1: + return "Balzers"; + case 2: + return "Eschen"; + case 3: + return "Gamprin"; + case 4: + return "Mauren"; + case 5: + return "Planken"; + case 6: + return "Ruggell"; + case 7: + return "Schaan"; + case 8: + return "Schellenberg"; + case 9: + return "Triesen"; + case 10: + return "Triesenberg"; + case 11: + return "Vaduz"; + case 21: + return "Gbarpolu"; + case 22: + return "River Gee"; + default: + return NULL; + } +} + +static const char *get_region_name_LK(int region_code) { + switch (region_code) { + case 29: + return "Central"; + case 30: + return "North Central"; + case 32: + return "North Western"; + case 33: + return "Sabaragamuwa"; + case 34: + return "Southern"; + case 35: + return "Uva"; + case 36: + return "Western"; + case 37: + return "Eastern"; + case 38: + return "Northern"; + default: + return NULL; + } +} + +static const char *get_region_name_LR(int region_code) { + switch (region_code) { + case 1: + return "Bong"; + case 4: + return "Grand Cape Mount"; + case 5: + return "Lofa"; + case 6: + return "Maryland"; + case 7: + return "Monrovia"; + case 9: + return "Nimba"; + case 10: + return "Sino"; + case 11: + return "Grand Bassa"; + case 12: + return "Grand Cape Mount"; + case 13: + return "Maryland"; + case 14: + return "Montserrado"; + case 17: + return "Margibi"; + case 18: + return "River Cess"; + case 19: + return "Grand Gedeh"; + case 20: + return "Lofa"; + case 21: + return "Gbarpolu"; + case 22: + return "River Gee"; + default: + return NULL; + } +} + +static const char *get_region_name_LS(int region_code) { + switch (region_code) { + case 10: + return "Berea"; + case 11: + return "Butha-Buthe"; + case 12: + return "Leribe"; + case 13: + return "Mafeteng"; + case 14: + return "Maseru"; + case 15: + return "Mohales Hoek"; + case 16: + return "Mokhotlong"; + case 17: + return "Qachas Nek"; + case 18: + return "Quthing"; + case 19: + return "Thaba-Tseka"; + default: + return NULL; + } +} + +static const char *get_region_name_LT(int region_code) { + switch (region_code) { + case 56: + return "Alytaus Apskritis"; + case 57: + return "Kauno Apskritis"; + case 58: + return "Klaipedos Apskritis"; + case 59: + return "Marijampoles Apskritis"; + case 60: + return "Panevezio Apskritis"; + case 61: + return "Siauliu Apskritis"; + case 62: + return "Taurages Apskritis"; + case 63: + return "Telsiu Apskritis"; + case 64: + return "Utenos Apskritis"; + case 65: + return "Vilniaus Apskritis"; + default: + return NULL; + } +} + +static const char *get_region_name_LU(int region_code) { + switch (region_code) { + case 1: + return "Diekirch"; + case 2: + return "Grevenmacher"; + case 3: + return "Luxembourg"; + default: + return NULL; + } +} + +static const char *get_region_name_LV(int region_code) { + switch (region_code) { + case 1: + return "Aizkraukles"; + case 2: + return "Aluksnes"; + case 3: + return "Balvu"; + case 4: + return "Bauskas"; + case 5: + return "Cesu"; + case 6: + return "Daugavpils"; + case 7: + return "Daugavpils"; + case 8: + return "Dobeles"; + case 9: + return "Gulbenes"; + case 10: + return "Jekabpils"; + case 11: + return "Jelgava"; + case 12: + return "Jelgavas"; + case 13: + return "Jurmala"; + case 14: + return "Kraslavas"; + case 15: + return "Kuldigas"; + case 16: + return "Liepaja"; + case 17: + return "Liepajas"; + case 18: + return "Limbazu"; + case 19: + return "Ludzas"; + case 20: + return "Madonas"; + case 21: + return "Ogres"; + case 22: + return "Preilu"; + case 23: + return "Rezekne"; + case 24: + return "Rezeknes"; + case 25: + return "Riga"; + case 26: + return "Rigas"; + case 27: + return "Saldus"; + case 28: + return "Talsu"; + case 29: + return "Tukuma"; + case 30: + return "Valkas"; + case 31: + return "Valmieras"; + case 32: + return "Ventspils"; + case 33: + return "Ventspils"; + default: + return NULL; + } +} + +static const char *get_region_name_LY(int region_code) { + switch (region_code) { + case 3: + return "Al Aziziyah"; + case 5: + return "Al Jufrah"; + case 8: + return "Al Kufrah"; + case 13: + return "Ash Shati'"; + case 30: + return "Murzuq"; + case 34: + return "Sabha"; + case 41: + return "Tarhunah"; + case 42: + return "Tubruq"; + case 45: + return "Zlitan"; + case 47: + return "Ajdabiya"; + case 48: + return "Al Fatih"; + case 49: + return "Al Jabal al Akhdar"; + case 50: + return "Al Khums"; + case 51: + return "An Nuqat al Khams"; + case 52: + return "Awbari"; + case 53: + return "Az Zawiyah"; + case 54: + return "Banghazi"; + case 55: + return "Darnah"; + case 56: + return "Ghadamis"; + case 57: + return "Gharyan"; + case 58: + return "Misratah"; + case 59: + return "Sawfajjin"; + case 60: + return "Surt"; + case 61: + return "Tarabulus"; + case 62: + return "Yafran"; + default: + return NULL; + } +} + +static const char *get_region_name_MA(int region_code) { + switch (region_code) { + case 45: + return "Grand Casablanca"; + case 46: + return "Fes-Boulemane"; + case 47: + return "Marrakech-Tensift-Al Haouz"; + case 48: + return "Meknes-Tafilalet"; + case 49: + return "Rabat-Sale-Zemmour-Zaer"; + case 50: + return "Chaouia-Ouardigha"; + case 51: + return "Doukkala-Abda"; + case 52: + return "Gharb-Chrarda-Beni Hssen"; + case 53: + return "Guelmim-Es Smara"; + case 54: + return "Oriental"; + case 55: + return "Souss-Massa-Dr,a"; + case 56: + return "Tadla-Azilal"; + case 57: + return "Tanger-Tetouan"; + case 58: + return "Taza-Al Hoceima-Taounate"; + case 59: + return "La,youne-Boujdour-Sakia El Hamra"; + default: + return NULL; + } +} + +static const char *get_region_name_MC(int region_code) { + switch (region_code) { + case 1: + return "La Condamine"; + case 2: + return "Monaco"; + case 3: + return "Monte-Carlo"; + default: + return NULL; + } +} + +static const char *get_region_name_MD(int region_code) { + switch (region_code) { + case 51: + return "Gagauzia"; + case 57: + return "Chisinau"; + case 58: + return "Stinga Nistrului"; + case 59: + return "Anenii Noi"; + case 60: + return "Balti"; + case 61: + return "Basarabeasca"; + case 62: + return "Bender"; + case 63: + return "Briceni"; + case 64: + return "Cahul"; + case 65: + return "Cantemir"; + case 66: + return "Calarasi"; + case 67: + return "Causeni"; + case 68: + return "Cimislia"; + case 69: + return "Criuleni"; + case 70: + return "Donduseni"; + case 71: + return "Drochia"; + case 72: + return "Dubasari"; + case 73: + return "Edinet"; + case 74: + return "Falesti"; + case 75: + return "Floresti"; + case 76: + return "Glodeni"; + case 77: + return "Hincesti"; + case 78: + return "Ialoveni"; + case 79: + return "Leova"; + case 80: + return "Nisporeni"; + case 81: + return "Ocnita"; + case 82: + return "Orhei"; + case 83: + return "Rezina"; + case 84: + return "Riscani"; + case 85: + return "Singerei"; + case 86: + return "Soldanesti"; + case 87: + return "Soroca"; + case 88: + return "Stefan-Voda"; + case 89: + return "Straseni"; + case 90: + return "Taraclia"; + case 91: + return "Telenesti"; + case 92: + return "Ungheni"; + default: + return NULL; + } +} + +static const char *get_region_name_MG(int region_code) { + switch (region_code) { + case 1: + return "Antsiranana"; + case 2: + return "Fianarantsoa"; + case 3: + return "Mahajanga"; + case 4: + return "Toamasina"; + case 5: + return "Antananarivo"; + case 6: + return "Toliara"; + default: + return NULL; + } +} + +static const char *get_region_name_MK(int region_code) { + switch (region_code) { + case 1: + return "Aracinovo"; + case 2: + return "Bac"; + case 3: + return "Belcista"; + case 4: + return "Berovo"; + case 5: + return "Bistrica"; + case 6: + return "Bitola"; + case 7: + return "Blatec"; + case 8: + return "Bogdanci"; + case 9: + return "Bogomila"; + case 10: + return "Bogovinje"; + case 11: + return "Bosilovo"; + case 12: + return "Brvenica"; + case 13: + return "Cair"; + case 14: + return "Capari"; + case 15: + return "Caska"; + case 16: + return "Cegrane"; + case 17: + return "Centar"; + case 18: + return "Centar Zupa"; + case 19: + return "Cesinovo"; + case 20: + return "Cucer-Sandevo"; + case 21: + return "Debar"; + case 22: + return "Delcevo"; + case 23: + return "Delogozdi"; + case 24: + return "Demir Hisar"; + case 25: + return "Demir Kapija"; + case 26: + return "Dobrusevo"; + case 27: + return "Dolna Banjica"; + case 28: + return "Dolneni"; + case 29: + return "Dorce Petrov"; + case 30: + return "Drugovo"; + case 31: + return "Dzepciste"; + case 32: + return "Gazi Baba"; + case 33: + return "Gevgelija"; + case 34: + return "Gostivar"; + case 35: + return "Gradsko"; + case 36: + return "Ilinden"; + case 37: + return "Izvor"; + case 38: + return "Jegunovce"; + case 39: + return "Kamenjane"; + case 40: + return "Karbinci"; + case 41: + return "Karpos"; + case 42: + return "Kavadarci"; + case 43: + return "Kicevo"; + case 44: + return "Kisela Voda"; + case 45: + return "Klecevce"; + case 46: + return "Kocani"; + case 47: + return "Konce"; + case 48: + return "Kondovo"; + case 49: + return "Konopiste"; + case 50: + return "Kosel"; + case 51: + return "Kratovo"; + case 52: + return "Kriva Palanka"; + case 53: + return "Krivogastani"; + case 54: + return "Krusevo"; + case 55: + return "Kuklis"; + case 56: + return "Kukurecani"; + case 57: + return "Kumanovo"; + case 58: + return "Labunista"; + case 59: + return "Lipkovo"; + case 60: + return "Lozovo"; + case 61: + return "Lukovo"; + case 62: + return "Makedonska Kamenica"; + case 63: + return "Makedonski Brod"; + case 64: + return "Mavrovi Anovi"; + case 65: + return "Meseista"; + case 66: + return "Miravci"; + case 67: + return "Mogila"; + case 68: + return "Murtino"; + case 69: + return "Negotino"; + case 70: + return "Negotino-Polosko"; + case 71: + return "Novaci"; + case 72: + return "Novo Selo"; + case 73: + return "Oblesevo"; + case 74: + return "Ohrid"; + case 75: + return "Orasac"; + case 76: + return "Orizari"; + case 77: + return "Oslomej"; + case 78: + return "Pehcevo"; + case 79: + return "Petrovec"; + case 80: + return "Plasnica"; + case 81: + return "Podares"; + case 82: + return "Prilep"; + case 83: + return "Probistip"; + case 84: + return "Radovis"; + case 85: + return "Rankovce"; + case 86: + return "Resen"; + case 87: + return "Rosoman"; + case 88: + return "Rostusa"; + case 89: + return "Samokov"; + case 90: + return "Saraj"; + case 91: + return "Sipkovica"; + case 92: + return "Sopiste"; + case 93: + return "Sopotnica"; + case 94: + return "Srbinovo"; + case 95: + return "Staravina"; + case 96: + return "Star Dojran"; + case 97: + return "Staro Nagoricane"; + case 98: + return "Stip"; + case 99: + return "Struga"; + case 832: + return "Strumica"; + case 833: + return "Studenicani"; + case 834: + return "Suto Orizari"; + case 835: + return "Sveti Nikole"; + case 836: + return "Tearce"; + case 837: + return "Tetovo"; + case 838: + return "Topolcani"; + case 839: + return "Valandovo"; + case 840: + return "Vasilevo"; + case 875: + return "Veles"; + case 876: + return "Velesta"; + case 877: + return "Vevcani"; + case 878: + return "Vinica"; + case 879: + return "Vitoliste"; + case 880: + return "Vranestica"; + case 881: + return "Vrapciste"; + case 882: + return "Vratnica"; + case 883: + return "Vrutok"; + case 918: + return "Zajas"; + case 919: + return "Zelenikovo"; + case 920: + return "Zelino"; + case 921: + return "Zitose"; + case 922: + return "Zletovo"; + case 923: + return "Zrnovci"; + case 925: + return "Cair"; + case 926: + return "Caska"; + case 962: + return "Debar"; + case 963: + return "Demir Hisar"; + case 964: + return "Gostivar"; + case 965: + return "Jegunovce"; + case 966: + return "Kavadarci"; + case 967: + return "Kumanovo"; + case 968: + return "Makedonski Brod"; + case 1005: + return "Ohrid"; + case 1006: + return "Prilep"; + case 1008: + return "Dojran"; + case 1009: + return "Struga"; + case 1010: + return "Strumica"; + case 1011: + return "Tetovo"; + case 1012: + return "Valandovo"; + case 1047: + return "Veles"; + case 1048: + return "Aerodrom"; + default: + return NULL; + } +} + +static const char *get_region_name_ML(int region_code) { + switch (region_code) { + case 1: + return "Bamako"; + case 3: + return "Kayes"; + case 4: + return "Mopti"; + case 5: + return "Segou"; + case 6: + return "Sikasso"; + case 7: + return "Koulikoro"; + case 8: + return "Tombouctou"; + case 9: + return "Gao"; + case 10: + return "Kidal"; + default: + return NULL; + } +} + +static const char *get_region_name_MM(int region_code) { + switch (region_code) { + case 1: + return "Rakhine State"; + case 2: + return "Chin State"; + case 3: + return "Irrawaddy"; + case 4: + return "Kachin State"; + case 5: + return "Karan State"; + case 6: + return "Kayah State"; + case 7: + return "Magwe"; + case 8: + return "Mandalay"; + case 9: + return "Pegu"; + case 10: + return "Sagaing"; + case 11: + return "Shan State"; + case 12: + return "Tenasserim"; + case 13: + return "Mon State"; + case 14: + return "Rangoon"; + case 17: + return "Yangon"; + default: + return NULL; + } +} + +static const char *get_region_name_MN(int region_code) { + switch (region_code) { + case 1: + return "Arhangay"; + case 2: + return "Bayanhongor"; + case 3: + return "Bayan-Olgiy"; + case 5: + return "Darhan"; + case 6: + return "Dornod"; + case 7: + return "Dornogovi"; + case 8: + return "Dundgovi"; + case 9: + return "Dzavhan"; + case 10: + return "Govi-Altay"; + case 11: + return "Hentiy"; + case 12: + return "Hovd"; + case 13: + return "Hovsgol"; + case 14: + return "Omnogovi"; + case 15: + return "Ovorhangay"; + case 16: + return "Selenge"; + case 17: + return "Suhbaatar"; + case 18: + return "Tov"; + case 19: + return "Uvs"; + case 20: + return "Ulaanbaatar"; + case 21: + return "Bulgan"; + case 22: + return "Erdenet"; + case 23: + return "Darhan-Uul"; + case 24: + return "Govisumber"; + case 25: + return "Orhon"; + default: + return NULL; + } +} + +static const char *get_region_name_MO(int region_code) { + switch (region_code) { + case 1: + return "Ilhas"; + case 2: + return "Macau"; + default: + return NULL; + } +} + +static const char *get_region_name_MR(int region_code) { + switch (region_code) { + case 1: + return "Hodh Ech Chargui"; + case 2: + return "Hodh El Gharbi"; + case 3: + return "Assaba"; + case 4: + return "Gorgol"; + case 5: + return "Brakna"; + case 6: + return "Trarza"; + case 7: + return "Adrar"; + case 8: + return "Dakhlet Nouadhibou"; + case 9: + return "Tagant"; + case 10: + return "Guidimaka"; + case 11: + return "Tiris Zemmour"; + case 12: + return "Inchiri"; + default: + return NULL; + } +} + +static const char *get_region_name_MS(int region_code) { + switch (region_code) { + case 1: + return "Saint Anthony"; + case 2: + return "Saint Georges"; + case 3: + return "Saint Peter"; + default: + return NULL; + } +} + +static const char *get_region_name_MU(int region_code) { + switch (region_code) { + case 12: + return "Black River"; + case 13: + return "Flacq"; + case 14: + return "Grand Port"; + case 15: + return "Moka"; + case 16: + return "Pamplemousses"; + case 17: + return "Plaines Wilhems"; + case 18: + return "Port Louis"; + case 19: + return "Riviere du Rempart"; + case 20: + return "Savanne"; + case 21: + return "Agalega Islands"; + case 22: + return "Cargados Carajos"; + case 23: + return "Rodrigues"; + default: + return NULL; + } +} + +static const char *get_region_name_MV(int region_code) { + switch (region_code) { + case 1: + return "Seenu"; + case 5: + return "Laamu"; + case 30: + return "Alifu"; + case 31: + return "Baa"; + case 32: + return "Dhaalu"; + case 33: + return "Faafu "; + case 34: + return "Gaafu Alifu"; + case 35: + return "Gaafu Dhaalu"; + case 36: + return "Haa Alifu"; + case 37: + return "Haa Dhaalu"; + case 38: + return "Kaafu"; + case 39: + return "Lhaviyani"; + case 40: + return "Maale"; + case 41: + return "Meemu"; + case 42: + return "Gnaviyani"; + case 43: + return "Noonu"; + case 44: + return "Raa"; + case 45: + return "Shaviyani"; + case 46: + return "Thaa"; + case 47: + return "Vaavu"; + default: + return NULL; + } +} + +static const char *get_region_name_MW(int region_code) { + switch (region_code) { + case 2: + return "Chikwawa"; + case 3: + return "Chiradzulu"; + case 4: + return "Chitipa"; + case 5: + return "Thyolo"; + case 6: + return "Dedza"; + case 7: + return "Dowa"; + case 8: + return "Karonga"; + case 9: + return "Kasungu"; + case 11: + return "Lilongwe"; + case 12: + return "Mangochi"; + case 13: + return "Mchinji"; + case 15: + return "Mzimba"; + case 16: + return "Ntcheu"; + case 17: + return "Nkhata Bay"; + case 18: + return "Nkhotakota"; + case 19: + return "Nsanje"; + case 20: + return "Ntchisi"; + case 21: + return "Rumphi"; + case 22: + return "Salima"; + case 23: + return "Zomba"; + case 24: + return "Blantyre"; + case 25: + return "Mwanza"; + case 26: + return "Balaka"; + case 27: + return "Likoma"; + case 28: + return "Machinga"; + case 29: + return "Mulanje"; + case 30: + return "Phalombe"; + default: + return NULL; + } +} + +static const char *get_region_name_MX(int region_code) { + switch (region_code) { + case 1: + return "Aguascalientes"; + case 2: + return "Baja California"; + case 3: + return "Baja California Sur"; + case 4: + return "Campeche"; + case 5: + return "Chiapas"; + case 6: + return "Chihuahua"; + case 7: + return "Coahuila de Zaragoza"; + case 8: + return "Colima"; + case 9: + return "Distrito Federal"; + case 10: + return "Durango"; + case 11: + return "Guanajuato"; + case 12: + return "Guerrero"; + case 13: + return "Hidalgo"; + case 14: + return "Jalisco"; + case 15: + return "Mexico"; + case 16: + return "Michoacan de Ocampo"; + case 17: + return "Morelos"; + case 18: + return "Nayarit"; + case 19: + return "Nuevo Leon"; + case 20: + return "Oaxaca"; + case 21: + return "Puebla"; + case 22: + return "Queretaro de Arteaga"; + case 23: + return "Quintana Roo"; + case 24: + return "San Luis Potosi"; + case 25: + return "Sinaloa"; + case 26: + return "Sonora"; + case 27: + return "Tabasco"; + case 28: + return "Tamaulipas"; + case 29: + return "Tlaxcala"; + case 30: + return "Veracruz-Llave"; + case 31: + return "Yucatan"; + case 32: + return "Zacatecas"; + default: + return NULL; + } +} + +static const char *get_region_name_MY(int region_code) { + switch (region_code) { + case 1: + return "Johor"; + case 2: + return "Kedah"; + case 3: + return "Kelantan"; + case 4: + return "Melaka"; + case 5: + return "Negeri Sembilan"; + case 6: + return "Pahang"; + case 7: + return "Perak"; + case 8: + return "Perlis"; + case 9: + return "Pulau Pinang"; + case 11: + return "Sarawak"; + case 12: + return "Selangor"; + case 13: + return "Terengganu"; + case 14: + return "Kuala Lumpur"; + case 15: + return "Labuan"; + case 16: + return "Sabah"; + case 17: + return "Putrajaya"; + default: + return NULL; + } +} + +static const char *get_region_name_MZ(int region_code) { + switch (region_code) { + case 1: + return "Cabo Delgado"; + case 2: + return "Gaza"; + case 3: + return "Inhambane"; + case 4: + return "Maputo"; + case 5: + return "Sofala"; + case 6: + return "Nampula"; + case 7: + return "Niassa"; + case 8: + return "Tete"; + case 9: + return "Zambezia"; + case 10: + return "Manica"; + case 11: + return "Maputo"; + default: + return NULL; + } +} + +static const char *get_region_name_NA(int region_code) { + switch (region_code) { + case 1: + return "Bethanien"; + case 2: + return "Caprivi Oos"; + case 3: + return "Boesmanland"; + case 4: + return "Gobabis"; + case 5: + return "Grootfontein"; + case 6: + return "Kaokoland"; + case 7: + return "Karibib"; + case 8: + return "Keetmanshoop"; + case 9: + return "Luderitz"; + case 10: + return "Maltahohe"; + case 11: + return "Okahandja"; + case 12: + return "Omaruru"; + case 13: + return "Otjiwarongo"; + case 14: + return "Outjo"; + case 15: + return "Owambo"; + case 16: + return "Rehoboth"; + case 17: + return "Swakopmund"; + case 18: + return "Tsumeb"; + case 20: + return "Karasburg"; + case 21: + return "Windhoek"; + case 22: + return "Damaraland"; + case 23: + return "Hereroland Oos"; + case 24: + return "Hereroland Wes"; + case 25: + return "Kavango"; + case 26: + return "Mariental"; + case 27: + return "Namaland"; + case 28: + return "Caprivi"; + case 29: + return "Erongo"; + case 30: + return "Hardap"; + case 31: + return "Karas"; + case 32: + return "Kunene"; + case 33: + return "Ohangwena"; + case 34: + return "Okavango"; + case 35: + return "Omaheke"; + case 36: + return "Omusati"; + case 37: + return "Oshana"; + case 38: + return "Oshikoto"; + case 39: + return "Otjozondjupa"; + default: + return NULL; + } +} + +static const char *get_region_name_NE(int region_code) { + switch (region_code) { + case 1: + return "Agadez"; + case 2: + return "Diffa"; + case 3: + return "Dosso"; + case 4: + return "Maradi"; + case 5: + return "Niamey"; + case 6: + return "Tahoua"; + case 7: + return "Zinder"; + case 8: + return "Niamey"; + default: + return NULL; + } +} + +static const char *get_region_name_NG(int region_code) { + switch (region_code) { + case 5: + return "Lagos"; + case 11: + return "Federal Capital Territory"; + case 16: + return "Ogun"; + case 21: + return "Akwa Ibom"; + case 22: + return "Cross River"; + case 23: + return "Kaduna"; + case 24: + return "Katsina"; + case 25: + return "Anambra"; + case 26: + return "Benue"; + case 27: + return "Borno"; + case 28: + return "Imo"; + case 29: + return "Kano"; + case 30: + return "Kwara"; + case 31: + return "Niger"; + case 32: + return "Oyo"; + case 35: + return "Adamawa"; + case 36: + return "Delta"; + case 37: + return "Edo"; + case 39: + return "Jigawa"; + case 40: + return "Kebbi"; + case 41: + return "Kogi"; + case 42: + return "Osun"; + case 43: + return "Taraba"; + case 44: + return "Yobe"; + case 45: + return "Abia"; + case 46: + return "Bauchi"; + case 47: + return "Enugu"; + case 48: + return "Ondo"; + case 49: + return "Plateau"; + case 50: + return "Rivers"; + case 51: + return "Sokoto"; + case 52: + return "Bayelsa"; + case 53: + return "Ebonyi"; + case 54: + return "Ekiti"; + case 55: + return "Gombe"; + case 56: + return "Nassarawa"; + case 57: + return "Zamfara"; + default: + return NULL; + } +} + +static const char *get_region_name_NI(int region_code) { + switch (region_code) { + case 1: + return "Boaco"; + case 2: + return "Carazo"; + case 3: + return "Chinandega"; + case 4: + return "Chontales"; + case 5: + return "Esteli"; + case 6: + return "Granada"; + case 7: + return "Jinotega"; + case 8: + return "Leon"; + case 9: + return "Madriz"; + case 10: + return "Managua"; + case 11: + return "Masaya"; + case 12: + return "Matagalpa"; + case 13: + return "Nueva Segovia"; + case 14: + return "Rio San Juan"; + case 15: + return "Rivas"; + case 16: + return "Zelaya"; + case 17: + return "Autonoma Atlantico Norte"; + case 18: + return "Region Autonoma Atlantico Sur"; + default: + return NULL; + } +} + +static const char *get_region_name_NL(int region_code) { + switch (region_code) { + case 1: + return "Drenthe"; + case 2: + return "Friesland"; + case 3: + return "Gelderland"; + case 4: + return "Groningen"; + case 5: + return "Limburg"; + case 6: + return "Noord-Brabant"; + case 7: + return "Noord-Holland"; + case 9: + return "Utrecht"; + case 10: + return "Zeeland"; + case 11: + return "Zuid-Holland"; + case 15: + return "Overijssel"; + case 16: + return "Flevoland"; + default: + return NULL; + } +} + +static const char *get_region_name_NO(int region_code) { + switch (region_code) { + case 1: + return "Akershus"; + case 2: + return "Aust-Agder"; + case 4: + return "Buskerud"; + case 5: + return "Finnmark"; + case 6: + return "Hedmark"; + case 7: + return "Hordaland"; + case 8: + return "More og Romsdal"; + case 9: + return "Nordland"; + case 10: + return "Nord-Trondelag"; + case 11: + return "Oppland"; + case 12: + return "Oslo"; + case 13: + return "Ostfold"; + case 14: + return "Rogaland"; + case 15: + return "Sogn og Fjordane"; + case 16: + return "Sor-Trondelag"; + case 17: + return "Telemark"; + case 18: + return "Troms"; + case 19: + return "Vest-Agder"; + case 20: + return "Vestfold"; + default: + return NULL; + } +} + +static const char *get_region_name_NP(int region_code) { + switch (region_code) { + case 1: + return "Bagmati"; + case 2: + return "Bheri"; + case 3: + return "Dhawalagiri"; + case 4: + return "Gandaki"; + case 5: + return "Janakpur"; + case 6: + return "Karnali"; + case 7: + return "Kosi"; + case 8: + return "Lumbini"; + case 9: + return "Mahakali"; + case 10: + return "Mechi"; + case 11: + return "Narayani"; + case 12: + return "Rapti"; + case 13: + return "Sagarmatha"; + case 14: + return "Seti"; + default: + return NULL; + } +} + +static const char *get_region_name_NR(int region_code) { + switch (region_code) { + case 1: + return "Aiwo"; + case 2: + return "Anabar"; + case 3: + return "Anetan"; + case 4: + return "Anibare"; + case 5: + return "Baiti"; + case 6: + return "Boe"; + case 7: + return "Buada"; + case 8: + return "Denigomodu"; + case 9: + return "Ewa"; + case 10: + return "Ijuw"; + case 11: + return "Meneng"; + case 12: + return "Nibok"; + case 13: + return "Uaboe"; + case 14: + return "Yaren"; + default: + return NULL; + } +} + +static const char *get_region_name_NZ(int region_code) { + switch (region_code) { + case 10: + return "Chatham Islands"; + case 1010: + return "Auckland"; + case 1011: + return "Bay of Plenty"; + case 1012: + return "Canterbury"; + case 1047: + return "Gisborne"; + case 1048: + return "Hawke's Bay"; + case 1049: + return "Manawatu-Wanganui"; + case 1050: + return "Marlborough"; + case 1051: + return "Nelson"; + case 1052: + return "Northland"; + case 1053: + return "Otago"; + case 1054: + return "Southland"; + case 1055: + return "Taranaki"; + case 1090: + return "Waikato"; + case 1091: + return "Wellington"; + case 1092: + return "West Coast"; + default: + return NULL; + } +} + +static const char *get_region_name_OM(int region_code) { + switch (region_code) { + case 1: + return "Ad Dakhiliyah"; + case 2: + return "Al Batinah"; + case 3: + return "Al Wusta"; + case 4: + return "Ash Sharqiyah"; + case 5: + return "Az Zahirah"; + case 6: + return "Masqat"; + case 7: + return "Musandam"; + case 8: + return "Zufar"; + default: + return NULL; + } +} + +static const char *get_region_name_PA(int region_code) { + switch (region_code) { + case 1: + return "Bocas del Toro"; + case 2: + return "Chiriqui"; + case 3: + return "Cocle"; + case 4: + return "Colon"; + case 5: + return "Darien"; + case 6: + return "Herrera"; + case 7: + return "Los Santos"; + case 8: + return "Panama"; + case 9: + return "San Blas"; + case 10: + return "Veraguas"; + default: + return NULL; + } +} + +static const char *get_region_name_PE(int region_code) { + switch (region_code) { + case 1: + return "Amazonas"; + case 2: + return "Ancash"; + case 3: + return "Apurimac"; + case 4: + return "Arequipa"; + case 5: + return "Ayacucho"; + case 6: + return "Cajamarca"; + case 7: + return "Callao"; + case 8: + return "Cusco"; + case 9: + return "Huancavelica"; + case 10: + return "Huanuco"; + case 11: + return "Ica"; + case 12: + return "Junin"; + case 13: + return "La Libertad"; + case 14: + return "Lambayeque"; + case 15: + return "Lima"; + case 16: + return "Loreto"; + case 17: + return "Madre de Dios"; + case 18: + return "Moquegua"; + case 19: + return "Pasco"; + case 20: + return "Piura"; + case 21: + return "Puno"; + case 22: + return "San Martin"; + case 23: + return "Tacna"; + case 24: + return "Tumbes"; + case 25: + return "Ucayali"; + default: + return NULL; + } +} + +static const char *get_region_name_PG(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 2: + return "Gulf"; + case 3: + return "Milne Bay"; + case 4: + return "Northern"; + case 5: + return "Southern Highlands"; + case 6: + return "Western"; + case 7: + return "North Solomons"; + case 8: + return "Chimbu"; + case 9: + return "Eastern Highlands"; + case 10: + return "East New Britain"; + case 11: + return "East Sepik"; + case 12: + return "Madang"; + case 13: + return "Manus"; + case 14: + return "Morobe"; + case 15: + return "New Ireland"; + case 16: + return "Western Highlands"; + case 17: + return "West New Britain"; + case 18: + return "Sandaun"; + case 19: + return "Enga"; + case 20: + return "National Capital"; + default: + return NULL; + } +} + +static const char *get_region_name_PH(int region_code) { + switch (region_code) { + case 1: + return "Abra"; + case 2: + return "Agusan del Norte"; + case 3: + return "Agusan del Sur"; + case 4: + return "Aklan"; + case 5: + return "Albay"; + case 6: + return "Antique"; + case 7: + return "Bataan"; + case 8: + return "Batanes"; + case 9: + return "Batangas"; + case 10: + return "Benguet"; + case 11: + return "Bohol"; + case 12: + return "Bukidnon"; + case 13: + return "Bulacan"; + case 14: + return "Cagayan"; + case 15: + return "Camarines Norte"; + case 16: + return "Camarines Sur"; + case 17: + return "Camiguin"; + case 18: + return "Capiz"; + case 19: + return "Catanduanes"; + case 20: + return "Cavite"; + case 21: + return "Cebu"; + case 22: + return "Basilan"; + case 23: + return "Eastern Samar"; + case 24: + return "Davao"; + case 25: + return "Davao del Sur"; + case 26: + return "Davao Oriental"; + case 27: + return "Ifugao"; + case 28: + return "Ilocos Norte"; + case 29: + return "Ilocos Sur"; + case 30: + return "Iloilo"; + case 31: + return "Isabela"; + case 32: + return "Kalinga-Apayao"; + case 33: + return "Laguna"; + case 34: + return "Lanao del Norte"; + case 35: + return "Lanao del Sur"; + case 36: + return "La Union"; + case 37: + return "Leyte"; + case 38: + return "Marinduque"; + case 39: + return "Masbate"; + case 40: + return "Mindoro Occidental"; + case 41: + return "Mindoro Oriental"; + case 42: + return "Misamis Occidental"; + case 43: + return "Misamis Oriental"; + case 44: + return "Mountain"; + case 45: + return "Negros Occidental"; + case 46: + return "Negros Oriental"; + case 47: + return "Nueva Ecija"; + case 48: + return "Nueva Vizcaya"; + case 49: + return "Palawan"; + case 50: + return "Pampanga"; + case 51: + return "Pangasinan"; + case 53: + return "Rizal"; + case 54: + return "Romblon"; + case 55: + return "Samar"; + case 56: + return "Maguindanao"; + case 57: + return "North Cotabato"; + case 58: + return "Sorsogon"; + case 59: + return "Southern Leyte"; + case 60: + return "Sulu"; + case 61: + return "Surigao del Norte"; + case 62: + return "Surigao del Sur"; + case 63: + return "Tarlac"; + case 64: + return "Zambales"; + case 65: + return "Zamboanga del Norte"; + case 66: + return "Zamboanga del Sur"; + case 67: + return "Northern Samar"; + case 68: + return "Quirino"; + case 69: + return "Siquijor"; + case 70: + return "South Cotabato"; + case 71: + return "Sultan Kudarat"; + case 72: + return "Tawitawi"; + case 832: + return "Angeles"; + case 833: + return "Bacolod"; + case 834: + return "Bago"; + case 835: + return "Baguio"; + case 836: + return "Bais"; + case 837: + return "Basilan City"; + case 838: + return "Batangas City"; + case 839: + return "Butuan"; + case 840: + return "Cabanatuan"; + case 875: + return "Cadiz"; + case 876: + return "Cagayan de Oro"; + case 877: + return "Calbayog"; + case 878: + return "Caloocan"; + case 879: + return "Canlaon"; + case 880: + return "Cavite City"; + case 881: + return "Cebu City"; + case 882: + return "Cotabato"; + case 883: + return "Dagupan"; + case 918: + return "Danao"; + case 919: + return "Dapitan"; + case 920: + return "Davao City"; + case 921: + return "Dipolog"; + case 922: + return "Dumaguete"; + case 923: + return "General Santos"; + case 924: + return "Gingoog"; + case 925: + return "Iligan"; + case 926: + return "Iloilo City"; + case 961: + return "Iriga"; + case 962: + return "La Carlota"; + case 963: + return "Laoag"; + case 964: + return "Lapu-Lapu"; + case 965: + return "Legaspi"; + case 966: + return "Lipa"; + case 967: + return "Lucena"; + case 968: + return "Mandaue"; + case 969: + return "Manila"; + case 1004: + return "Marawi"; + case 1005: + return "Naga"; + case 1006: + return "Olongapo"; + case 1007: + return "Ormoc"; + case 1008: + return "Oroquieta"; + case 1009: + return "Ozamis"; + case 1010: + return "Pagadian"; + case 1011: + return "Palayan"; + case 1012: + return "Pasay"; + case 1047: + return "Puerto Princesa"; + case 1048: + return "Quezon City"; + case 1049: + return "Roxas"; + case 1050: + return "San Carlos"; + case 1051: + return "San Carlos"; + case 1052: + return "San Jose"; + case 1053: + return "San Pablo"; + case 1054: + return "Silay"; + case 1055: + return "Surigao"; + case 1090: + return "Tacloban"; + case 1091: + return "Tagaytay"; + case 1092: + return "Tagbilaran"; + case 1093: + return "Tangub"; + case 1094: + return "Toledo"; + case 1095: + return "Trece Martires"; + case 1096: + return "Zamboanga"; + case 1097: + return "Aurora"; + case 1134: + return "Quezon"; + case 1135: + return "Negros Occidental"; + case 1141: + return "Biliran"; + case 1181: + return "Compostela Valley"; + case 1182: + return "Davao del Norte"; + case 1221: + return "Guimaras"; + case 1222: + return "Himamaylan"; + case 1225: + return "Kalinga"; + case 1262: + return "Las Pinas"; + case 1266: + return "Malabon"; + case 1267: + return "Malaybalay"; + case 1308: + return "Muntinlupa"; + case 1309: + return "Navotas"; + case 1311: + return "Paranaque"; + case 1313: + return "Passi"; + case 1477: + return "Zambales"; + case 1352: + return "San Jose del Monte"; + case 1353: + return "San Juan"; + case 1355: + return "Santiago"; + case 1356: + return "Sarangani"; + case 1391: + return "Sipalay"; + case 1393: + return "Surigao del Norte"; + case 1478: + return "Zamboanga"; + default: + return NULL; + } +} + +static const char *get_region_name_PK(int region_code) { + switch (region_code) { + case 1: + return "Federally Administered Tribal Areas"; + case 2: + return "Balochistan"; + case 3: + return "North-West Frontier"; + case 4: + return "Punjab"; + case 5: + return "Sindh"; + case 6: + return "Azad Kashmir"; + case 7: + return "Northern Areas"; + case 8: + return "Islamabad"; + default: + return NULL; + } +} + +static const char *get_region_name_PL(int region_code) { + switch (region_code) { + case 72: + return "Dolnoslaskie"; + case 73: + return "Kujawsko-Pomorskie"; + case 74: + return "Lodzkie"; + case 75: + return "Lubelskie"; + case 76: + return "Lubuskie"; + case 77: + return "Malopolskie"; + case 78: + return "Mazowieckie"; + case 79: + return "Opolskie"; + case 80: + return "Podkarpackie"; + case 81: + return "Podlaskie"; + case 82: + return "Pomorskie"; + case 83: + return "Slaskie"; + case 84: + return "Swietokrzyskie"; + case 85: + return "Warminsko-Mazurskie"; + case 86: + return "Wielkopolskie"; + case 87: + return "Zachodniopomorskie"; + default: + return NULL; + } +} + +static const char *get_region_name_PS(int region_code) { + switch (region_code) { + case 1131: + return "Gaza"; + case 1798: + return "West Bank"; + default: + return NULL; + } +} + +static const char *get_region_name_PT(int region_code) { + switch (region_code) { + case 2: + return "Aveiro"; + case 3: + return "Beja"; + case 4: + return "Braga"; + case 5: + return "Braganca"; + case 6: + return "Castelo Branco"; + case 7: + return "Coimbra"; + case 8: + return "Evora"; + case 9: + return "Faro"; + case 10: + return "Madeira"; + case 11: + return "Guarda"; + case 13: + return "Leiria"; + case 14: + return "Lisboa"; + case 16: + return "Portalegre"; + case 17: + return "Porto"; + case 18: + return "Santarem"; + case 19: + return "Setubal"; + case 20: + return "Viana do Castelo"; + case 21: + return "Vila Real"; + case 22: + return "Viseu"; + case 23: + return "Azores"; + default: + return NULL; + } +} + +static const char *get_region_name_PY(int region_code) { + switch (region_code) { + case 1: + return "Alto Parana"; + case 2: + return "Amambay"; + case 4: + return "Caaguazu"; + case 5: + return "Caazapa"; + case 6: + return "Central"; + case 7: + return "Concepcion"; + case 8: + return "Cordillera"; + case 10: + return "Guaira"; + case 11: + return "Itapua"; + case 12: + return "Misiones"; + case 13: + return "Neembucu"; + case 15: + return "Paraguari"; + case 16: + return "Presidente Hayes"; + case 17: + return "San Pedro"; + case 19: + return "Canindeyu"; + case 22: + return "Asuncion"; + case 23: + return "Alto Paraguay"; + case 24: + return "Boqueron"; + default: + return NULL; + } +} + +static const char *get_region_name_QA(int region_code) { + switch (region_code) { + case 1: + return "Ad Dawhah"; + case 2: + return "Al Ghuwariyah"; + case 3: + return "Al Jumaliyah"; + case 4: + return "Al Khawr"; + case 5: + return "Al Wakrah Municipality"; + case 6: + return "Ar Rayyan"; + case 8: + return "Madinat ach Shamal"; + case 9: + return "Umm Salal"; + case 10: + return "Al Wakrah"; + case 11: + return "Jariyan al Batnah"; + case 12: + return "Umm Sa'id"; + default: + return NULL; + } +} + +static const char *get_region_name_RO(int region_code) { + switch (region_code) { + case 1: + return "Alba"; + case 2: + return "Arad"; + case 3: + return "Arges"; + case 4: + return "Bacau"; + case 5: + return "Bihor"; + case 6: + return "Bistrita-Nasaud"; + case 7: + return "Botosani"; + case 8: + return "Braila"; + case 9: + return "Brasov"; + case 10: + return "Bucuresti"; + case 11: + return "Buzau"; + case 12: + return "Caras-Severin"; + case 13: + return "Cluj"; + case 14: + return "Constanta"; + case 15: + return "Covasna"; + case 16: + return "Dambovita"; + case 17: + return "Dolj"; + case 18: + return "Galati"; + case 19: + return "Gorj"; + case 20: + return "Harghita"; + case 21: + return "Hunedoara"; + case 22: + return "Ialomita"; + case 23: + return "Iasi"; + case 25: + return "Maramures"; + case 26: + return "Mehedinti"; + case 27: + return "Mures"; + case 28: + return "Neamt"; + case 29: + return "Olt"; + case 30: + return "Prahova"; + case 31: + return "Salaj"; + case 32: + return "Satu Mare"; + case 33: + return "Sibiu"; + case 34: + return "Suceava"; + case 35: + return "Teleorman"; + case 36: + return "Timis"; + case 37: + return "Tulcea"; + case 38: + return "Vaslui"; + case 39: + return "Valcea"; + case 40: + return "Vrancea"; + case 41: + return "Calarasi"; + case 42: + return "Giurgiu"; + case 43: + return "Ilfov"; + default: + return NULL; + } +} + +static const char *get_region_name_RS(int region_code) { + switch (region_code) { + case 1: + return "Kosovo"; + case 2: + return "Vojvodina"; + default: + return NULL; + } +} + +static const char *get_region_name_RU(int region_code) { + switch (region_code) { + case 1: + return "Adygeya, Republic of"; + case 2: + return "Aginsky Buryatsky AO"; + case 3: + return "Gorno-Altay"; + case 4: + return "Altaisky krai"; + case 5: + return "Amur"; + case 6: + return "Arkhangel'sk"; + case 7: + return "Astrakhan'"; + case 8: + return "Bashkortostan"; + case 9: + return "Belgorod"; + case 10: + return "Bryansk"; + case 11: + return "Buryat"; + case 12: + return "Chechnya"; + case 13: + return "Chelyabinsk"; + case 14: + return "Chita"; + case 15: + return "Chukot"; + case 16: + return "Chuvashia"; + case 17: + return "Dagestan"; + case 18: + return "Evenk"; + case 19: + return "Ingush"; + case 20: + return "Irkutsk"; + case 21: + return "Ivanovo"; + case 22: + return "Kabardin-Balkar"; + case 23: + return "Kaliningrad"; + case 24: + return "Kalmyk"; + case 25: + return "Kaluga"; + case 26: + return "Kamchatka"; + case 27: + return "Karachay-Cherkess"; + case 28: + return "Karelia"; + case 29: + return "Kemerovo"; + case 30: + return "Khabarovsk"; + case 31: + return "Khakass"; + case 32: + return "Khanty-Mansiy"; + case 33: + return "Kirov"; + case 34: + return "Komi"; + case 36: + return "Koryak"; + case 37: + return "Kostroma"; + case 38: + return "Krasnodar"; + case 39: + return "Krasnoyarsk"; + case 40: + return "Kurgan"; + case 41: + return "Kursk"; + case 42: + return "Leningrad"; + case 43: + return "Lipetsk"; + case 44: + return "Magadan"; + case 45: + return "Mariy-El"; + case 46: + return "Mordovia"; + case 47: + return "Moskva"; + case 48: + return "Moscow City"; + case 49: + return "Murmansk"; + case 50: + return "Nenets"; + case 51: + return "Nizhegorod"; + case 52: + return "Novgorod"; + case 53: + return "Novosibirsk"; + case 54: + return "Omsk"; + case 55: + return "Orenburg"; + case 56: + return "Orel"; + case 57: + return "Penza"; + case 58: + return "Perm'"; + case 59: + return "Primor'ye"; + case 60: + return "Pskov"; + case 61: + return "Rostov"; + case 62: + return "Ryazan'"; + case 63: + return "Sakha"; + case 64: + return "Sakhalin"; + case 65: + return "Samara"; + case 66: + return "Saint Petersburg City"; + case 67: + return "Saratov"; + case 68: + return "North Ossetia"; + case 69: + return "Smolensk"; + case 70: + return "Stavropol'"; + case 71: + return "Sverdlovsk"; + case 72: + return "Tambovskaya oblast"; + case 73: + return "Tatarstan"; + case 74: + return "Taymyr"; + case 75: + return "Tomsk"; + case 76: + return "Tula"; + case 77: + return "Tver'"; + case 78: + return "Tyumen'"; + case 79: + return "Tuva"; + case 80: + return "Udmurt"; + case 81: + return "Ul'yanovsk"; + case 83: + return "Vladimir"; + case 84: + return "Volgograd"; + case 85: + return "Vologda"; + case 86: + return "Voronezh"; + case 87: + return "Yamal-Nenets"; + case 88: + return "Yaroslavl'"; + case 89: + return "Yevrey"; + case 90: + return "Permskiy Kray"; + case 91: + return "Krasnoyarskiy Kray"; + case 92: + return "Kamchatskiy Kray"; + case 93: + return "Zabaykal'skiy Kray"; + default: + return NULL; + } +} + +static const char *get_region_name_RW(int region_code) { + switch (region_code) { + case 1: + return "Butare"; + case 6: + return "Gitarama"; + case 7: + return "Kibungo"; + case 9: + return "Kigali"; + case 11: + return "Est"; + case 12: + return "Kigali"; + case 13: + return "Nord"; + case 14: + return "Ouest"; + case 15: + return "Sud"; + default: + return NULL; + } +} + +static const char *get_region_name_SA(int region_code) { + switch (region_code) { + case 2: + return "Al Bahah"; + case 5: + return "Al Madinah"; + case 6: + return "Ash Sharqiyah"; + case 8: + return "Al Qasim"; + case 10: + return "Ar Riyad"; + case 11: + return "Asir Province"; + case 13: + return "Ha'il"; + case 14: + return "Makkah"; + case 15: + return "Al Hudud ash Shamaliyah"; + case 16: + return "Najran"; + case 17: + return "Jizan"; + case 19: + return "Tabuk"; + case 20: + return "Al Jawf"; + default: + return NULL; + } +} + +static const char *get_region_name_SB(int region_code) { + switch (region_code) { + case 3: + return "Malaita"; + case 6: + return "Guadalcanal"; + case 7: + return "Isabel"; + case 8: + return "Makira"; + case 9: + return "Temotu"; + case 10: + return "Central"; + case 11: + return "Western"; + case 12: + return "Choiseul"; + case 13: + return "Rennell and Bellona"; + default: + return NULL; + } +} + +static const char *get_region_name_SC(int region_code) { + switch (region_code) { + case 1: + return "Anse aux Pins"; + case 2: + return "Anse Boileau"; + case 3: + return "Anse Etoile"; + case 4: + return "Anse Louis"; + case 5: + return "Anse Royale"; + case 6: + return "Baie Lazare"; + case 7: + return "Baie Sainte Anne"; + case 8: + return "Beau Vallon"; + case 9: + return "Bel Air"; + case 10: + return "Bel Ombre"; + case 11: + return "Cascade"; + case 12: + return "Glacis"; + case 13: + return "Grand' Anse"; + case 14: + return "Grand' Anse"; + case 15: + return "La Digue"; + case 16: + return "La Riviere Anglaise"; + case 17: + return "Mont Buxton"; + case 18: + return "Mont Fleuri"; + case 19: + return "Plaisance"; + case 20: + return "Pointe La Rue"; + case 21: + return "Port Glaud"; + case 22: + return "Saint Louis"; + case 23: + return "Takamaka"; + default: + return NULL; + } +} + +static const char *get_region_name_SD(int region_code) { + switch (region_code) { + case 27: + return "Al Wusta"; + case 28: + return "Al Istiwa'iyah"; + case 29: + return "Al Khartum"; + case 30: + return "Ash Shamaliyah"; + case 31: + return "Ash Sharqiyah"; + case 32: + return "Bahr al Ghazal"; + case 33: + return "Darfur"; + case 34: + return "Kurdufan"; + case 35: + return "Upper Nile"; + case 40: + return "Al Wahadah State"; + case 44: + return "Central Equatoria State"; + case 49: + return "Southern Darfur"; + case 50: + return "Southern Kordofan"; + case 52: + return "Kassala"; + case 53: + return "River Nile"; + case 55: + return "Northern Darfur"; + default: + return NULL; + } +} + +static const char *get_region_name_SE(int region_code) { + switch (region_code) { + case 2: + return "Blekinge Lan"; + case 3: + return "Gavleborgs Lan"; + case 5: + return "Gotlands Lan"; + case 6: + return "Hallands Lan"; + case 7: + return "Jamtlands Lan"; + case 8: + return "Jonkopings Lan"; + case 9: + return "Kalmar Lan"; + case 10: + return "Dalarnas Lan"; + case 12: + return "Kronobergs Lan"; + case 14: + return "Norrbottens Lan"; + case 15: + return "Orebro Lan"; + case 16: + return "Ostergotlands Lan"; + case 18: + return "Sodermanlands Lan"; + case 21: + return "Uppsala Lan"; + case 22: + return "Varmlands Lan"; + case 23: + return "Vasterbottens Lan"; + case 24: + return "Vasternorrlands Lan"; + case 25: + return "Vastmanlands Lan"; + case 26: + return "Stockholms Lan"; + case 27: + return "Skane Lan"; + case 28: + return "Vastra Gotaland"; + default: + return NULL; + } +} + +static const char *get_region_name_SH(int region_code) { + switch (region_code) { + case 1: + return "Ascension"; + case 2: + return "Saint Helena"; + case 3: + return "Tristan da Cunha"; + default: + return NULL; + } +} + +static const char *get_region_name_SI(int region_code) { + switch (region_code) { + case 1: + return "Ajdovscina Commune"; + case 2: + return "Beltinci Commune"; + case 3: + return "Bled Commune"; + case 4: + return "Bohinj Commune"; + case 5: + return "Borovnica Commune"; + case 6: + return "Bovec Commune"; + case 7: + return "Brda Commune"; + case 8: + return "Brezice Commune"; + case 9: + return "Brezovica Commune"; + case 11: + return "Celje Commune"; + case 12: + return "Cerklje na Gorenjskem Commune"; + case 13: + return "Cerknica Commune"; + case 14: + return "Cerkno Commune"; + case 15: + return "Crensovci Commune"; + case 16: + return "Crna na Koroskem Commune"; + case 17: + return "Crnomelj Commune"; + case 19: + return "Divaca Commune"; + case 20: + return "Dobrepolje Commune"; + case 22: + return "Dol pri Ljubljani Commune"; + case 24: + return "Dornava Commune"; + case 25: + return "Dravograd Commune"; + case 26: + return "Duplek Commune"; + case 27: + return "Gorenja vas-Poljane Commune"; + case 28: + return "Gorisnica Commune"; + case 29: + return "Gornja Radgona Commune"; + case 30: + return "Gornji Grad Commune"; + case 31: + return "Gornji Petrovci Commune"; + case 32: + return "Grosuplje Commune"; + case 34: + return "Hrastnik Commune"; + case 35: + return "Hrpelje-Kozina Commune"; + case 36: + return "Idrija Commune"; + case 37: + return "Ig Commune"; + case 38: + return "Ilirska Bistrica Commune"; + case 39: + return "Ivancna Gorica Commune"; + case 40: + return "Izola-Isola Commune"; + case 42: + return "Jursinci Commune"; + case 44: + return "Kanal Commune"; + case 45: + return "Kidricevo Commune"; + case 46: + return "Kobarid Commune"; + case 47: + return "Kobilje Commune"; + case 49: + return "Komen Commune"; + case 50: + return "Koper-Capodistria Urban Commune"; + case 51: + return "Kozje Commune"; + case 52: + return "Kranj Commune"; + case 53: + return "Kranjska Gora Commune"; + case 54: + return "Krsko Commune"; + case 55: + return "Kungota Commune"; + case 57: + return "Lasko Commune"; + case 61: + return "Ljubljana Urban Commune"; + case 62: + return "Ljubno Commune"; + case 64: + return "Logatec Commune"; + case 66: + return "Loski Potok Commune"; + case 68: + return "Lukovica Commune"; + case 71: + return "Medvode Commune"; + case 72: + return "Menges Commune"; + case 73: + return "Metlika Commune"; + case 74: + return "Mezica Commune"; + case 76: + return "Mislinja Commune"; + case 77: + return "Moravce Commune"; + case 78: + return "Moravske Toplice Commune"; + case 79: + return "Mozirje Commune"; + case 80: + return "Murska Sobota Urban Commune"; + case 81: + return "Muta Commune"; + case 82: + return "Naklo Commune"; + case 83: + return "Nazarje Commune"; + case 84: + return "Nova Gorica Urban Commune"; + case 86: + return "Odranci Commune"; + case 87: + return "Ormoz Commune"; + case 88: + return "Osilnica Commune"; + case 89: + return "Pesnica Commune"; + case 91: + return "Pivka Commune"; + case 92: + return "Podcetrtek Commune"; + case 94: + return "Postojna Commune"; + case 97: + return "Puconci Commune"; + case 98: + return "Race-Fram Commune"; + case 99: + return "Radece Commune"; + case 832: + return "Radenci Commune"; + case 833: + return "Radlje ob Dravi Commune"; + case 834: + return "Radovljica Commune"; + case 837: + return "Rogasovci Commune"; + case 838: + return "Rogaska Slatina Commune"; + case 839: + return "Rogatec Commune"; + case 875: + return "Semic Commune"; + case 876: + return "Sencur Commune"; + case 877: + return "Sentilj Commune"; + case 878: + return "Sentjernej Commune"; + case 880: + return "Sevnica Commune"; + case 881: + return "Sezana Commune"; + case 882: + return "Skocjan Commune"; + case 883: + return "Skofja Loka Commune"; + case 918: + return "Skofljica Commune"; + case 919: + return "Slovenj Gradec Urban Commune"; + case 921: + return "Slovenske Konjice Commune"; + case 922: + return "Smarje pri Jelsah Commune"; + case 923: + return "Smartno ob Paki Commune"; + case 924: + return "Sostanj Commune"; + case 925: + return "Starse Commune"; + case 926: + return "Store Commune"; + case 961: + return "Sveti Jurij Commune"; + case 962: + return "Tolmin Commune"; + case 963: + return "Trbovlje Commune"; + case 964: + return "Trebnje Commune"; + case 965: + return "Trzic Commune"; + case 966: + return "Turnisce Commune"; + case 967: + return "Velenje Urban Commune"; + case 968: + return "Velike Lasce Commune"; + case 1004: + return "Vipava Commune"; + case 1005: + return "Vitanje Commune"; + case 1006: + return "Vodice Commune"; + case 1008: + return "Vrhnika Commune"; + case 1009: + return "Vuzenica Commune"; + case 1010: + return "Zagorje ob Savi Commune"; + case 1012: + return "Zavrc Commune"; + case 1047: + return "Zelezniki Commune"; + case 1048: + return "Ziri Commune"; + case 1049: + return "Zrece Commune"; + case 1050: + return "Benedikt Commune"; + case 1051: + return "Bistrica ob Sotli Commune"; + case 1052: + return "Bloke Commune"; + case 1053: + return "Braslovce Commune"; + case 1054: + return "Cankova Commune"; + case 1055: + return "Cerkvenjak Commune"; + case 1090: + return "Destrnik Commune"; + case 1091: + return "Dobje Commune"; + case 1092: + return "Dobrna Commune"; + case 1093: + return "Dobrova-Horjul-Polhov Gradec Commune"; + case 1094: + return "Dobrovnik-Dobronak Commune"; + case 1095: + return "Dolenjske Toplice Commune"; + case 1096: + return "Domzale Commune"; + case 1097: + return "Grad Commune"; + case 1098: + return "Hajdina Commune"; + case 1133: + return "Hoce-Slivnica Commune"; + case 1134: + return "Hodos-Hodos Commune"; + case 1135: + return "Horjul Commune"; + case 1136: + return "Jesenice Commune"; + case 1137: + return "Jezersko Commune"; + case 1138: + return "Kamnik Commune"; + case 1139: + return "Kocevje Commune"; + case 1140: + return "Komenda Commune"; + case 1141: + return "Kostel Commune"; + case 1176: + return "Krizevci Commune"; + case 1177: + return "Kuzma Commune"; + case 1178: + return "Lenart Commune"; + case 1179: + return "Lendava-Lendva Commune"; + case 1180: + return "Litija Commune"; + case 1181: + return "Ljutomer Commune"; + case 1182: + return "Loska Dolina Commune"; + case 1183: + return "Lovrenc na Pohorju Commune"; + case 1184: + return "Luce Commune"; + case 1219: + return "Majsperk Commune"; + case 1220: + return "Maribor Commune"; + case 1221: + return "Markovci Commune"; + case 1222: + return "Miklavz na Dravskem polju Commune"; + case 1223: + return "Miren-Kostanjevica Commune"; + case 1224: + return "Mirna Pec Commune"; + case 1225: + return "Novo mesto Urban Commune"; + case 1226: + return "Oplotnica Commune"; + case 1227: + return "Piran-Pirano Commune"; + case 1262: + return "Podlehnik Commune"; + case 1263: + return "Podvelka Commune"; + case 1264: + return "Polzela Commune"; + case 1265: + return "Prebold Commune"; + case 1266: + return "Preddvor Commune"; + case 1267: + return "Prevalje Commune"; + case 1268: + return "Ptuj Urban Commune"; + case 1269: + return "Ravne na Koroskem Commune"; + case 1270: + return "Razkrizje Commune"; + case 1305: + return "Ribnica Commune"; + case 1306: + return "Ribnica na Pohorju Commune"; + case 1307: + return "Ruse Commune"; + case 1308: + return "Salovci Commune"; + case 1309: + return "Selnica ob Dravi Commune"; + case 1310: + return "Sempeter-Vrtojba Commune"; + case 1311: + return "Sentjur pri Celju Commune"; + case 1312: + return "Slovenska Bistrica Commune"; + case 1313: + return "Smartno pri Litiji Commune"; + case 1348: + return "Sodrazica Commune"; + case 1349: + return "Solcava Commune"; + case 1350: + return "Sveta Ana Commune"; + case 1351: + return "Sveti Andraz v Slovenskih goricah Commune"; + case 1352: + return "Tabor Commune"; + case 1353: + return "Tisina Commune"; + case 1354: + return "Trnovska vas Commune"; + case 1355: + return "Trzin Commune"; + case 1356: + return "Velika Polana Commune"; + case 1391: + return "Verzej Commune"; + case 1392: + return "Videm Commune"; + case 1393: + return "Vojnik Commune"; + case 1394: + return "Vransko Commune"; + case 1395: + return "Zalec Commune"; + case 1396: + return "Zetale Commune"; + case 1397: + return "Zirovnica Commune"; + case 1398: + return "Zuzemberk Commune"; + case 1399: + return "Apace Commune"; + case 1434: + return "Cirkulane Commune"; + case 1435: + return "Gorje"; + case 1436: + return "Kostanjevica na Krki"; + case 1437: + return "Log-Dragomer"; + case 1438: + return "Makole"; + case 1439: + return "Mirna"; + case 1440: + return "Mokronog-Trebelno"; + case 1441: + return "Poljcane"; + case 1442: + return "Recica ob Savinji"; + case 1477: + return "Rence-Vogrsko"; + case 1478: + return "Sentrupert"; + case 1479: + return "Smarjesk Toplice"; + case 1480: + return "Sredisce ob Dravi"; + case 1481: + return "Straza"; + case 1483: + return "Sveti Jurij v Slovenskih Goricah"; + default: + return NULL; + } +} + +static const char *get_region_name_SK(int region_code) { + switch (region_code) { + case 1: + return "Banska Bystrica"; + case 2: + return "Bratislava"; + case 3: + return "Kosice"; + case 4: + return "Nitra"; + case 5: + return "Presov"; + case 6: + return "Trencin"; + case 7: + return "Trnava"; + case 8: + return "Zilina"; + default: + return NULL; + } +} + +static const char *get_region_name_SL(int region_code) { + switch (region_code) { + case 1: + return "Eastern"; + case 2: + return "Northern"; + case 3: + return "Southern"; + case 4: + return "Western Area"; + default: + return NULL; + } +} + +static const char *get_region_name_SM(int region_code) { + switch (region_code) { + case 1: + return "Acquaviva"; + case 2: + return "Chiesanuova"; + case 3: + return "Domagnano"; + case 4: + return "Faetano"; + case 5: + return "Fiorentino"; + case 6: + return "Borgo Maggiore"; + case 7: + return "San Marino"; + case 8: + return "Monte Giardino"; + case 9: + return "Serravalle"; + default: + return NULL; + } +} + +static const char *get_region_name_SN(int region_code) { + switch (region_code) { + case 1: + return "Dakar"; + case 3: + return "Diourbel"; + case 5: + return "Tambacounda"; + case 7: + return "Thies"; + case 9: + return "Fatick"; + case 10: + return "Kaolack"; + case 11: + return "Kolda"; + case 12: + return "Ziguinchor"; + case 13: + return "Louga"; + case 14: + return "Saint-Louis"; + case 15: + return "Matam"; + default: + return NULL; + } +} + +static const char *get_region_name_SO(int region_code) { + switch (region_code) { + case 1: + return "Bakool"; + case 2: + return "Banaadir"; + case 3: + return "Bari"; + case 4: + return "Bay"; + case 5: + return "Galguduud"; + case 6: + return "Gedo"; + case 7: + return "Hiiraan"; + case 8: + return "Jubbada Dhexe"; + case 9: + return "Jubbada Hoose"; + case 10: + return "Mudug"; + case 11: + return "Nugaal"; + case 12: + return "Sanaag"; + case 13: + return "Shabeellaha Dhexe"; + case 14: + return "Shabeellaha Hoose"; + case 16: + return "Woqooyi Galbeed"; + case 18: + return "Nugaal"; + case 19: + return "Togdheer"; + case 20: + return "Woqooyi Galbeed"; + case 21: + return "Awdal"; + case 22: + return "Sool"; + default: + return NULL; + } +} + +static const char *get_region_name_SR(int region_code) { + switch (region_code) { + case 10: + return "Brokopondo"; + case 11: + return "Commewijne"; + case 12: + return "Coronie"; + case 13: + return "Marowijne"; + case 14: + return "Nickerie"; + case 15: + return "Para"; + case 16: + return "Paramaribo"; + case 17: + return "Saramacca"; + case 18: + return "Sipaliwini"; + case 19: + return "Wanica"; + default: + return NULL; + } +} + +static const char *get_region_name_SS(int region_code) { + switch (region_code) { + case 1: + return "Central Equatoria"; + case 2: + return "Eastern Equatoria"; + case 3: + return "Jonglei"; + case 4: + return "Lakes"; + case 5: + return "Northern Bahr el Ghazal"; + case 6: + return "Unity"; + case 7: + return "Upper Nile"; + case 8: + return "Warrap"; + case 9: + return "Western Bahr el Ghazal"; + case 10: + return "Western Equatoria"; + default: + return NULL; + } +} + +static const char *get_region_name_ST(int region_code) { + switch (region_code) { + case 1: + return "Principe"; + case 2: + return "Sao Tome"; + default: + return NULL; + } +} + +static const char *get_region_name_SV(int region_code) { + switch (region_code) { + case 1: + return "Ahuachapan"; + case 2: + return "Cabanas"; + case 3: + return "Chalatenango"; + case 4: + return "Cuscatlan"; + case 5: + return "La Libertad"; + case 6: + return "La Paz"; + case 7: + return "La Union"; + case 8: + return "Morazan"; + case 9: + return "San Miguel"; + case 10: + return "San Salvador"; + case 11: + return "Santa Ana"; + case 12: + return "San Vicente"; + case 13: + return "Sonsonate"; + case 14: + return "Usulutan"; + default: + return NULL; + } +} + +static const char *get_region_name_SY(int region_code) { + switch (region_code) { + case 1: + return "Al Hasakah"; + case 2: + return "Al Ladhiqiyah"; + case 3: + return "Al Qunaytirah"; + case 4: + return "Ar Raqqah"; + case 5: + return "As Suwayda'"; + case 6: + return "Dar"; + case 7: + return "Dayr az Zawr"; + case 8: + return "Rif Dimashq"; + case 9: + return "Halab"; + case 10: + return "Hamah"; + case 11: + return "Hims"; + case 12: + return "Idlib"; + case 13: + return "Dimashq"; + case 14: + return "Tartus"; + default: + return NULL; + } +} + +static const char *get_region_name_SZ(int region_code) { + switch (region_code) { + case 1: + return "Hhohho"; + case 2: + return "Lubombo"; + case 3: + return "Manzini"; + case 4: + return "Shiselweni"; + case 5: + return "Praslin"; + default: + return NULL; + } +} + +static const char *get_region_name_TD(int region_code) { + switch (region_code) { + case 1: + return "Batha"; + case 2: + return "Biltine"; + case 3: + return "Borkou-Ennedi-Tibesti"; + case 4: + return "Chari-Baguirmi"; + case 5: + return "Guera"; + case 6: + return "Kanem"; + case 7: + return "Lac"; + case 8: + return "Logone Occidental"; + case 9: + return "Logone Oriental"; + case 10: + return "Mayo-Kebbi"; + case 11: + return "Moyen-Chari"; + case 12: + return "Ouaddai"; + case 13: + return "Salamat"; + case 14: + return "Tandjile"; + default: + return NULL; + } +} + +static const char *get_region_name_TG(int region_code) { + switch (region_code) { + case 22: + return "Centrale"; + case 23: + return "Kara"; + case 24: + return "Maritime"; + case 25: + return "Plateaux"; + case 26: + return "Savanes"; + default: + return NULL; + } +} + +static const char *get_region_name_TH(int region_code) { + switch (region_code) { + case 1: + return "Mae Hong Son"; + case 2: + return "Chiang Mai"; + case 3: + return "Chiang Rai"; + case 4: + return "Nan"; + case 5: + return "Lamphun"; + case 6: + return "Lampang"; + case 7: + return "Phrae"; + case 8: + return "Tak"; + case 9: + return "Sukhothai"; + case 10: + return "Uttaradit"; + case 11: + return "Kamphaeng Phet"; + case 12: + return "Phitsanulok"; + case 13: + return "Phichit"; + case 14: + return "Phetchabun"; + case 15: + return "Uthai Thani"; + case 16: + return "Nakhon Sawan"; + case 17: + return "Nong Khai"; + case 18: + return "Loei"; + case 20: + return "Sakon Nakhon"; + case 21: + return "Nakhon Phanom"; + case 22: + return "Khon Kaen"; + case 23: + return "Kalasin"; + case 24: + return "Maha Sarakham"; + case 25: + return "Roi Et"; + case 26: + return "Chaiyaphum"; + case 27: + return "Nakhon Ratchasima"; + case 28: + return "Buriram"; + case 29: + return "Surin"; + case 30: + return "Sisaket"; + case 31: + return "Narathiwat"; + case 32: + return "Chai Nat"; + case 33: + return "Sing Buri"; + case 34: + return "Lop Buri"; + case 35: + return "Ang Thong"; + case 36: + return "Phra Nakhon Si Ayutthaya"; + case 37: + return "Saraburi"; + case 38: + return "Nonthaburi"; + case 39: + return "Pathum Thani"; + case 40: + return "Krung Thep"; + case 41: + return "Phayao"; + case 42: + return "Samut Prakan"; + case 43: + return "Nakhon Nayok"; + case 44: + return "Chachoengsao"; + case 45: + return "Prachin Buri"; + case 46: + return "Chon Buri"; + case 47: + return "Rayong"; + case 48: + return "Chanthaburi"; + case 49: + return "Trat"; + case 50: + return "Kanchanaburi"; + case 51: + return "Suphan Buri"; + case 52: + return "Ratchaburi"; + case 53: + return "Nakhon Pathom"; + case 54: + return "Samut Songkhram"; + case 55: + return "Samut Sakhon"; + case 56: + return "Phetchaburi"; + case 57: + return "Prachuap Khiri Khan"; + case 58: + return "Chumphon"; + case 59: + return "Ranong"; + case 60: + return "Surat Thani"; + case 61: + return "Phangnga"; + case 62: + return "Phuket"; + case 63: + return "Krabi"; + case 64: + return "Nakhon Si Thammarat"; + case 65: + return "Trang"; + case 66: + return "Phatthalung"; + case 67: + return "Satun"; + case 68: + return "Songkhla"; + case 69: + return "Pattani"; + case 70: + return "Yala"; + case 71: + return "Ubon Ratchathani"; + case 72: + return "Yasothon"; + case 73: + return "Nakhon Phanom"; + case 74: + return "Prachin Buri"; + case 75: + return "Ubon Ratchathani"; + case 76: + return "Udon Thani"; + case 77: + return "Amnat Charoen"; + case 78: + return "Mukdahan"; + case 79: + return "Nong Bua Lamphu"; + case 80: + return "Sa Kaeo"; + case 81: + return "Bueng Kan"; + default: + return NULL; + } +} + +static const char *get_region_name_TJ(int region_code) { + switch (region_code) { + case 1: + return "Kuhistoni Badakhshon"; + case 2: + return "Khatlon"; + case 3: + return "Sughd"; + case 4: + return "Dushanbe"; + case 5: + return "Nohiyahoi Tobei Jumhuri"; + default: + return NULL; + } +} + +static const char *get_region_name_TL(int region_code) { + switch (region_code) { + case 6: + return "Dili"; + default: + return NULL; + } +} + +static const char *get_region_name_TM(int region_code) { + switch (region_code) { + case 1: + return "Ahal"; + case 2: + return "Balkan"; + case 3: + return "Dashoguz"; + case 4: + return "Lebap"; + case 5: + return "Mary"; + default: + return NULL; + } +} + +static const char *get_region_name_TN(int region_code) { + switch (region_code) { + case 2: + return "Kasserine"; + case 3: + return "Kairouan"; + case 6: + return "Jendouba"; + case 10: + return "Qafsah"; + case 14: + return "El Kef"; + case 15: + return "Al Mahdia"; + case 16: + return "Al Munastir"; + case 17: + return "Bajah"; + case 18: + return "Bizerte"; + case 19: + return "Nabeul"; + case 22: + return "Siliana"; + case 23: + return "Sousse"; + case 27: + return "Ben Arous"; + case 28: + return "Madanin"; + case 29: + return "Gabes"; + case 31: + return "Kebili"; + case 32: + return "Sfax"; + case 33: + return "Sidi Bou Zid"; + case 34: + return "Tataouine"; + case 35: + return "Tozeur"; + case 36: + return "Tunis"; + case 37: + return "Zaghouan"; + case 38: + return "Aiana"; + case 39: + return "Manouba"; + default: + return NULL; + } +} + +static const char *get_region_name_TO(int region_code) { + switch (region_code) { + case 1: + return "Ha"; + case 2: + return "Tongatapu"; + case 3: + return "Vava"; + default: + return NULL; + } +} + +static const char *get_region_name_TR(int region_code) { + switch (region_code) { + case 2: + return "Adiyaman"; + case 3: + return "Afyonkarahisar"; + case 4: + return "Agri"; + case 5: + return "Amasya"; + case 7: + return "Antalya"; + case 8: + return "Artvin"; + case 9: + return "Aydin"; + case 10: + return "Balikesir"; + case 11: + return "Bilecik"; + case 12: + return "Bingol"; + case 13: + return "Bitlis"; + case 14: + return "Bolu"; + case 15: + return "Burdur"; + case 16: + return "Bursa"; + case 17: + return "Canakkale"; + case 19: + return "Corum"; + case 20: + return "Denizli"; + case 21: + return "Diyarbakir"; + case 22: + return "Edirne"; + case 23: + return "Elazig"; + case 24: + return "Erzincan"; + case 25: + return "Erzurum"; + case 26: + return "Eskisehir"; + case 28: + return "Giresun"; + case 31: + return "Hatay"; + case 32: + return "Mersin"; + case 33: + return "Isparta"; + case 34: + return "Istanbul"; + case 35: + return "Izmir"; + case 37: + return "Kastamonu"; + case 38: + return "Kayseri"; + case 39: + return "Kirklareli"; + case 40: + return "Kirsehir"; + case 41: + return "Kocaeli"; + case 43: + return "Kutahya"; + case 44: + return "Malatya"; + case 45: + return "Manisa"; + case 46: + return "Kahramanmaras"; + case 48: + return "Mugla"; + case 49: + return "Mus"; + case 50: + return "Nevsehir"; + case 52: + return "Ordu"; + case 53: + return "Rize"; + case 54: + return "Sakarya"; + case 55: + return "Samsun"; + case 57: + return "Sinop"; + case 58: + return "Sivas"; + case 59: + return "Tekirdag"; + case 60: + return "Tokat"; + case 61: + return "Trabzon"; + case 62: + return "Tunceli"; + case 63: + return "Sanliurfa"; + case 64: + return "Usak"; + case 65: + return "Van"; + case 66: + return "Yozgat"; + case 68: + return "Ankara"; + case 69: + return "Gumushane"; + case 70: + return "Hakkari"; + case 71: + return "Konya"; + case 72: + return "Mardin"; + case 73: + return "Nigde"; + case 74: + return "Siirt"; + case 75: + return "Aksaray"; + case 76: + return "Batman"; + case 77: + return "Bayburt"; + case 78: + return "Karaman"; + case 79: + return "Kirikkale"; + case 80: + return "Sirnak"; + case 81: + return "Adana"; + case 82: + return "Cankiri"; + case 83: + return "Gaziantep"; + case 84: + return "Kars"; + case 85: + return "Zonguldak"; + case 86: + return "Ardahan"; + case 87: + return "Bartin"; + case 88: + return "Igdir"; + case 89: + return "Karabuk"; + case 90: + return "Kilis"; + case 91: + return "Osmaniye"; + case 92: + return "Yalova"; + case 93: + return "Duzce"; + default: + return NULL; + } +} + +static const char *get_region_name_TT(int region_code) { + switch (region_code) { + case 1: + return "Arima"; + case 2: + return "Caroni"; + case 3: + return "Mayaro"; + case 4: + return "Nariva"; + case 5: + return "Port-of-Spain"; + case 6: + return "Saint Andrew"; + case 7: + return "Saint David"; + case 8: + return "Saint George"; + case 9: + return "Saint Patrick"; + case 10: + return "San Fernando"; + case 11: + return "Tobago"; + case 12: + return "Victoria"; + default: + return NULL; + } +} + +static const char *get_region_name_TW(int region_code) { + switch (region_code) { + case 1: + return "Fu-chien"; + case 2: + return "Kao-hsiung"; + case 3: + return "T'ai-pei"; + case 4: + return "T'ai-wan"; + default: + return NULL; + } +} + +static const char *get_region_name_TZ(int region_code) { + switch (region_code) { + case 2: + return "Pwani"; + case 3: + return "Dodoma"; + case 4: + return "Iringa"; + case 5: + return "Kigoma"; + case 6: + return "Kilimanjaro"; + case 7: + return "Lindi"; + case 8: + return "Mara"; + case 9: + return "Mbeya"; + case 10: + return "Morogoro"; + case 11: + return "Mtwara"; + case 12: + return "Mwanza"; + case 13: + return "Pemba North"; + case 14: + return "Ruvuma"; + case 15: + return "Shinyanga"; + case 16: + return "Singida"; + case 17: + return "Tabora"; + case 18: + return "Tanga"; + case 19: + return "Kagera"; + case 20: + return "Pemba South"; + case 21: + return "Zanzibar Central"; + case 22: + return "Zanzibar North"; + case 23: + return "Dar es Salaam"; + case 24: + return "Rukwa"; + case 25: + return "Zanzibar Urban"; + case 26: + return "Arusha"; + case 27: + return "Manyara"; + default: + return NULL; + } +} + +static const char *get_region_name_UA(int region_code) { + switch (region_code) { + case 1: + return "Cherkas'ka Oblast'"; + case 2: + return "Chernihivs'ka Oblast'"; + case 3: + return "Chernivets'ka Oblast'"; + case 4: + return "Dnipropetrovs'ka Oblast'"; + case 5: + return "Donets'ka Oblast'"; + case 6: + return "Ivano-Frankivs'ka Oblast'"; + case 7: + return "Kharkivs'ka Oblast'"; + case 8: + return "Khersons'ka Oblast'"; + case 9: + return "Khmel'nyts'ka Oblast'"; + case 10: + return "Kirovohrads'ka Oblast'"; + case 11: + return "Krym"; + case 12: + return "Kyyiv"; + case 13: + return "Kyyivs'ka Oblast'"; + case 14: + return "Luhans'ka Oblast'"; + case 15: + return "L'vivs'ka Oblast'"; + case 16: + return "Mykolayivs'ka Oblast'"; + case 17: + return "Odes'ka Oblast'"; + case 18: + return "Poltavs'ka Oblast'"; + case 19: + return "Rivnens'ka Oblast'"; + case 20: + return "Sevastopol'"; + case 21: + return "Sums'ka Oblast'"; + case 22: + return "Ternopil's'ka Oblast'"; + case 23: + return "Vinnyts'ka Oblast'"; + case 24: + return "Volyns'ka Oblast'"; + case 25: + return "Zakarpats'ka Oblast'"; + case 26: + return "Zaporiz'ka Oblast'"; + case 27: + return "Zhytomyrs'ka Oblast'"; + default: + return NULL; + } +} + +static const char *get_region_name_UG(int region_code) { + switch (region_code) { + case 26: + return "Apac"; + case 28: + return "Bundibugyo"; + case 29: + return "Bushenyi"; + case 30: + return "Gulu"; + case 31: + return "Hoima"; + case 33: + return "Jinja"; + case 36: + return "Kalangala"; + case 37: + return "Kampala"; + case 38: + return "Kamuli"; + case 39: + return "Kapchorwa"; + case 40: + return "Kasese"; + case 41: + return "Kibale"; + case 42: + return "Kiboga"; + case 43: + return "Kisoro"; + case 45: + return "Kotido"; + case 46: + return "Kumi"; + case 47: + return "Lira"; + case 50: + return "Masindi"; + case 52: + return "Mbarara"; + case 56: + return "Mubende"; + case 58: + return "Nebbi"; + case 59: + return "Ntungamo"; + case 60: + return "Pallisa"; + case 61: + return "Rakai"; + case 65: + return "Adjumani"; + case 66: + return "Bugiri"; + case 67: + return "Busia"; + case 69: + return "Katakwi"; + case 70: + return "Luwero"; + case 71: + return "Masaka"; + case 72: + return "Moyo"; + case 73: + return "Nakasongola"; + case 74: + return "Sembabule"; + case 76: + return "Tororo"; + case 77: + return "Arua"; + case 78: + return "Iganga"; + case 79: + return "Kabarole"; + case 80: + return "Kaberamaido"; + case 81: + return "Kamwenge"; + case 82: + return "Kanungu"; + case 83: + return "Kayunga"; + case 84: + return "Kitgum"; + case 85: + return "Kyenjojo"; + case 86: + return "Mayuge"; + case 87: + return "Mbale"; + case 88: + return "Moroto"; + case 89: + return "Mpigi"; + case 90: + return "Mukono"; + case 91: + return "Nakapiripirit"; + case 92: + return "Pader"; + case 93: + return "Rukungiri"; + case 94: + return "Sironko"; + case 95: + return "Soroti"; + case 96: + return "Wakiso"; + case 97: + return "Yumbe"; + default: + return NULL; + } +} + +static const char *get_region_name_US(int region_code) { + switch (region_code) { + case 848: + return "Armed Forces Americas"; + case 852: + return "Armed Forces Europe, Middle East, & Canada"; + case 858: + return "Alaska"; + case 859: + return "Alabama"; + case 863: + return "Armed Forces Pacific"; + case 865: + return "Arkansas"; + case 866: + return "American Samoa"; + case 873: + return "Arizona"; + case 934: + return "California"; + case 948: + return "Colorado"; + case 953: + return "Connecticut"; + case 979: + return "District of Columbia"; + case 981: + return "Delaware"; + case 1074: + return "Florida"; + case 1075: + return "Federated States of Micronesia"; + case 1106: + return "Georgia"; + case 1126: + return "Guam"; + case 1157: + return "Hawaii"; + case 1192: + return "Iowa"; + case 1195: + return "Idaho"; + case 1203: + return "Illinois"; + case 1205: + return "Indiana"; + case 1296: + return "Kansas"; + case 1302: + return "Kentucky"; + case 1321: + return "Louisiana"; + case 1364: + return "Massachusetts"; + case 1367: + return "Maryland"; + case 1368: + return "Maine"; + case 1371: + return "Marshall Islands"; + case 1372: + return "Michigan"; + case 1377: + return "Minnesota"; + case 1378: + return "Missouri"; + case 1379: + return "Northern Mariana Islands"; + case 1382: + return "Mississippi"; + case 1383: + return "Montana"; + case 1409: + return "North Carolina"; + case 1410: + return "North Dakota"; + case 1411: + return "Nebraska"; + case 1414: + return "New Hampshire"; + case 1416: + return "New Jersey"; + case 1419: + return "New Mexico"; + case 1428: + return "Nevada"; + case 1431: + return "New York"; + case 1457: + return "Ohio"; + case 1460: + return "Oklahoma"; + case 1467: + return "Oregon"; + case 1493: + return "Pennsylvania"; + case 1515: + return "Palau"; + case 1587: + return "Rhode Island"; + case 1624: + return "South Carolina"; + case 1625: + return "South Dakota"; + case 1678: + return "Tennessee"; + case 1688: + return "Texas"; + case 1727: + return "Utah"; + case 1751: + return "Virginia"; + case 1759: + return "Virgin Islands"; + case 1770: + return "Vermont"; + case 1794: + return "Washington"; + case 1802: + return "Wisconsin"; + case 1815: + return "West Virginia"; + case 1818: + return "Wyoming"; + default: + return NULL; + } +} + +static const char *get_region_name_UY(int region_code) { + switch (region_code) { + case 1: + return "Artigas"; + case 2: + return "Canelones"; + case 3: + return "Cerro Largo"; + case 4: + return "Colonia"; + case 5: + return "Durazno"; + case 6: + return "Flores"; + case 7: + return "Florida"; + case 8: + return "Lavalleja"; + case 9: + return "Maldonado"; + case 10: + return "Montevideo"; + case 11: + return "Paysandu"; + case 12: + return "Rio Negro"; + case 13: + return "Rivera"; + case 14: + return "Rocha"; + case 15: + return "Salto"; + case 16: + return "San Jose"; + case 17: + return "Soriano"; + case 18: + return "Tacuarembo"; + case 19: + return "Treinta y Tres"; + default: + return NULL; + } +} + +static const char *get_region_name_UZ(int region_code) { + switch (region_code) { + case 1: + return "Andijon"; + case 2: + return "Bukhoro"; + case 3: + return "Farghona"; + case 4: + return "Jizzakh"; + case 5: + return "Khorazm"; + case 6: + return "Namangan"; + case 7: + return "Nawoiy"; + case 8: + return "Qashqadaryo"; + case 9: + return "Qoraqalpoghiston"; + case 10: + return "Samarqand"; + case 11: + return "Sirdaryo"; + case 12: + return "Surkhondaryo"; + case 13: + return "Toshkent"; + case 14: + return "Toshkent"; + case 15: + return "Jizzax"; + default: + return NULL; + } +} + +static const char *get_region_name_VC(int region_code) { + switch (region_code) { + case 1: + return "Charlotte"; + case 2: + return "Saint Andrew"; + case 3: + return "Saint David"; + case 4: + return "Saint George"; + case 5: + return "Saint Patrick"; + case 6: + return "Grenadines"; + default: + return NULL; + } +} + +static const char *get_region_name_VE(int region_code) { + switch (region_code) { + case 1: + return "Amazonas"; + case 2: + return "Anzoategui"; + case 3: + return "Apure"; + case 4: + return "Aragua"; + case 5: + return "Barinas"; + case 6: + return "Bolivar"; + case 7: + return "Carabobo"; + case 8: + return "Cojedes"; + case 9: + return "Delta Amacuro"; + case 11: + return "Falcon"; + case 12: + return "Guarico"; + case 13: + return "Lara"; + case 14: + return "Merida"; + case 15: + return "Miranda"; + case 16: + return "Monagas"; + case 17: + return "Nueva Esparta"; + case 18: + return "Portuguesa"; + case 19: + return "Sucre"; + case 20: + return "Tachira"; + case 21: + return "Trujillo"; + case 22: + return "Yaracuy"; + case 23: + return "Zulia"; + case 24: + return "Dependencias Federales"; + case 25: + return "Distrito Federal"; + case 26: + return "Vargas"; + default: + return NULL; + } +} + +static const char *get_region_name_VN(int region_code) { + switch (region_code) { + case 1: + return "An Giang"; + case 3: + return "Ben Tre"; + case 5: + return "Cao Bang"; + case 9: + return "Dong Thap"; + case 13: + return "Hai Phong"; + case 20: + return "Ho Chi Minh"; + case 21: + return "Kien Giang"; + case 23: + return "Lam Dong"; + case 24: + return "Long An"; + case 30: + return "Quang Ninh"; + case 32: + return "Son La"; + case 33: + return "Tay Ninh"; + case 34: + return "Thanh Hoa"; + case 35: + return "Thai Binh"; + case 37: + return "Tien Giang"; + case 39: + return "Lang Son"; + case 43: + return "Dong Nai"; + case 44: + return "Ha Noi"; + case 45: + return "Ba Ria-Vung Tau"; + case 46: + return "Binh Dinh"; + case 47: + return "Binh Thuan"; + case 49: + return "Gia Lai"; + case 50: + return "Ha Giang"; + case 52: + return "Ha Tinh"; + case 53: + return "Hoa Binh"; + case 54: + return "Khanh Hoa"; + case 55: + return "Kon Tum"; + case 58: + return "Nghe An"; + case 59: + return "Ninh Binh"; + case 60: + return "Ninh Thuan"; + case 61: + return "Phu Yen"; + case 62: + return "Quang Binh"; + case 63: + return "Quang Ngai"; + case 64: + return "Quang Tri"; + case 65: + return "Soc Trang"; + case 66: + return "Thua Thien-Hue"; + case 67: + return "Tra Vinh"; + case 68: + return "Tuyen Quang"; + case 69: + return "Vinh Long"; + case 70: + return "Yen Bai"; + case 71: + return "Bac Giang"; + case 72: + return "Bac Kan"; + case 73: + return "Bac Lieu"; + case 74: + return "Bac Ninh"; + case 75: + return "Binh Duong"; + case 76: + return "Binh Phuoc"; + case 77: + return "Ca Mau"; + case 78: + return "Da Nang"; + case 79: + return "Hai Duong"; + case 80: + return "Ha Nam"; + case 81: + return "Hung Yen"; + case 82: + return "Nam Dinh"; + case 83: + return "Phu Tho"; + case 84: + return "Quang Nam"; + case 85: + return "Thai Nguyen"; + case 86: + return "Vinh Phuc"; + case 87: + return "Can Tho"; + case 88: + return "Dac Lak"; + case 89: + return "Lai Chau"; + case 90: + return "Lao Cai"; + case 91: + return "Dak Nong"; + case 92: + return "Dien Bien"; + case 93: + return "Hau Giang"; + default: + return NULL; + } +} + +static const char *get_region_name_VU(int region_code) { + switch (region_code) { + case 5: + return "Ambrym"; + case 6: + return "Aoba"; + case 7: + return "Torba"; + case 8: + return "Efate"; + case 9: + return "Epi"; + case 10: + return "Malakula"; + case 11: + return "Paama"; + case 12: + return "Pentecote"; + case 13: + return "Sanma"; + case 14: + return "Shepherd"; + case 15: + return "Tafea"; + case 16: + return "Malampa"; + case 17: + return "Penama"; + case 18: + return "Shefa"; + default: + return NULL; + } +} + +static const char *get_region_name_WS(int region_code) { + switch (region_code) { + case 2: + return "Aiga-i-le-Tai"; + case 3: + return "Atua"; + case 4: + return "Fa"; + case 5: + return "Gaga"; + case 6: + return "Va"; + case 7: + return "Gagaifomauga"; + case 8: + return "Palauli"; + case 9: + return "Satupa"; + case 10: + return "Tuamasaga"; + case 11: + return "Vaisigano"; + default: + return NULL; + } +} + +static const char *get_region_name_YE(int region_code) { + switch (region_code) { + case 1: + return "Abyan"; + case 2: + return "Adan"; + case 3: + return "Al Mahrah"; + case 4: + return "Hadramawt"; + case 5: + return "Shabwah"; + case 6: + return "Lahij"; + case 7: + return "Al Bayda'"; + case 8: + return "Al Hudaydah"; + case 9: + return "Al Jawf"; + case 10: + return "Al Mahwit"; + case 11: + return "Dhamar"; + case 12: + return "Hajjah"; + case 13: + return "Ibb"; + case 14: + return "Ma'rib"; + case 15: + return "Sa'dah"; + case 16: + return "San'a'"; + case 17: + return "Taizz"; + case 18: + return "Ad Dali"; + case 19: + return "Amran"; + case 20: + return "Al Bayda'"; + case 21: + return "Al Jawf"; + case 22: + return "Hajjah"; + case 23: + return "Ibb"; + case 24: + return "Lahij"; + case 25: + return "Taizz"; + default: + return NULL; + } +} + +static const char *get_region_name_ZA(int region_code) { + switch (region_code) { + case 1: + return "North-Western Province"; + case 2: + return "KwaZulu-Natal"; + case 3: + return "Free State"; + case 5: + return "Eastern Cape"; + case 6: + return "Gauteng"; + case 7: + return "Mpumalanga"; + case 8: + return "Northern Cape"; + case 9: + return "Limpopo"; + case 10: + return "North-West"; + case 11: + return "Western Cape"; + default: + return NULL; + } +} + +static const char *get_region_name_ZM(int region_code) { + switch (region_code) { + case 1: + return "Western"; + case 2: + return "Central"; + case 3: + return "Eastern"; + case 4: + return "Luapula"; + case 5: + return "Northern"; + case 6: + return "North-Western"; + case 7: + return "Southern"; + case 8: + return "Copperbelt"; + case 9: + return "Lusaka"; + default: + return NULL; + } +} + +static const char *get_region_name_ZW(int region_code) { + switch (region_code) { + case 1: + return "Manicaland"; + case 2: + return "Midlands"; + case 3: + return "Mashonaland Central"; + case 4: + return "Mashonaland East"; + case 5: + return "Mashonaland West"; + case 6: + return "Matabeleland North"; + case 7: + return "Matabeleland South"; + case 8: + return "Masvingo"; + case 9: + return "Bulawayo"; + case 10: + return "Harare"; + default: + return NULL; + } +} + +const char *GeoIP_region_name_by_code(const char *country_code, + const char *region_code) { + int region_code2 = -1; + if (region_code == NULL) { + return NULL; + } + + if (((region_code[0] >= 48) && (region_code[0] < (48 + 10))) && + ((region_code[1] >= 48) && (region_code[1] < (48 + 10)))) { + + /* only numbers, that shortens the large switch statements */ + region_code2 = (region_code[0] - 48) * 10 + region_code[1] - 48; + } + + else if ((((region_code[0] >= 65) && (region_code[0] < (65 + 26))) || + ((region_code[0] >= 48) && (region_code[0] < (48 + 10)))) && + (((region_code[1] >= 65) && (region_code[1] < (65 + 26))) || + ((region_code[1] >= 48) && (region_code[1] < (48 + 10))))) { + + region_code2 = + (region_code[0] - 48) * (65 + 26 - 48) + region_code[1] - 48 + 100; + } + + if (region_code2 == -1) { + return NULL; + } + + if (strcmp(country_code, "AD") == 0) { + return get_region_name_AD(region_code2); + } + if (strcmp(country_code, "AE") == 0) { + return get_region_name_AE(region_code2); + } + if (strcmp(country_code, "AF") == 0) { + return get_region_name_AF(region_code2); + } + if (strcmp(country_code, "AG") == 0) { + return get_region_name_AG(region_code2); + } + if (strcmp(country_code, "AL") == 0) { + return get_region_name_AL(region_code2); + } + if (strcmp(country_code, "AM") == 0) { + return get_region_name_AM(region_code2); + } + if (strcmp(country_code, "AO") == 0) { + return get_region_name_AO(region_code2); + } + if (strcmp(country_code, "AR") == 0) { + return get_region_name_AR(region_code2); + } + if (strcmp(country_code, "AT") == 0) { + return get_region_name_AT(region_code2); + } + if (strcmp(country_code, "AU") == 0) { + return get_region_name_AU(region_code2); + } + if (strcmp(country_code, "AZ") == 0) { + return get_region_name_AZ(region_code2); + } + if (strcmp(country_code, "BA") == 0) { + return get_region_name_BA(region_code2); + } + if (strcmp(country_code, "BB") == 0) { + return get_region_name_BB(region_code2); + } + if (strcmp(country_code, "BD") == 0) { + return get_region_name_BD(region_code2); + } + if (strcmp(country_code, "BE") == 0) { + return get_region_name_BE(region_code2); + } + if (strcmp(country_code, "BF") == 0) { + return get_region_name_BF(region_code2); + } + if (strcmp(country_code, "BG") == 0) { + return get_region_name_BG(region_code2); + } + if (strcmp(country_code, "BH") == 0) { + return get_region_name_BH(region_code2); + } + if (strcmp(country_code, "BI") == 0) { + return get_region_name_BI(region_code2); + } + if (strcmp(country_code, "BJ") == 0) { + return get_region_name_BJ(region_code2); + } + if (strcmp(country_code, "BM") == 0) { + return get_region_name_BM(region_code2); + } + if (strcmp(country_code, "BN") == 0) { + return get_region_name_BN(region_code2); + } + if (strcmp(country_code, "BO") == 0) { + return get_region_name_BO(region_code2); + } + if (strcmp(country_code, "BR") == 0) { + return get_region_name_BR(region_code2); + } + if (strcmp(country_code, "BS") == 0) { + return get_region_name_BS(region_code2); + } + if (strcmp(country_code, "BT") == 0) { + return get_region_name_BT(region_code2); + } + if (strcmp(country_code, "BW") == 0) { + return get_region_name_BW(region_code2); + } + if (strcmp(country_code, "BY") == 0) { + return get_region_name_BY(region_code2); + } + if (strcmp(country_code, "BZ") == 0) { + return get_region_name_BZ(region_code2); + } + if (strcmp(country_code, "CA") == 0) { + return get_region_name_CA(region_code2); + } + if (strcmp(country_code, "CD") == 0) { + return get_region_name_CD(region_code2); + } + if (strcmp(country_code, "CF") == 0) { + return get_region_name_CF(region_code2); + } + if (strcmp(country_code, "CG") == 0) { + return get_region_name_CG(region_code2); + } + if (strcmp(country_code, "CH") == 0) { + return get_region_name_CH(region_code2); + } + if (strcmp(country_code, "CI") == 0) { + return get_region_name_CI(region_code2); + } + if (strcmp(country_code, "CL") == 0) { + return get_region_name_CL(region_code2); + } + if (strcmp(country_code, "CM") == 0) { + return get_region_name_CM(region_code2); + } + if (strcmp(country_code, "CN") == 0) { + return get_region_name_CN(region_code2); + } + if (strcmp(country_code, "CO") == 0) { + return get_region_name_CO(region_code2); + } + if (strcmp(country_code, "CR") == 0) { + return get_region_name_CR(region_code2); + } + if (strcmp(country_code, "CU") == 0) { + return get_region_name_CU(region_code2); + } + if (strcmp(country_code, "CV") == 0) { + return get_region_name_CV(region_code2); + } + if (strcmp(country_code, "CY") == 0) { + return get_region_name_CY(region_code2); + } + if (strcmp(country_code, "CZ") == 0) { + return get_region_name_CZ(region_code2); + } + if (strcmp(country_code, "DE") == 0) { + return get_region_name_DE(region_code2); + } + if (strcmp(country_code, "DJ") == 0) { + return get_region_name_DJ(region_code2); + } + if (strcmp(country_code, "DK") == 0) { + return get_region_name_DK(region_code2); + } + if (strcmp(country_code, "DM") == 0) { + return get_region_name_DM(region_code2); + } + if (strcmp(country_code, "DO") == 0) { + return get_region_name_DO(region_code2); + } + if (strcmp(country_code, "DZ") == 0) { + return get_region_name_DZ(region_code2); + } + if (strcmp(country_code, "EC") == 0) { + return get_region_name_EC(region_code2); + } + if (strcmp(country_code, "EE") == 0) { + return get_region_name_EE(region_code2); + } + if (strcmp(country_code, "EG") == 0) { + return get_region_name_EG(region_code2); + } + if (strcmp(country_code, "ER") == 0) { + return get_region_name_ER(region_code2); + } + if (strcmp(country_code, "ES") == 0) { + return get_region_name_ES(region_code2); + } + if (strcmp(country_code, "ET") == 0) { + return get_region_name_ET(region_code2); + } + if (strcmp(country_code, "FI") == 0) { + return get_region_name_FI(region_code2); + } + if (strcmp(country_code, "FJ") == 0) { + return get_region_name_FJ(region_code2); + } + if (strcmp(country_code, "FM") == 0) { + return get_region_name_FM(region_code2); + } + if (strcmp(country_code, "FR") == 0) { + return get_region_name_FR(region_code2); + } + if (strcmp(country_code, "GA") == 0) { + return get_region_name_GA(region_code2); + } + if (strcmp(country_code, "GB") == 0) { + return get_region_name_GB(region_code2); + } + if (strcmp(country_code, "GD") == 0) { + return get_region_name_GD(region_code2); + } + if (strcmp(country_code, "GE") == 0) { + return get_region_name_GE(region_code2); + } + if (strcmp(country_code, "GH") == 0) { + return get_region_name_GH(region_code2); + } + if (strcmp(country_code, "GL") == 0) { + return get_region_name_GL(region_code2); + } + if (strcmp(country_code, "GM") == 0) { + return get_region_name_GM(region_code2); + } + if (strcmp(country_code, "GN") == 0) { + return get_region_name_GN(region_code2); + } + if (strcmp(country_code, "GQ") == 0) { + return get_region_name_GQ(region_code2); + } + if (strcmp(country_code, "GR") == 0) { + return get_region_name_GR(region_code2); + } + if (strcmp(country_code, "GT") == 0) { + return get_region_name_GT(region_code2); + } + if (strcmp(country_code, "GW") == 0) { + return get_region_name_GW(region_code2); + } + if (strcmp(country_code, "GY") == 0) { + return get_region_name_GY(region_code2); + } + if (strcmp(country_code, "HN") == 0) { + return get_region_name_HN(region_code2); + } + if (strcmp(country_code, "HR") == 0) { + return get_region_name_HR(region_code2); + } + if (strcmp(country_code, "HT") == 0) { + return get_region_name_HT(region_code2); + } + if (strcmp(country_code, "HU") == 0) { + return get_region_name_HU(region_code2); + } + if (strcmp(country_code, "ID") == 0) { + return get_region_name_ID(region_code2); + } + if (strcmp(country_code, "IE") == 0) { + return get_region_name_IE(region_code2); + } + if (strcmp(country_code, "IL") == 0) { + return get_region_name_IL(region_code2); + } + if (strcmp(country_code, "IN") == 0) { + return get_region_name_IN(region_code2); + } + if (strcmp(country_code, "IQ") == 0) { + return get_region_name_IQ(region_code2); + } + if (strcmp(country_code, "IR") == 0) { + return get_region_name_IR(region_code2); + } + if (strcmp(country_code, "IS") == 0) { + return get_region_name_IS(region_code2); + } + if (strcmp(country_code, "IT") == 0) { + return get_region_name_IT(region_code2); + } + if (strcmp(country_code, "JM") == 0) { + return get_region_name_JM(region_code2); + } + if (strcmp(country_code, "JO") == 0) { + return get_region_name_JO(region_code2); + } + if (strcmp(country_code, "JP") == 0) { + return get_region_name_JP(region_code2); + } + if (strcmp(country_code, "KE") == 0) { + return get_region_name_KE(region_code2); + } + if (strcmp(country_code, "KG") == 0) { + return get_region_name_KG(region_code2); + } + if (strcmp(country_code, "KH") == 0) { + return get_region_name_KH(region_code2); + } + if (strcmp(country_code, "KI") == 0) { + return get_region_name_KI(region_code2); + } + if (strcmp(country_code, "KM") == 0) { + return get_region_name_KM(region_code2); + } + if (strcmp(country_code, "KN") == 0) { + return get_region_name_KN(region_code2); + } + if (strcmp(country_code, "KP") == 0) { + return get_region_name_KP(region_code2); + } + if (strcmp(country_code, "KR") == 0) { + return get_region_name_KR(region_code2); + } + if (strcmp(country_code, "KW") == 0) { + return get_region_name_KW(region_code2); + } + if (strcmp(country_code, "KY") == 0) { + return get_region_name_KY(region_code2); + } + if (strcmp(country_code, "KZ") == 0) { + return get_region_name_KZ(region_code2); + } + if (strcmp(country_code, "LA") == 0) { + return get_region_name_LA(region_code2); + } + if (strcmp(country_code, "LB") == 0) { + return get_region_name_LB(region_code2); + } + if (strcmp(country_code, "LC") == 0) { + return get_region_name_LC(region_code2); + } + if (strcmp(country_code, "LI") == 0) { + return get_region_name_LI(region_code2); + } + if (strcmp(country_code, "LK") == 0) { + return get_region_name_LK(region_code2); + } + if (strcmp(country_code, "LR") == 0) { + return get_region_name_LR(region_code2); + } + if (strcmp(country_code, "LS") == 0) { + return get_region_name_LS(region_code2); + } + if (strcmp(country_code, "LT") == 0) { + return get_region_name_LT(region_code2); + } + if (strcmp(country_code, "LU") == 0) { + return get_region_name_LU(region_code2); + } + if (strcmp(country_code, "LV") == 0) { + return get_region_name_LV(region_code2); + } + if (strcmp(country_code, "LY") == 0) { + return get_region_name_LY(region_code2); + } + if (strcmp(country_code, "MA") == 0) { + return get_region_name_MA(region_code2); + } + if (strcmp(country_code, "MC") == 0) { + return get_region_name_MC(region_code2); + } + if (strcmp(country_code, "MD") == 0) { + return get_region_name_MD(region_code2); + } + if (strcmp(country_code, "MG") == 0) { + return get_region_name_MG(region_code2); + } + if (strcmp(country_code, "MK") == 0) { + return get_region_name_MK(region_code2); + } + if (strcmp(country_code, "ML") == 0) { + return get_region_name_ML(region_code2); + } + if (strcmp(country_code, "MM") == 0) { + return get_region_name_MM(region_code2); + } + if (strcmp(country_code, "MN") == 0) { + return get_region_name_MN(region_code2); + } + if (strcmp(country_code, "MO") == 0) { + return get_region_name_MO(region_code2); + } + if (strcmp(country_code, "MR") == 0) { + return get_region_name_MR(region_code2); + } + if (strcmp(country_code, "MS") == 0) { + return get_region_name_MS(region_code2); + } + if (strcmp(country_code, "MU") == 0) { + return get_region_name_MU(region_code2); + } + if (strcmp(country_code, "MV") == 0) { + return get_region_name_MV(region_code2); + } + if (strcmp(country_code, "MW") == 0) { + return get_region_name_MW(region_code2); + } + if (strcmp(country_code, "MX") == 0) { + return get_region_name_MX(region_code2); + } + if (strcmp(country_code, "MY") == 0) { + return get_region_name_MY(region_code2); + } + if (strcmp(country_code, "MZ") == 0) { + return get_region_name_MZ(region_code2); + } + if (strcmp(country_code, "NA") == 0) { + return get_region_name_NA(region_code2); + } + if (strcmp(country_code, "NE") == 0) { + return get_region_name_NE(region_code2); + } + if (strcmp(country_code, "NG") == 0) { + return get_region_name_NG(region_code2); + } + if (strcmp(country_code, "NI") == 0) { + return get_region_name_NI(region_code2); + } + if (strcmp(country_code, "NL") == 0) { + return get_region_name_NL(region_code2); + } + if (strcmp(country_code, "NO") == 0) { + return get_region_name_NO(region_code2); + } + if (strcmp(country_code, "NP") == 0) { + return get_region_name_NP(region_code2); + } + if (strcmp(country_code, "NR") == 0) { + return get_region_name_NR(region_code2); + } + if (strcmp(country_code, "NZ") == 0) { + return get_region_name_NZ(region_code2); + } + if (strcmp(country_code, "OM") == 0) { + return get_region_name_OM(region_code2); + } + if (strcmp(country_code, "PA") == 0) { + return get_region_name_PA(region_code2); + } + if (strcmp(country_code, "PE") == 0) { + return get_region_name_PE(region_code2); + } + if (strcmp(country_code, "PG") == 0) { + return get_region_name_PG(region_code2); + } + if (strcmp(country_code, "PH") == 0) { + return get_region_name_PH(region_code2); + } + if (strcmp(country_code, "PK") == 0) { + return get_region_name_PK(region_code2); + } + if (strcmp(country_code, "PL") == 0) { + return get_region_name_PL(region_code2); + } + if (strcmp(country_code, "PS") == 0) { + return get_region_name_PS(region_code2); + } + if (strcmp(country_code, "PT") == 0) { + return get_region_name_PT(region_code2); + } + if (strcmp(country_code, "PY") == 0) { + return get_region_name_PY(region_code2); + } + if (strcmp(country_code, "QA") == 0) { + return get_region_name_QA(region_code2); + } + if (strcmp(country_code, "RO") == 0) { + return get_region_name_RO(region_code2); + } + if (strcmp(country_code, "RS") == 0) { + return get_region_name_RS(region_code2); + } + if (strcmp(country_code, "RU") == 0) { + return get_region_name_RU(region_code2); + } + if (strcmp(country_code, "RW") == 0) { + return get_region_name_RW(region_code2); + } + if (strcmp(country_code, "SA") == 0) { + return get_region_name_SA(region_code2); + } + if (strcmp(country_code, "SB") == 0) { + return get_region_name_SB(region_code2); + } + if (strcmp(country_code, "SC") == 0) { + return get_region_name_SC(region_code2); + } + if (strcmp(country_code, "SD") == 0) { + return get_region_name_SD(region_code2); + } + if (strcmp(country_code, "SE") == 0) { + return get_region_name_SE(region_code2); + } + if (strcmp(country_code, "SH") == 0) { + return get_region_name_SH(region_code2); + } + if (strcmp(country_code, "SI") == 0) { + return get_region_name_SI(region_code2); + } + if (strcmp(country_code, "SK") == 0) { + return get_region_name_SK(region_code2); + } + if (strcmp(country_code, "SL") == 0) { + return get_region_name_SL(region_code2); + } + if (strcmp(country_code, "SM") == 0) { + return get_region_name_SM(region_code2); + } + if (strcmp(country_code, "SN") == 0) { + return get_region_name_SN(region_code2); + } + if (strcmp(country_code, "SO") == 0) { + return get_region_name_SO(region_code2); + } + if (strcmp(country_code, "SR") == 0) { + return get_region_name_SR(region_code2); + } + if (strcmp(country_code, "SS") == 0) { + return get_region_name_SS(region_code2); + } + if (strcmp(country_code, "ST") == 0) { + return get_region_name_ST(region_code2); + } + if (strcmp(country_code, "SV") == 0) { + return get_region_name_SV(region_code2); + } + if (strcmp(country_code, "SY") == 0) { + return get_region_name_SY(region_code2); + } + if (strcmp(country_code, "SZ") == 0) { + return get_region_name_SZ(region_code2); + } + if (strcmp(country_code, "TD") == 0) { + return get_region_name_TD(region_code2); + } + if (strcmp(country_code, "TG") == 0) { + return get_region_name_TG(region_code2); + } + if (strcmp(country_code, "TH") == 0) { + return get_region_name_TH(region_code2); + } + if (strcmp(country_code, "TJ") == 0) { + return get_region_name_TJ(region_code2); + } + if (strcmp(country_code, "TL") == 0) { + return get_region_name_TL(region_code2); + } + if (strcmp(country_code, "TM") == 0) { + return get_region_name_TM(region_code2); + } + if (strcmp(country_code, "TN") == 0) { + return get_region_name_TN(region_code2); + } + if (strcmp(country_code, "TO") == 0) { + return get_region_name_TO(region_code2); + } + if (strcmp(country_code, "TR") == 0) { + return get_region_name_TR(region_code2); + } + if (strcmp(country_code, "TT") == 0) { + return get_region_name_TT(region_code2); + } + if (strcmp(country_code, "TW") == 0) { + return get_region_name_TW(region_code2); + } + if (strcmp(country_code, "TZ") == 0) { + return get_region_name_TZ(region_code2); + } + if (strcmp(country_code, "UA") == 0) { + return get_region_name_UA(region_code2); + } + if (strcmp(country_code, "UG") == 0) { + return get_region_name_UG(region_code2); + } + if (strcmp(country_code, "US") == 0) { + return get_region_name_US(region_code2); + } + if (strcmp(country_code, "UY") == 0) { + return get_region_name_UY(region_code2); + } + if (strcmp(country_code, "UZ") == 0) { + return get_region_name_UZ(region_code2); + } + if (strcmp(country_code, "VC") == 0) { + return get_region_name_VC(region_code2); + } + if (strcmp(country_code, "VE") == 0) { + return get_region_name_VE(region_code2); + } + if (strcmp(country_code, "VN") == 0) { + return get_region_name_VN(region_code2); + } + if (strcmp(country_code, "VU") == 0) { + return get_region_name_VU(region_code2); + } + if (strcmp(country_code, "WS") == 0) { + return get_region_name_WS(region_code2); + } + if (strcmp(country_code, "YE") == 0) { + return get_region_name_YE(region_code2); + } + if (strcmp(country_code, "ZA") == 0) { + return get_region_name_ZA(region_code2); + } + if (strcmp(country_code, "ZM") == 0) { + return get_region_name_ZM(region_code2); + } + if (strcmp(country_code, "ZW") == 0) { + return get_region_name_ZW(region_code2); + } + return NULL; +} diff --git a/libGeoIP/timeZone.c b/libGeoIP/timeZone.c new file mode 100644 index 0000000..cc30619 --- /dev/null +++ b/libGeoIP/timeZone.c @@ -0,0 +1,1775 @@ +#include <string.h> +const char *GeoIP_time_zone_by_country_and_region(const char *country, + const char *region) { + const char *timezone = NULL; + if (country == NULL) { + return NULL; + } + if (region == NULL) { + region = ""; + } + if (strcmp(country, "AD") == 0) { + return "Europe/Andorra"; + } + if (strcmp(country, "AE") == 0) { + return "Asia/Dubai"; + } + if (strcmp(country, "AF") == 0) { + return "Asia/Kabul"; + } + if (strcmp(country, "AG") == 0) { + return "America/Antigua"; + } + if (strcmp(country, "AI") == 0) { + return "America/Anguilla"; + } + if (strcmp(country, "AL") == 0) { + return "Europe/Tirane"; + } + if (strcmp(country, "AM") == 0) { + return "Asia/Yerevan"; + } + if (strcmp(country, "AN") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "AO") == 0) { + return "Africa/Luanda"; + } + if (strcmp(country, "AQ") == 0) { + return "Antarctica/South_Pole"; + } + if (strcmp(country, "AR") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "02") == 0) { + return "America/Argentina/Catamarca"; + } else if (strcmp(region, "03") == 0) { + return "America/Argentina/Tucuman"; + } else if (strcmp(region, "04") == 0) { + return "America/Argentina/Rio_Gallegos"; + } else if (strcmp(region, "05") == 0) { + return "America/Argentina/Cordoba"; + } else if (strcmp(region, "06") == 0) { + return "America/Argentina/Tucuman"; + } else if (strcmp(region, "07") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "08") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "09") == 0) { + return "America/Argentina/Tucuman"; + } else if (strcmp(region, "10") == 0) { + return "America/Argentina/Jujuy"; + } else if (strcmp(region, "11") == 0) { + return "America/Argentina/San_Luis"; + } else if (strcmp(region, "12") == 0) { + return "America/Argentina/La_Rioja"; + } else if (strcmp(region, "13") == 0) { + return "America/Argentina/Mendoza"; + } else if (strcmp(region, "14") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "15") == 0) { + return "America/Argentina/San_Luis"; + } else if (strcmp(region, "16") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "17") == 0) { + return "America/Argentina/Salta"; + } else if (strcmp(region, "18") == 0) { + return "America/Argentina/San_Juan"; + } else if (strcmp(region, "19") == 0) { + return "America/Argentina/San_Luis"; + } else if (strcmp(region, "20") == 0) { + return "America/Argentina/Rio_Gallegos"; + } else if (strcmp(region, "21") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "22") == 0) { + return "America/Argentina/Catamarca"; + } else if (strcmp(region, "23") == 0) { + return "America/Argentina/Ushuaia"; + } else if (strcmp(region, "24") == 0) { + return "America/Argentina/Tucuman"; + } else { + return NULL; + } + } + if (strcmp(country, "AS") == 0) { + return "Pacific/Pago_Pago"; + } + if (strcmp(country, "AT") == 0) { + return "Europe/Vienna"; + } + if (strcmp(country, "AU") == 0) { + if (strcmp(region, "01") == 0) { + return "Australia/Sydney"; + } else if (strcmp(region, "02") == 0) { + return "Australia/Sydney"; + } else if (strcmp(region, "03") == 0) { + return "Australia/Darwin"; + } else if (strcmp(region, "04") == 0) { + return "Australia/Brisbane"; + } else if (strcmp(region, "05") == 0) { + return "Australia/Adelaide"; + } else if (strcmp(region, "06") == 0) { + return "Australia/Hobart"; + } else if (strcmp(region, "07") == 0) { + return "Australia/Melbourne"; + } else if (strcmp(region, "08") == 0) { + return "Australia/Perth"; + } else { + return NULL; + } + } + if (strcmp(country, "AW") == 0) { + return "America/Aruba"; + } + if (strcmp(country, "AX") == 0) { + return "Europe/Mariehamn"; + } + if (strcmp(country, "AZ") == 0) { + return "Asia/Baku"; + } + if (strcmp(country, "BA") == 0) { + return "Europe/Sarajevo"; + } + if (strcmp(country, "BB") == 0) { + return "America/Barbados"; + } + if (strcmp(country, "BD") == 0) { + return "Asia/Dhaka"; + } + if (strcmp(country, "BE") == 0) { + return "Europe/Brussels"; + } + if (strcmp(country, "BF") == 0) { + return "Africa/Ouagadougou"; + } + if (strcmp(country, "BG") == 0) { + return "Europe/Sofia"; + } + if (strcmp(country, "BH") == 0) { + return "Asia/Bahrain"; + } + if (strcmp(country, "BI") == 0) { + return "Africa/Bujumbura"; + } + if (strcmp(country, "BJ") == 0) { + return "Africa/Porto-Novo"; + } + if (strcmp(country, "BL") == 0) { + return "America/St_Barthelemy"; + } + if (strcmp(country, "BM") == 0) { + return "Atlantic/Bermuda"; + } + if (strcmp(country, "BN") == 0) { + return "Asia/Brunei"; + } + if (strcmp(country, "BO") == 0) { + return "America/La_Paz"; + } + if (strcmp(country, "BQ") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "BR") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Rio_Branco"; + } else if (strcmp(region, "02") == 0) { + return "America/Maceio"; + } else if (strcmp(region, "03") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "04") == 0) { + return "America/Manaus"; + } else if (strcmp(region, "05") == 0) { + return "America/Bahia"; + } else if (strcmp(region, "06") == 0) { + return "America/Fortaleza"; + } else if (strcmp(region, "07") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "08") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "11") == 0) { + return "America/Campo_Grande"; + } else if (strcmp(region, "13") == 0) { + return "America/Belem"; + } else if (strcmp(region, "14") == 0) { + return "America/Cuiaba"; + } else if (strcmp(region, "15") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "16") == 0) { + return "America/Belem"; + } else if (strcmp(region, "17") == 0) { + return "America/Recife"; + } else if (strcmp(region, "18") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "20") == 0) { + return "America/Fortaleza"; + } else if (strcmp(region, "21") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "22") == 0) { + return "America/Recife"; + } else if (strcmp(region, "23") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "24") == 0) { + return "America/Porto_Velho"; + } else if (strcmp(region, "25") == 0) { + return "America/Boa_Vista"; + } else if (strcmp(region, "26") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "27") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "28") == 0) { + return "America/Maceio"; + } else if (strcmp(region, "29") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "30") == 0) { + return "America/Recife"; + } else if (strcmp(region, "31") == 0) { + return "America/Araguaina"; + } else { + return NULL; + } + } + if (strcmp(country, "BS") == 0) { + return "America/Nassau"; + } + if (strcmp(country, "BT") == 0) { + return "Asia/Thimphu"; + } + if (strcmp(country, "BV") == 0) { + return "Antarctica/Syowa"; + } + if (strcmp(country, "BW") == 0) { + return "Africa/Gaborone"; + } + if (strcmp(country, "BY") == 0) { + return "Europe/Minsk"; + } + if (strcmp(country, "BZ") == 0) { + return "America/Belize"; + } + if (strcmp(country, "CA") == 0) { + if (strcmp(region, "AB") == 0) { + return "America/Edmonton"; + } else if (strcmp(region, "BC") == 0) { + return "America/Vancouver"; + } else if (strcmp(region, "MB") == 0) { + return "America/Winnipeg"; + } else if (strcmp(region, "NB") == 0) { + return "America/Halifax"; + } else if (strcmp(region, "NL") == 0) { + return "America/St_Johns"; + } else if (strcmp(region, "NS") == 0) { + return "America/Halifax"; + } else if (strcmp(region, "NT") == 0) { + return "America/Yellowknife"; + } else if (strcmp(region, "NU") == 0) { + return "America/Rankin_Inlet"; + } else if (strcmp(region, "ON") == 0) { + return "America/Toronto"; + } else if (strcmp(region, "PE") == 0) { + return "America/Halifax"; + } else if (strcmp(region, "QC") == 0) { + return "America/Montreal"; + } else if (strcmp(region, "SK") == 0) { + return "America/Regina"; + } else if (strcmp(region, "YT") == 0) { + return "America/Whitehorse"; + } else { + return NULL; + } + } + if (strcmp(country, "CC") == 0) { + return "Indian/Cocos"; + } + if (strcmp(country, "CD") == 0) { + if (strcmp(region, "01") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "02") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "03") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "04") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "05") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "06") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "07") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "08") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "09") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "10") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "11") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "12") == 0) { + return "Africa/Lubumbashi"; + } else { + return NULL; + } + } + if (strcmp(country, "CF") == 0) { + return "Africa/Bangui"; + } + if (strcmp(country, "CG") == 0) { + return "Africa/Brazzaville"; + } + if (strcmp(country, "CH") == 0) { + return "Europe/Zurich"; + } + if (strcmp(country, "CI") == 0) { + return "Africa/Abidjan"; + } + if (strcmp(country, "CK") == 0) { + return "Pacific/Rarotonga"; + } + if (strcmp(country, "CL") == 0) { + return "America/Santiago"; + } + if (strcmp(country, "CM") == 0) { + return "Africa/Lagos"; + } + if (strcmp(country, "CN") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Urumqi"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "18") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "19") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "21") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "22") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "23") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "24") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "25") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "26") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "28") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "29") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "30") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "31") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "32") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "33") == 0) { + return "Asia/Chongqing"; + } else { + return NULL; + } + } + if (strcmp(country, "CO") == 0) { + return "America/Bogota"; + } + if (strcmp(country, "CR") == 0) { + return "America/Costa_Rica"; + } + if (strcmp(country, "CU") == 0) { + return "America/Havana"; + } + if (strcmp(country, "CV") == 0) { + return "Atlantic/Cape_Verde"; + } + if (strcmp(country, "CW") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "CX") == 0) { + return "Indian/Christmas"; + } + if (strcmp(country, "CY") == 0) { + return "Asia/Nicosia"; + } + if (strcmp(country, "CZ") == 0) { + return "Europe/Prague"; + } + if (strcmp(country, "DE") == 0) { + return "Europe/Berlin"; + } + if (strcmp(country, "DJ") == 0) { + return "Africa/Djibouti"; + } + if (strcmp(country, "DK") == 0) { + return "Europe/Copenhagen"; + } + if (strcmp(country, "DM") == 0) { + return "America/Dominica"; + } + if (strcmp(country, "DO") == 0) { + return "America/Santo_Domingo"; + } + if (strcmp(country, "DZ") == 0) { + return "Africa/Algiers"; + } + if (strcmp(country, "EC") == 0) { + if (strcmp(region, "01") == 0) { + return "Pacific/Galapagos"; + } else if (strcmp(region, "02") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "03") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "04") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "05") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "06") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "07") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "08") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "09") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "10") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "11") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "12") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "13") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "14") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "15") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "17") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "18") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "19") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "20") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "22") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "24") == 0) { + return "America/Guayaquil"; + } else { + return NULL; + } + } + if (strcmp(country, "EE") == 0) { + return "Europe/Tallinn"; + } + if (strcmp(country, "EG") == 0) { + return "Africa/Cairo"; + } + if (strcmp(country, "EH") == 0) { + return "Africa/El_Aaiun"; + } + if (strcmp(country, "ER") == 0) { + return "Africa/Asmara"; + } + if (strcmp(country, "ES") == 0) { + if (strcmp(region, "07") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "27") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "29") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "31") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "32") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "34") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "39") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "51") == 0) { + return "Africa/Ceuta"; + } else if (strcmp(region, "52") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "53") == 0) { + return "Atlantic/Canary"; + } else if (strcmp(region, "54") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "55") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "56") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "57") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "58") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "59") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "60") == 0) { + return "Europe/Madrid"; + } else { + return NULL; + } + } + if (strcmp(country, "ET") == 0) { + return "Africa/Addis_Ababa"; + } + if (strcmp(country, "FI") == 0) { + return "Europe/Helsinki"; + } + if (strcmp(country, "FJ") == 0) { + return "Pacific/Fiji"; + } + if (strcmp(country, "FK") == 0) { + return "Atlantic/Stanley"; + } + if (strcmp(country, "FM") == 0) { + return "Pacific/Pohnpei"; + } + if (strcmp(country, "FO") == 0) { + return "Atlantic/Faroe"; + } + if (strcmp(country, "FR") == 0) { + return "Europe/Paris"; + } + if (strcmp(country, "FX") == 0) { + return "Europe/Paris"; + } + if (strcmp(country, "GA") == 0) { + return "Africa/Libreville"; + } + if (strcmp(country, "GB") == 0) { + return "Europe/London"; + } + if (strcmp(country, "GD") == 0) { + return "America/Grenada"; + } + if (strcmp(country, "GE") == 0) { + return "Asia/Tbilisi"; + } + if (strcmp(country, "GF") == 0) { + return "America/Cayenne"; + } + if (strcmp(country, "GG") == 0) { + return "Europe/Guernsey"; + } + if (strcmp(country, "GH") == 0) { + return "Africa/Accra"; + } + if (strcmp(country, "GI") == 0) { + return "Europe/Gibraltar"; + } + if (strcmp(country, "GL") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Thule"; + } else if (strcmp(region, "02") == 0) { + return "America/Godthab"; + } else if (strcmp(region, "03") == 0) { + return "America/Godthab"; + } else { + return NULL; + } + } + if (strcmp(country, "GM") == 0) { + return "Africa/Banjul"; + } + if (strcmp(country, "GN") == 0) { + return "Africa/Conakry"; + } + if (strcmp(country, "GP") == 0) { + return "America/Guadeloupe"; + } + if (strcmp(country, "GQ") == 0) { + return "Africa/Malabo"; + } + if (strcmp(country, "GR") == 0) { + return "Europe/Athens"; + } + if (strcmp(country, "GS") == 0) { + return "Atlantic/South_Georgia"; + } + if (strcmp(country, "GT") == 0) { + return "America/Guatemala"; + } + if (strcmp(country, "GU") == 0) { + return "Pacific/Guam"; + } + if (strcmp(country, "GW") == 0) { + return "Africa/Bissau"; + } + if (strcmp(country, "GY") == 0) { + return "America/Guyana"; + } + if (strcmp(country, "HK") == 0) { + return "Asia/Hong_Kong"; + } + if (strcmp(country, "HN") == 0) { + return "America/Tegucigalpa"; + } + if (strcmp(country, "HR") == 0) { + return "Europe/Zagreb"; + } + if (strcmp(country, "HT") == 0) { + return "America/Port-au-Prince"; + } + if (strcmp(country, "HU") == 0) { + return "Europe/Budapest"; + } + if (strcmp(country, "ID") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "17") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "18") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "19") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "21") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "22") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "23") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "24") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "25") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "26") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "28") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "29") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "30") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "31") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "32") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "33") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "34") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "35") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "36") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "37") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "38") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "39") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "40") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "41") == 0) { + return "Asia/Makassar"; + } else { + return NULL; + } + } + if (strcmp(country, "IE") == 0) { + return "Europe/Dublin"; + } + if (strcmp(country, "IL") == 0) { + return "Asia/Jerusalem"; + } + if (strcmp(country, "IM") == 0) { + return "Europe/Isle_of_Man"; + } + if (strcmp(country, "IN") == 0) { + return "Asia/Kolkata"; + } + if (strcmp(country, "IO") == 0) { + return "Indian/Chagos"; + } + if (strcmp(country, "IQ") == 0) { + return "Asia/Baghdad"; + } + if (strcmp(country, "IR") == 0) { + return "Asia/Tehran"; + } + if (strcmp(country, "IS") == 0) { + return "Atlantic/Reykjavik"; + } + if (strcmp(country, "IT") == 0) { + return "Europe/Rome"; + } + if (strcmp(country, "JE") == 0) { + return "Europe/Jersey"; + } + if (strcmp(country, "JM") == 0) { + return "America/Jamaica"; + } + if (strcmp(country, "JO") == 0) { + return "Asia/Amman"; + } + if (strcmp(country, "JP") == 0) { + return "Asia/Tokyo"; + } + if (strcmp(country, "KE") == 0) { + return "Africa/Nairobi"; + } + if (strcmp(country, "KG") == 0) { + return "Asia/Bishkek"; + } + if (strcmp(country, "KH") == 0) { + return "Asia/Phnom_Penh"; + } + if (strcmp(country, "KI") == 0) { + return "Pacific/Tarawa"; + } + if (strcmp(country, "KM") == 0) { + return "Indian/Comoro"; + } + if (strcmp(country, "KN") == 0) { + return "America/St_Kitts"; + } + if (strcmp(country, "KP") == 0) { + return "Asia/Pyongyang"; + } + if (strcmp(country, "KR") == 0) { + return "Asia/Seoul"; + } + if (strcmp(country, "KW") == 0) { + return "Asia/Kuwait"; + } + if (strcmp(country, "KY") == 0) { + return "America/Cayman"; + } + if (strcmp(country, "KZ") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Aqtobe"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Aqtau"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Oral"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Aqtau"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Aqtobe"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Aqtobe"; + } else if (strcmp(region, "17") == 0) { + return "Asia/Almaty"; + } else { + return NULL; + } + } + if (strcmp(country, "LA") == 0) { + return "Asia/Vientiane"; + } + if (strcmp(country, "LB") == 0) { + return "Asia/Beirut"; + } + if (strcmp(country, "LC") == 0) { + return "America/St_Lucia"; + } + if (strcmp(country, "LI") == 0) { + return "Europe/Vaduz"; + } + if (strcmp(country, "LK") == 0) { + return "Asia/Colombo"; + } + if (strcmp(country, "LR") == 0) { + return "Africa/Monrovia"; + } + if (strcmp(country, "LS") == 0) { + return "Africa/Maseru"; + } + if (strcmp(country, "LT") == 0) { + return "Europe/Vilnius"; + } + if (strcmp(country, "LU") == 0) { + return "Europe/Luxembourg"; + } + if (strcmp(country, "LV") == 0) { + return "Europe/Riga"; + } + if (strcmp(country, "LY") == 0) { + return "Africa/Tripoli"; + } + if (strcmp(country, "MA") == 0) { + return "Africa/Casablanca"; + } + if (strcmp(country, "MC") == 0) { + return "Europe/Monaco"; + } + if (strcmp(country, "MD") == 0) { + return "Europe/Chisinau"; + } + if (strcmp(country, "ME") == 0) { + return "Europe/Podgorica"; + } + if (strcmp(country, "MF") == 0) { + return "America/Marigot"; + } + if (strcmp(country, "MG") == 0) { + return "Indian/Antananarivo"; + } + if (strcmp(country, "MH") == 0) { + return "Pacific/Kwajalein"; + } + if (strcmp(country, "MK") == 0) { + return "Europe/Skopje"; + } + if (strcmp(country, "ML") == 0) { + return "Africa/Bamako"; + } + if (strcmp(country, "MM") == 0) { + return "Asia/Rangoon"; + } + if (strcmp(country, "MN") == 0) { + if (strcmp(region, "06") == 0) { + return "Asia/Choibalsan"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Ulaanbaatar"; + } else if (strcmp(region, "17") == 0) { + return "Asia/Choibalsan"; + } else if (strcmp(region, "19") == 0) { + return "Asia/Hovd"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Ulaanbaatar"; + } else if (strcmp(region, "21") == 0) { + return "Asia/Ulaanbaatar"; + } else if (strcmp(region, "25") == 0) { + return "Asia/Ulaanbaatar"; + } else { + return NULL; + } + } + if (strcmp(country, "MO") == 0) { + return "Asia/Macau"; + } + if (strcmp(country, "MP") == 0) { + return "Pacific/Saipan"; + } + if (strcmp(country, "MQ") == 0) { + return "America/Martinique"; + } + if (strcmp(country, "MR") == 0) { + return "Africa/Nouakchott"; + } + if (strcmp(country, "MS") == 0) { + return "America/Montserrat"; + } + if (strcmp(country, "MT") == 0) { + return "Europe/Malta"; + } + if (strcmp(country, "MU") == 0) { + return "Indian/Mauritius"; + } + if (strcmp(country, "MV") == 0) { + return "Indian/Maldives"; + } + if (strcmp(country, "MW") == 0) { + return "Africa/Blantyre"; + } + if (strcmp(country, "MX") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "02") == 0) { + return "America/Tijuana"; + } else if (strcmp(region, "03") == 0) { + return "America/Hermosillo"; + } else if (strcmp(region, "04") == 0) { + return "America/Merida"; + } else if (strcmp(region, "05") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "06") == 0) { + return "America/Chihuahua"; + } else if (strcmp(region, "07") == 0) { + return "America/Monterrey"; + } else if (strcmp(region, "08") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "09") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "10") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "11") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "12") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "13") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "14") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "15") == 0) { + return "America/Chihuahua"; + } else if (strcmp(region, "16") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "17") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "18") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "19") == 0) { + return "America/Monterrey"; + } else if (strcmp(region, "20") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "21") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "22") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "23") == 0) { + return "America/Cancun"; + } else if (strcmp(region, "24") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "25") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "26") == 0) { + return "America/Hermosillo"; + } else if (strcmp(region, "27") == 0) { + return "America/Merida"; + } else if (strcmp(region, "28") == 0) { + return "America/Monterrey"; + } else if (strcmp(region, "29") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "30") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "31") == 0) { + return "America/Merida"; + } else if (strcmp(region, "32") == 0) { + return "America/Monterrey"; + } else { + return NULL; + } + } + if (strcmp(country, "MY") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Kuching"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Kuching"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Kuching"; + } else { + return NULL; + } + } + if (strcmp(country, "MZ") == 0) { + return "Africa/Maputo"; + } + if (strcmp(country, "NA") == 0) { + return "Africa/Windhoek"; + } + if (strcmp(country, "NC") == 0) { + return "Pacific/Noumea"; + } + if (strcmp(country, "NE") == 0) { + return "Africa/Niamey"; + } + if (strcmp(country, "NF") == 0) { + return "Pacific/Norfolk"; + } + if (strcmp(country, "NG") == 0) { + return "Africa/Lagos"; + } + if (strcmp(country, "NI") == 0) { + return "America/Managua"; + } + if (strcmp(country, "NL") == 0) { + return "Europe/Amsterdam"; + } + if (strcmp(country, "NO") == 0) { + return "Europe/Oslo"; + } + if (strcmp(country, "NP") == 0) { + return "Asia/Kathmandu"; + } + if (strcmp(country, "NR") == 0) { + return "Pacific/Nauru"; + } + if (strcmp(country, "NU") == 0) { + return "Pacific/Niue"; + } + if (strcmp(country, "NZ") == 0) { + if (strcmp(region, "85") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "E7") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "E8") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "E9") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F1") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F2") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F3") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F4") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F5") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F6") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F7") == 0) { + return "Pacific/Chatham"; + } else if (strcmp(region, "F8") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F9") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "G1") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "G2") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "G3") == 0) { + return "Pacific/Auckland"; + } else { + return NULL; + } + } + if (strcmp(country, "OM") == 0) { + return "Asia/Muscat"; + } + if (strcmp(country, "PA") == 0) { + return "America/Panama"; + } + if (strcmp(country, "PE") == 0) { + return "America/Lima"; + } + if (strcmp(country, "PF") == 0) { + return "Pacific/Marquesas"; + } + if (strcmp(country, "PG") == 0) { + return "Pacific/Port_Moresby"; + } + if (strcmp(country, "PH") == 0) { + return "Asia/Manila"; + } + if (strcmp(country, "PK") == 0) { + return "Asia/Karachi"; + } + if (strcmp(country, "PL") == 0) { + return "Europe/Warsaw"; + } + if (strcmp(country, "PM") == 0) { + return "America/Miquelon"; + } + if (strcmp(country, "PN") == 0) { + return "Pacific/Pitcairn"; + } + if (strcmp(country, "PR") == 0) { + return "America/Puerto_Rico"; + } + if (strcmp(country, "PS") == 0) { + return "Asia/Gaza"; + } + if (strcmp(country, "PT") == 0) { + if (strcmp(region, "02") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "03") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "04") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "05") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "06") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "07") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "08") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "09") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "10") == 0) { + return "Atlantic/Madeira"; + } else if (strcmp(region, "11") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "13") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "14") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "16") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "17") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "18") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "19") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "20") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "21") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "22") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "23") == 0) { + return "Atlantic/Azores"; + } else { + return NULL; + } + } + if (strcmp(country, "PW") == 0) { + return "Pacific/Palau"; + } + if (strcmp(country, "PY") == 0) { + return "America/Asuncion"; + } + if (strcmp(country, "QA") == 0) { + return "Asia/Qatar"; + } + if (strcmp(country, "RE") == 0) { + return "Indian/Reunion"; + } + if (strcmp(country, "RO") == 0) { + return "Europe/Bucharest"; + } + if (strcmp(country, "RS") == 0) { + return "Europe/Belgrade"; + } + if (strcmp(country, "RU") == 0) { + if (strcmp(region, "01") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Novokuznetsk"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "06") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "07") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "08") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "09") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "10") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "12") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Anadyr"; + } else if (strcmp(region, "16") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "17") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "18") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "21") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "22") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "23") == 0) { + return "Europe/Kaliningrad"; + } else if (strcmp(region, "24") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "25") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "26") == 0) { + return "Asia/Kamchatka"; + } else if (strcmp(region, "27") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "28") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "29") == 0) { + return "Asia/Novokuznetsk"; + } else if (strcmp(region, "30") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "31") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "32") == 0) { + return "Asia/Omsk"; + } else if (strcmp(region, "33") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "34") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "35") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "36") == 0) { + return "Asia/Anadyr"; + } else if (strcmp(region, "37") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "38") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "39") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "40") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "41") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "42") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "43") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "44") == 0) { + return "Asia/Magadan"; + } else if (strcmp(region, "45") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "46") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "47") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "48") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "49") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "50") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "51") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "52") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "53") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "54") == 0) { + return "Asia/Omsk"; + } else if (strcmp(region, "55") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "56") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "57") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "58") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "59") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "60") == 0) { + return "Europe/Kaliningrad"; + } else if (strcmp(region, "61") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "62") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "63") == 0) { + return "Asia/Yakutsk"; + } else if (strcmp(region, "64") == 0) { + return "Asia/Sakhalin"; + } else if (strcmp(region, "65") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "66") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "67") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "68") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "69") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "70") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "71") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "72") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "73") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "74") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "75") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "76") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "77") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "78") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "79") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "80") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "81") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "82") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "83") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "84") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "85") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "86") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "87") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "88") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "89") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "90") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "91") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "92") == 0) { + return "Asia/Anadyr"; + } else if (strcmp(region, "93") == 0) { + return "Asia/Irkutsk"; + } else { + return NULL; + } + } + if (strcmp(country, "RW") == 0) { + return "Africa/Kigali"; + } + if (strcmp(country, "SA") == 0) { + return "Asia/Riyadh"; + } + if (strcmp(country, "SB") == 0) { + return "Pacific/Guadalcanal"; + } + if (strcmp(country, "SC") == 0) { + return "Indian/Mahe"; + } + if (strcmp(country, "SD") == 0) { + return "Africa/Khartoum"; + } + if (strcmp(country, "SE") == 0) { + return "Europe/Stockholm"; + } + if (strcmp(country, "SG") == 0) { + return "Asia/Singapore"; + } + if (strcmp(country, "SH") == 0) { + return "Atlantic/St_Helena"; + } + if (strcmp(country, "SI") == 0) { + return "Europe/Ljubljana"; + } + if (strcmp(country, "SJ") == 0) { + return "Arctic/Longyearbyen"; + } + if (strcmp(country, "SK") == 0) { + return "Europe/Bratislava"; + } + if (strcmp(country, "SL") == 0) { + return "Africa/Freetown"; + } + if (strcmp(country, "SM") == 0) { + return "Europe/San_Marino"; + } + if (strcmp(country, "SN") == 0) { + return "Africa/Dakar"; + } + if (strcmp(country, "SO") == 0) { + return "Africa/Mogadishu"; + } + if (strcmp(country, "SR") == 0) { + return "America/Paramaribo"; + } + if (strcmp(country, "SS") == 0) { + return "Africa/Juba"; + } + if (strcmp(country, "ST") == 0) { + return "Africa/Sao_Tome"; + } + if (strcmp(country, "SV") == 0) { + return "America/El_Salvador"; + } + if (strcmp(country, "SX") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "SY") == 0) { + return "Asia/Damascus"; + } + if (strcmp(country, "SZ") == 0) { + return "Africa/Mbabane"; + } + if (strcmp(country, "TC") == 0) { + return "America/Grand_Turk"; + } + if (strcmp(country, "TD") == 0) { + return "Africa/Ndjamena"; + } + if (strcmp(country, "TF") == 0) { + return "Indian/Kerguelen"; + } + if (strcmp(country, "TG") == 0) { + return "Africa/Lome"; + } + if (strcmp(country, "TH") == 0) { + return "Asia/Bangkok"; + } + if (strcmp(country, "TJ") == 0) { + return "Asia/Dushanbe"; + } + if (strcmp(country, "TK") == 0) { + return "Pacific/Fakaofo"; + } + if (strcmp(country, "TL") == 0) { + return "Asia/Dili"; + } + if (strcmp(country, "TM") == 0) { + return "Asia/Ashgabat"; + } + if (strcmp(country, "TN") == 0) { + return "Africa/Tunis"; + } + if (strcmp(country, "TO") == 0) { + return "Pacific/Tongatapu"; + } + if (strcmp(country, "TR") == 0) { + return "Asia/Istanbul"; + } + if (strcmp(country, "TT") == 0) { + return "America/Port_of_Spain"; + } + if (strcmp(country, "TV") == 0) { + return "Pacific/Funafuti"; + } + if (strcmp(country, "TW") == 0) { + return "Asia/Taipei"; + } + if (strcmp(country, "TZ") == 0) { + return "Africa/Dar_es_Salaam"; + } + if (strcmp(country, "UA") == 0) { + if (strcmp(region, "01") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "02") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "03") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "04") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "05") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "06") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "07") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "08") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "09") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "10") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "11") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "12") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "13") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "14") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "15") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "16") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "17") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "18") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "19") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "20") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "21") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "22") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "23") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "24") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "25") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "26") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "27") == 0) { + return "Europe/Kiev"; + } else { + return NULL; + } + } + if (strcmp(country, "UG") == 0) { + return "Africa/Kampala"; + } + if (strcmp(country, "UM") == 0) { + return "Pacific/Wake"; + } + if (strcmp(country, "US") == 0) { + if (strcmp(region, "AK") == 0) { + return "America/Anchorage"; + } else if (strcmp(region, "AL") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "AR") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "AZ") == 0) { + return "America/Phoenix"; + } else if (strcmp(region, "CA") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "CO") == 0) { + return "America/Denver"; + } else if (strcmp(region, "CT") == 0) { + return "America/New_York"; + } else if (strcmp(region, "DC") == 0) { + return "America/New_York"; + } else if (strcmp(region, "DE") == 0) { + return "America/New_York"; + } else if (strcmp(region, "FL") == 0) { + return "America/New_York"; + } else if (strcmp(region, "GA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "HI") == 0) { + return "Pacific/Honolulu"; + } else if (strcmp(region, "IA") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "ID") == 0) { + return "America/Denver"; + } else if (strcmp(region, "IL") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "IN") == 0) { + return "America/Indiana/Indianapolis"; + } else if (strcmp(region, "KS") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "KY") == 0) { + return "America/New_York"; + } else if (strcmp(region, "LA") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "MD") == 0) { + return "America/New_York"; + } else if (strcmp(region, "ME") == 0) { + return "America/New_York"; + } else if (strcmp(region, "MI") == 0) { + return "America/New_York"; + } else if (strcmp(region, "MN") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MO") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MS") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MT") == 0) { + return "America/Denver"; + } else if (strcmp(region, "NC") == 0) { + return "America/New_York"; + } else if (strcmp(region, "ND") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "NE") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "NH") == 0) { + return "America/New_York"; + } else if (strcmp(region, "NJ") == 0) { + return "America/New_York"; + } else if (strcmp(region, "NM") == 0) { + return "America/Denver"; + } else if (strcmp(region, "NV") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "NY") == 0) { + return "America/New_York"; + } else if (strcmp(region, "OH") == 0) { + return "America/New_York"; + } else if (strcmp(region, "OK") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "OR") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "PA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "RI") == 0) { + return "America/New_York"; + } else if (strcmp(region, "SC") == 0) { + return "America/New_York"; + } else if (strcmp(region, "SD") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "TN") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "TX") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "UT") == 0) { + return "America/Denver"; + } else if (strcmp(region, "VA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "VT") == 0) { + return "America/New_York"; + } else if (strcmp(region, "WA") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "WI") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "WV") == 0) { + return "America/New_York"; + } else if (strcmp(region, "WY") == 0) { + return "America/Denver"; + } else { + return NULL; + } + } + if (strcmp(country, "UY") == 0) { + return "America/Montevideo"; + } + if (strcmp(country, "UZ") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Tashkent"; + } else { + return NULL; + } + } + if (strcmp(country, "VA") == 0) { + return "Europe/Vatican"; + } + if (strcmp(country, "VC") == 0) { + return "America/St_Vincent"; + } + if (strcmp(country, "VE") == 0) { + return "America/Caracas"; + } + if (strcmp(country, "VG") == 0) { + return "America/Tortola"; + } + if (strcmp(country, "VI") == 0) { + return "America/St_Thomas"; + } + if (strcmp(country, "VN") == 0) { + return "Asia/Phnom_Penh"; + } + if (strcmp(country, "VU") == 0) { + return "Pacific/Efate"; + } + if (strcmp(country, "WF") == 0) { + return "Pacific/Wallis"; + } + if (strcmp(country, "WS") == 0) { + return "Pacific/Pago_Pago"; + } + if (strcmp(country, "YE") == 0) { + return "Asia/Aden"; + } + if (strcmp(country, "YT") == 0) { + return "Indian/Mayotte"; + } + if (strcmp(country, "YU") == 0) { + return "Europe/Belgrade"; + } + if (strcmp(country, "ZA") == 0) { + return "Africa/Johannesburg"; + } + if (strcmp(country, "ZM") == 0) { + return "Africa/Lusaka"; + } + if (strcmp(country, "ZW") == 0) { + return "Africa/Harare"; + } + return timezone; +} diff --git a/m4/.placeholder b/m4/.placeholder new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/m4/.placeholder diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..1615d54 --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,26 @@ +man_MANS = geoiplookup6.1 geoiplookup.1 + +EXTRA_DIST = geoiplookup6.1.in geoiplookup.1.in + + +edit = sed \ + -e 's|DATADIR|$(pkgdatadir)|g' \ + -e 's|CONF_DIR|$(sysconfdir)|g' + +geoiplookup.1 geoiplookup6.1: Makefile + rm -f $@ $@.tmp + $(edit) '$(srcdir)/$@.in' >$@.tmp + mv $@.tmp $@ + +geoiplookup.1: geoiplookup.1.in +geoiplookup6.1: geoiplookup6.1.in + +CLEANFILES = geoiplookup6.1 geoiplookup.1 + +LOOKUP_MAN = $(mandir)/man1/geoiplookup.1 +LOOKUP6_MAN = $(mandir)/man1/geoiplookup6.1 + +install-data-hook: + cat geoiplookup.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP_MAN) + cat geoiplookup6.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP6_MAN) + diff --git a/man/geoiplookup.1.in b/man/geoiplookup.1.in new file mode 100644 index 0000000..010e58f --- /dev/null +++ b/man/geoiplookup.1.in @@ -0,0 +1,37 @@ +.TH GEOIPLOOKUP 1 "2 Jan 2007" +.UC 4 +.SH NAME +geoiplookup \- look up country using IP Address or hostname +.SH SYNOPSIS +geoiplookup [\-d directory] [\-f filename] [\-v] <ipaddress|hostname> +.SH DESCRIPTION +geoiplookup uses the GeoIP library and database to find the Country +that an IP address or hostname originates from. +.PP +For example +.PP +.I geoiplookup 80.60.233.195 +.PP +will find the Country that 80.60.233.195 originates from, in the following format: +.PP +.I NL, Netherlands +.PP +.SH OPTIONS +.IP "\-f" +Specify a custom path to a single GeoIP datafile. +.IP "\-d" +Specify a custom directory containing GeoIP datafile(s). By default geoiplookup looks in DATADIR +.IP "\-v" +Lists the date and build number for the GeoIP datafile(s). +.SH AUTHOR +Written by T.J. Mather +.SH "REPORTING BUGS" +Report bugs to <support@maxmind.com> +.SH COPYRIGHT +Copyright (C) 2016 MaxMind, Inc. + +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +geoipupdate(1), nslookup(1). diff --git a/man/geoiplookup6.1.in b/man/geoiplookup6.1.in new file mode 100644 index 0000000..8816e47 --- /dev/null +++ b/man/geoiplookup6.1.in @@ -0,0 +1,42 @@ +.TH GEOIPLOOKUP6 1 "28 Oct 2008" +.UC 4 +.SH NAME +geouplookup6 \- look up country using IP Address or hostname +.SH SYNOPSIS +geouplookup6 [\-d directory] [\-f filename] [\-v] <ipaddress|hostname> +.SH DESCRIPTION +geouplookup6 uses the GeoIP library and database to find the Country +that an IP address or hostname originates from. You must install a database suitable for geoiplookup6. IE: GeoIPv6.dat +.PP +For example: +.PP +.I geouplookup6 2001:4860:0:1001::68 +.PP +.I geoiplookup6 ipv6.google.com +.PP +will find the Country that 2001:4860:0:1001::68 originates from, in the following format: +.PP +.I US, United States +.PP +.PP Please notice, that names must resolve to a ipv6 address. For example +.PP geoiplookup6 www.maxmind.com does not work, since there is no ipv6 +.PP DNS entry +.SH OPTIONS +.IP "\-f" +Specify a custom path to a single GeoIP datafile. +.IP "\-d" +Specify a custom directory containing GeoIP datafile(s). By default geouplookup6 looks in DATADIR +.IP "\-v" +Lists the date and build number for the GeoIP datafile(s). +.SH AUTHOR +Written by T.J. Mather +.SH "REPORTING BUGS" +Report bugs to <support@maxmind.com> +.SH COPYRIGHT +Copyright (C) 2008 MaxMind LLC + +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +geoipupdate(1), nslookup(1). diff --git a/regioncode/generate_regionName.pl b/regioncode/generate_regionName.pl new file mode 100755 index 0000000..7b75219 --- /dev/null +++ b/regioncode/generate_regionName.pl @@ -0,0 +1,176 @@ +#!/usr/bin/perl + +# Used to generate regionName.c +# usage: ./generate_regionName.pl > ../libGeoIP/regionName.c + +# Usually run update-region-codes.pl before generate_regionName.pl like +# +# ./update-region-codes.pl +# ./generate_regionName.pl > ../libGeoIP/regionName.c + +use strict; +use warnings; +use autodie; + +use Text::CSV_XS (); + +my $last_country_code = q{}; + +my @country_codes; +my @region_code2s; +my @region_names; + +sub init_variables () { + $last_country_code = q{}; +} + +sub parse_file { + + # http://geolite.maxmind.com/download/geoip/misc/region_codes.csv + open my $fh, '<:encoding(latin1)', 'region_codes.csv'; + <$fh>; + + my $csv = Text::CSV_XS->new( { binary => 1, auto_diag => 1 } ); + + while ( my $row = $csv->getline($fh) ) { + my ( $country_code, $region_code, $name ) = @{$row}; + my $region_code2; + if ( $country_code eq 'US' || $country_code eq 'CA' ) { + $region_code =~ /^[A-Z]{2}$/ or die "Wrong region code"; + $region_code2 + = ( ( ord( substr( $region_code, 0, 1 ) ) - 48 ) + * ( 65 + 26 - 48 ) ) + + ord( substr( $region_code, 1, 1 ) ) + - 48 + 100; + } + else { + if ( $region_code =~ /^\d\d$/ ) { + $region_code2 + = ( ord( substr( $region_code, 0, 1 ) ) - 48 ) * 10 + + ord( substr( $region_code, 1, 1 ) ) + - 48; + + } + elsif ( $region_code =~ /^[A-Z0-9]{2}$/ ) { + $region_code2 + = ( ( ord( substr( $region_code, 0, 1 ) ) - 48 ) + * ( 65 + 26 - 48 ) ) + + ord( substr( $region_code, 1, 1 ) ) + - 48 + 100; + } + else { + die "Region code seems wrong $region_code\n"; + } + } + die q{region name cannot contain a quote (")} if $name =~ /"/; + readcode( $country_code, $region_code, $region_code2, $name ); + } + close $fh; +} + +sub generate_region_name_functions { + + my $i = 0; + for my $country_code (@country_codes) { + + # function head + if ( $last_country_code ne $country_code ) { + if ( $last_country_code ne q{} ) { + print " default:\n return NULL;\n"; + print " }\n"; # switch end + print "}\n"; # function get_region_name_XX end + } + $last_country_code = $country_code; + + print "\nstatic const char * get_region_name_" . $country_code + . "(int region_code)\n"; # function begin + print "{\n"; + print " switch(region_code) {\n"; # switch end + } + + print " case " . $region_code2s[$i] . ":\n"; + print qq{ return "$region_names[$i]";\n}; + $i++; + } + + if ( $last_country_code ne "" ) { + print " default:\n return NULL;\n"; + print " }\n"; # switch end + print "}\n"; # function get_region_name_XX end + } +} + +# read code to collect to array +sub readcode { + my ( $country_code, $region_code, $region_code2, $name ) = @_; + + push( @country_codes, $country_code ); + push( @region_code2s, $region_code2 ); + push( @region_names, $name ); + +} + +sub generate_region_condition () { + + for my $country_code (@country_codes) { + if ( $last_country_code ne $country_code ) { + $last_country_code = $country_code; + + print " if (strcmp(country_code," . qq(") + . $last_country_code . qq(") + . ") == 0) {\n"; # if condition + print " return get_region_name_" + . $last_country_code + . "(region_code2);\n"; + print " }\n"; # function get_region_name_XX end + } + } +} + +# implementation of GeoIP_region_name_by_code +sub generate_api_function { + + print <<__C_CODE__; + +const char * GeoIP_region_name_by_code(const char * country_code,const char * region_code) { + int region_code2 = -1; + if (region_code == NULL) { return NULL; } + + if ( ((region_code[0] >= 48) && (region_code[0] < (48 + 10))) + && ((region_code[1] >= 48) && (region_code[1] < (48 + 10))) + ) { + + /* only numbers, that shortens the large switch statements */ + region_code2 = (region_code[0] - 48) * 10 + region_code[1] - 48; + } + + else if ( ( ((region_code[0] >= 65) && (region_code[0] < (65 + 26))) + || ((region_code[0] >= 48) && (region_code[0] < (48 + 10)))) + && ( ((region_code[1] >= 65) && (region_code[1] < (65 + 26))) + || ((region_code[1] >= 48) && (region_code[1] < (48 + 10)))) + ) { + + region_code2 = (region_code[0] - 48) * (65 + 26 - 48) + region_code[1] - 48 + 100; + } + + if (region_code2 == -1) {return NULL;} + +__C_CODE__ + + init_variables(); + generate_region_condition(); + + # function end + print " return NULL;\n"; + print "}\n"; + +} + +parse_file(); +init_variables(); +print qq{#include "GeoIP.h"\n}; +print "#include <string.h>\n"; +print "#include <stdio.h>\n\n"; +generate_region_name_functions(); +generate_api_function(); + diff --git a/regioncode/region_codes.csv b/regioncode/region_codes.csv new file mode 100644 index 0000000..aa62b98 --- /dev/null +++ b/regioncode/region_codes.csv @@ -0,0 +1,4108 @@ +AD,02,"Canillo" +AD,03,"Encamp" +AD,04,"La Massana" +AD,05,"Ordino" +AD,06,"Sant Julia de Loria" +AD,07,"Andorra la Vella" +AD,08,"Escaldes-Engordany" +AE,01,"Abu Dhabi" +AE,02,"Ajman" +AE,03,"Dubai" +AE,04,"Fujairah" +AE,05,"Ras Al Khaimah" +AE,06,"Sharjah" +AE,07,"Umm Al Quwain" +AF,01,"Badakhshan" +AF,02,"Badghis" +AF,03,"Baghlan" +AF,05,"Bamian" +AF,06,"Farah" +AF,07,"Faryab" +AF,08,"Ghazni" +AF,09,"Ghowr" +AF,10,"Helmand" +AF,11,"Herat" +AF,13,"Kabol" +AF,14,"Kapisa" +AF,17,"Lowgar" +AF,18,"Nangarhar" +AF,19,"Nimruz" +AF,23,"Kandahar" +AF,24,"Kondoz" +AF,26,"Takhar" +AF,27,"Vardak" +AF,28,"Zabol" +AF,29,"Paktika" +AF,30,"Balkh" +AF,31,"Jowzjan" +AF,32,"Samangan" +AF,33,"Sar-e Pol" +AF,34,"Konar" +AF,35,"Laghman" +AF,36,"Paktia" +AF,37,"Khowst" +AF,38,"Nurestan" +AF,39,"Oruzgan" +AF,40,"Parvan" +AF,41,"Daykondi" +AF,42,"Panjshir" +AG,01,"Barbuda" +AG,03,"Saint George" +AG,04,"Saint John" +AG,05,"Saint Mary" +AG,06,"Saint Paul" +AG,07,"Saint Peter" +AG,08,"Saint Philip" +AG,09,"Redonda" +AL,40,"Berat" +AL,41,"Diber" +AL,42,"Durres" +AL,43,"Elbasan" +AL,44,"Fier" +AL,45,"Gjirokaster" +AL,46,"Korce" +AL,47,"Kukes" +AL,48,"Lezhe" +AL,49,"Shkoder" +AL,50,"Tirane" +AL,51,"Vlore" +AM,01,"Aragatsotn" +AM,02,"Ararat" +AM,03,"Armavir" +AM,04,"Geghark'unik'" +AM,05,"Kotayk'" +AM,06,"Lorri" +AM,07,"Shirak" +AM,08,"Syunik'" +AM,09,"Tavush" +AM,10,"Vayots' Dzor" +AM,11,"Yerevan" +AO,01,"Benguela" +AO,02,"Bie" +AO,03,"Cabinda" +AO,04,"Cuando Cubango" +AO,05,"Cuanza Norte" +AO,06,"Cuanza Sul" +AO,07,"Cunene" +AO,08,"Huambo" +AO,09,"Huila" +AO,12,"Malanje" +AO,13,"Namibe" +AO,14,"Moxico" +AO,15,"Uige" +AO,16,"Zaire" +AO,17,"Lunda Norte" +AO,18,"Lunda Sul" +AO,19,"Bengo" +AO,20,"Luanda" +AR,01,"Buenos Aires" +AR,02,"Catamarca" +AR,03,"Chaco" +AR,04,"Chubut" +AR,05,"Cordoba" +AR,06,"Corrientes" +AR,07,"Distrito Federal" +AR,08,"Entre Rios" +AR,09,"Formosa" +AR,10,"Jujuy" +AR,11,"La Pampa" +AR,12,"La Rioja" +AR,13,"Mendoza" +AR,14,"Misiones" +AR,15,"Neuquen" +AR,16,"Rio Negro" +AR,17,"Salta" +AR,18,"San Juan" +AR,19,"San Luis" +AR,20,"Santa Cruz" +AR,21,"Santa Fe" +AR,22,"Santiago del Estero" +AR,23,"Tierra del Fuego" +AR,24,"Tucuman" +AT,01,"Burgenland" +AT,02,"Karnten" +AT,03,"Niederosterreich" +AT,04,"Oberosterreich" +AT,05,"Salzburg" +AT,06,"Steiermark" +AT,07,"Tirol" +AT,08,"Vorarlberg" +AT,09,"Wien" +AU,01,"Australian Capital Territory" +AU,02,"New South Wales" +AU,03,"Northern Territory" +AU,04,"Queensland" +AU,05,"South Australia" +AU,06,"Tasmania" +AU,07,"Victoria" +AU,08,"Western Australia" +AZ,01,"Abseron" +AZ,02,"Agcabadi" +AZ,03,"Agdam" +AZ,04,"Agdas" +AZ,05,"Agstafa" +AZ,06,"Agsu" +AZ,07,"Ali Bayramli" +AZ,08,"Astara" +AZ,09,"Baki" +AZ,10,"Balakan" +AZ,11,"Barda" +AZ,12,"Beylaqan" +AZ,13,"Bilasuvar" +AZ,14,"Cabrayil" +AZ,15,"Calilabad" +AZ,16,"Daskasan" +AZ,17,"Davaci" +AZ,18,"Fuzuli" +AZ,19,"Gadabay" +AZ,20,"Ganca" +AZ,21,"Goranboy" +AZ,22,"Goycay" +AZ,23,"Haciqabul" +AZ,24,"Imisli" +AZ,25,"Ismayilli" +AZ,26,"Kalbacar" +AZ,27,"Kurdamir" +AZ,28,"Lacin" +AZ,29,"Lankaran" +AZ,30,"Lankaran" +AZ,31,"Lerik" +AZ,32,"Masalli" +AZ,33,"Mingacevir" +AZ,34,"Naftalan" +AZ,35,"Naxcivan" +AZ,36,"Neftcala" +AZ,37,"Oguz" +AZ,38,"Qabala" +AZ,39,"Qax" +AZ,40,"Qazax" +AZ,41,"Qobustan" +AZ,42,"Quba" +AZ,43,"Qubadli" +AZ,44,"Qusar" +AZ,45,"Saatli" +AZ,46,"Sabirabad" +AZ,47,"Saki" +AZ,48,"Saki" +AZ,49,"Salyan" +AZ,50,"Samaxi" +AZ,51,"Samkir" +AZ,52,"Samux" +AZ,53,"Siyazan" +AZ,54,"Sumqayit" +AZ,55,"Susa" +AZ,56,"Susa" +AZ,57,"Tartar" +AZ,58,"Tovuz" +AZ,59,"Ucar" +AZ,60,"Xacmaz" +AZ,61,"Xankandi" +AZ,62,"Xanlar" +AZ,63,"Xizi" +AZ,64,"Xocali" +AZ,65,"Xocavand" +AZ,66,"Yardimli" +AZ,67,"Yevlax" +AZ,68,"Yevlax" +AZ,69,"Zangilan" +AZ,70,"Zaqatala" +AZ,71,"Zardab" +BA,01,"Federation of Bosnia and Herzegovina" +BA,03,"Brcko District" +BA,02,"Republika Srpska" +BB,01,"Christ Church" +BB,02,"Saint Andrew" +BB,03,"Saint George" +BB,04,"Saint James" +BB,05,"Saint John" +BB,06,"Saint Joseph" +BB,07,"Saint Lucy" +BB,08,"Saint Michael" +BB,09,"Saint Peter" +BB,10,"Saint Philip" +BB,11,"Saint Thomas" +BD,81,"Dhaka" +BD,82,"Khulna" +BD,83,"Rajshahi" +BD,84,"Chittagong" +BD,85,"Barisal" +BD,86,"Sylhet" +BD,87,"Rangpur" +BE,01,"Antwerpen" +BE,03,"Hainaut" +BE,04,"Liege" +BE,05,"Limburg" +BE,06,"Luxembourg" +BE,07,"Namur" +BE,08,"Oost-Vlaanderen" +BE,09,"West-Vlaanderen" +BE,10,"Brabant Wallon" +BE,11,"Brussels Hoofdstedelijk Gewest" +BE,12,"Vlaams-Brabant" +BE,13,"Flanders" +BE,14,"Wallonia" +BF,15,"Bam" +BF,19,"Boulkiemde" +BF,20,"Ganzourgou" +BF,21,"Gnagna" +BF,28,"Kouritenga" +BF,33,"Oudalan" +BF,34,"Passore" +BF,36,"Sanguie" +BF,40,"Soum" +BF,42,"Tapoa" +BF,44,"Zoundweogo" +BF,45,"Bale" +BF,46,"Banwa" +BF,47,"Bazega" +BF,48,"Bougouriba" +BF,49,"Boulgou" +BF,50,"Gourma" +BF,51,"Houet" +BF,52,"Ioba" +BF,53,"Kadiogo" +BF,54,"Kenedougou" +BF,55,"Komoe" +BF,56,"Komondjari" +BF,57,"Kompienga" +BF,58,"Kossi" +BF,59,"Koulpelogo" +BF,60,"Kourweogo" +BF,61,"Leraba" +BF,62,"Loroum" +BF,63,"Mouhoun" +BF,64,"Namentenga" +BF,65,"Naouri" +BF,66,"Nayala" +BF,67,"Noumbiel" +BF,68,"Oubritenga" +BF,69,"Poni" +BF,70,"Sanmatenga" +BF,71,"Seno" +BF,72,"Sissili" +BF,73,"Sourou" +BF,74,"Tuy" +BF,75,"Yagha" +BF,76,"Yatenga" +BF,77,"Ziro" +BF,78,"Zondoma" +BG,33,"Mikhaylovgrad" +BG,38,"Blagoevgrad" +BG,39,"Burgas" +BG,40,"Dobrich" +BG,41,"Gabrovo" +BG,42,"Grad Sofiya" +BG,43,"Khaskovo" +BG,44,"Kurdzhali" +BG,45,"Kyustendil" +BG,46,"Lovech" +BG,47,"Montana" +BG,48,"Pazardzhik" +BG,49,"Pernik" +BG,50,"Pleven" +BG,51,"Plovdiv" +BG,52,"Razgrad" +BG,53,"Ruse" +BG,54,"Shumen" +BG,55,"Silistra" +BG,56,"Sliven" +BG,57,"Smolyan" +BG,58,"Sofiya" +BG,59,"Stara Zagora" +BG,60,"Turgovishte" +BG,61,"Varna" +BG,62,"Veliko Turnovo" +BG,63,"Vidin" +BG,64,"Vratsa" +BG,65,"Yambol" +BH,01,"Al Hadd" +BH,02,"Al Manamah" +BH,05,"Jidd Hafs" +BH,06,"Sitrah" +BH,08,"Al Mintaqah al Gharbiyah" +BH,09,"Mintaqat Juzur Hawar" +BH,10,"Al Mintaqah ash Shamaliyah" +BH,11,"Al Mintaqah al Wusta" +BH,12,"Madinat" +BH,13,"Ar Rifa" +BH,14,"Madinat Hamad" +BH,15,"Al Muharraq" +BH,16,"Al Asimah" +BH,17,"Al Janubiyah" +BH,18,"Ash Shamaliyah" +BH,19,"Al Wusta" +BI,02,"Bujumbura" +BI,09,"Bubanza" +BI,10,"Bururi" +BI,11,"Cankuzo" +BI,12,"Cibitoke" +BI,13,"Gitega" +BI,14,"Karuzi" +BI,15,"Kayanza" +BI,16,"Kirundo" +BI,17,"Makamba" +BI,18,"Muyinga" +BI,19,"Ngozi" +BI,20,"Rutana" +BI,21,"Ruyigi" +BI,22,"Muramvya" +BI,23,"Mwaro" +BJ,07,"Alibori" +BJ,08,"Atakora" +BJ,09,"Atlanyique" +BJ,10,"Borgou" +BJ,11,"Collines" +BJ,12,"Kouffo" +BJ,13,"Donga" +BJ,14,"Littoral" +BJ,15,"Mono" +BJ,16,"Oueme" +BJ,17,"Plateau" +BJ,18,"Zou" +BM,01,"Devonshire" +BM,02,"Hamilton" +BM,03,"Hamilton" +BM,04,"Paget" +BM,05,"Pembroke" +BM,06,"Saint George" +BM,07,"Saint George's" +BM,08,"Sandys" +BM,09,"Smiths" +BM,10,"Southampton" +BM,11,"Warwick" +BN,07,"Alibori" +BN,08,"Belait" +BN,09,"Brunei and Muara" +BN,10,"Temburong" +BN,11,"Collines" +BN,12,"Kouffo" +BN,13,"Donga" +BN,14,"Littoral" +BN,15,"Tutong" +BN,16,"Oueme" +BN,17,"Plateau" +BN,18,"Zou" +BO,01,"Chuquisaca" +BO,02,"Cochabamba" +BO,03,"El Beni" +BO,04,"La Paz" +BO,05,"Oruro" +BO,06,"Pando" +BO,07,"Potosi" +BO,08,"Santa Cruz" +BO,09,"Tarija" +BR,01,"Acre" +BR,02,"Alagoas" +BR,03,"Amapa" +BR,04,"Amazonas" +BR,05,"Bahia" +BR,06,"Ceara" +BR,07,"Distrito Federal" +BR,08,"Espirito Santo" +BR,11,"Mato Grosso do Sul" +BR,13,"Maranhao" +BR,14,"Mato Grosso" +BR,15,"Minas Gerais" +BR,16,"Para" +BR,17,"Paraiba" +BR,18,"Parana" +BR,20,"Piaui" +BR,21,"Rio de Janeiro" +BR,22,"Rio Grande do Norte" +BR,23,"Rio Grande do Sul" +BR,24,"Rondonia" +BR,25,"Roraima" +BR,26,"Santa Catarina" +BR,27,"Sao Paulo" +BR,28,"Sergipe" +BR,29,"Goias" +BR,30,"Pernambuco" +BR,31,"Tocantins" +BS,05,"Bimini" +BS,06,"Cat Island" +BS,10,"Exuma" +BS,13,"Inagua" +BS,15,"Long Island" +BS,16,"Mayaguana" +BS,18,"Ragged Island" +BS,22,"Harbour Island" +BS,23,"New Providence" +BS,24,"Acklins and Crooked Islands" +BS,25,"Freeport" +BS,26,"Fresh Creek" +BS,27,"Governor's Harbour" +BS,28,"Green Turtle Cay" +BS,29,"High Rock" +BS,30,"Kemps Bay" +BS,31,"Marsh Harbour" +BS,32,"Nichollstown and Berry Islands" +BS,33,"Rock Sound" +BS,34,"Sandy Point" +BS,35,"San Salvador and Rum Cay" +BT,05,"Bumthang" +BT,06,"Chhukha" +BT,07,"Chirang" +BT,08,"Daga" +BT,09,"Geylegphug" +BT,10,"Ha" +BT,11,"Lhuntshi" +BT,12,"Mongar" +BT,13,"Paro" +BT,14,"Pemagatsel" +BT,15,"Punakha" +BT,16,"Samchi" +BT,17,"Samdrup" +BT,18,"Shemgang" +BT,19,"Tashigang" +BT,20,"Thimphu" +BT,21,"Tongsa" +BT,22,"Wangdi Phodrang" +BW,01,"Central" +BW,03,"Ghanzi" +BW,04,"Kgalagadi" +BW,05,"Kgatleng" +BW,06,"Kweneng" +BW,08,"North-East" +BW,09,"South-East" +BW,10,"Southern" +BW,11,"North-West" +BY,01,"Brestskaya Voblasts'" +BY,02,"Homyel'skaya Voblasts'" +BY,03,"Hrodzyenskaya Voblasts'" +BY,04,"Minsk" +BY,05,"Minskaya Voblasts'" +BY,06,"Mahilyowskaya Voblasts'" +BY,07,"Vitsyebskaya Voblasts'" +BZ,01,"Belize" +BZ,02,"Cayo" +BZ,03,"Corozal" +BZ,04,"Orange Walk" +BZ,05,"Stann Creek" +BZ,06,"Toledo" +CA,AB,"Alberta" +CA,BC,"British Columbia" +CA,MB,"Manitoba" +CA,NB,"New Brunswick" +CA,NL,"Newfoundland" +CA,NS,"Nova Scotia" +CA,NT,"Northwest Territories" +CA,NU,"Nunavut" +CA,ON,"Ontario" +CA,PE,"Prince Edward Island" +CA,QC,"Quebec" +CA,SK,"Saskatchewan" +CA,YT,"Yukon Territory" +CD,01,"Bandundu" +CD,02,"Equateur" +CD,04,"Kasai-Oriental" +CD,05,"Katanga" +CD,06,"Kinshasa" +CD,08,"Bas-Congo" +CD,09,"Orientale" +CD,10,"Maniema" +CD,11,"Nord-Kivu" +CD,12,"Sud-Kivu" +CF,01,"Bamingui-Bangoran" +CF,02,"Basse-Kotto" +CF,03,"Haute-Kotto" +CF,04,"Mambere-Kadei" +CF,05,"Haut-Mbomou" +CF,06,"Kemo" +CF,07,"Lobaye" +CF,08,"Mbomou" +CF,09,"Nana-Mambere" +CF,11,"Ouaka" +CF,12,"Ouham" +CF,13,"Ouham-Pende" +CF,14,"Cuvette-Ouest" +CF,15,"Nana-Grebizi" +CF,16,"Sangha-Mbaere" +CF,17,"Ombella-Mpoko" +CF,18,"Bangui" +CG,01,"Bouenza" +CG,04,"Kouilou" +CG,05,"Lekoumou" +CG,06,"Likouala" +CG,07,"Niari" +CG,08,"Plateaux" +CG,10,"Sangha" +CG,11,"Pool" +CG,12,"Brazzaville" +CG,13,"Cuvette" +CG,14,"Cuvette-Ouest" +CH,01,"Aargau" +CH,02,"Ausser-Rhoden" +CH,03,"Basel-Landschaft" +CH,04,"Basel-Stadt" +CH,05,"Bern" +CH,06,"Fribourg" +CH,07,"Geneve" +CH,08,"Glarus" +CH,09,"Graubunden" +CH,10,"Inner-Rhoden" +CH,11,"Luzern" +CH,12,"Neuchatel" +CH,13,"Nidwalden" +CH,14,"Obwalden" +CH,15,"Sankt Gallen" +CH,16,"Schaffhausen" +CH,17,"Schwyz" +CH,18,"Solothurn" +CH,19,"Thurgau" +CH,20,"Ticino" +CH,21,"Uri" +CH,22,"Valais" +CH,23,"Vaud" +CH,24,"Zug" +CH,25,"Zurich" +CH,26,"Jura" +CI,74,"Agneby" +CI,75,"Bafing" +CI,76,"Bas-Sassandra" +CI,77,"Denguele" +CI,78,"Dix-Huit Montagnes" +CI,79,"Fromager" +CI,80,"Haut-Sassandra" +CI,81,"Lacs" +CI,82,"Lagunes" +CI,83,"Marahoue" +CI,84,"Moyen-Cavally" +CI,85,"Moyen-Comoe" +CI,86,"N'zi-Comoe" +CI,87,"Savanes" +CI,88,"Sud-Bandama" +CI,89,"Sud-Comoe" +CI,90,"Vallee du Bandama" +CI,91,"Worodougou" +CI,92,"Zanzan" +CL,01,"Valparaiso" +CL,02,"Aisen del General Carlos Ibanez del Campo" +CL,03,"Antofagasta" +CL,04,"Araucania" +CL,05,"Atacama" +CL,06,"Bio-Bio" +CL,07,"Coquimbo" +CL,08,"Libertador General Bernardo O'Higgins" +CL,09,"Los Lagos" +CL,10,"Magallanes y de la Antartica Chilena" +CL,11,"Maule" +CL,12,"Region Metropolitana" +CL,13,"Tarapaca" +CL,14,"Los Lagos" +CL,15,"Tarapaca" +CL,16,"Arica y Parinacota" +CL,17,"Los Rios" +CM,04,"Est" +CM,05,"Littoral" +CM,07,"Nord-Ouest" +CM,08,"Ouest" +CM,09,"Sud-Ouest" +CM,10,"Adamaoua" +CM,11,"Centre" +CM,12,"Extreme-Nord" +CM,13,"Nord" +CM,14,"Sud" +CN,01,"Anhui" +CN,02,"Zhejiang" +CN,03,"Jiangxi" +CN,04,"Jiangsu" +CN,05,"Jilin" +CN,06,"Qinghai" +CN,07,"Fujian" +CN,08,"Heilongjiang" +CN,09,"Henan" +CN,10,"Hebei" +CN,11,"Hunan" +CN,12,"Hubei" +CN,13,"Xinjiang" +CN,14,"Xizang" +CN,15,"Gansu" +CN,16,"Guangxi" +CN,18,"Guizhou" +CN,19,"Liaoning" +CN,20,"Nei Mongol" +CN,21,"Ningxia" +CN,22,"Beijing" +CN,23,"Shanghai" +CN,24,"Shanxi" +CN,25,"Shandong" +CN,26,"Shaanxi" +CN,28,"Tianjin" +CN,29,"Yunnan" +CN,30,"Guangdong" +CN,31,"Hainan" +CN,32,"Sichuan" +CN,33,"Chongqing" +CO,01,"Amazonas" +CO,02,"Antioquia" +CO,03,"Arauca" +CO,04,"Atlantico" +CO,08,"Caqueta" +CO,09,"Cauca" +CO,10,"Cesar" +CO,11,"Choco" +CO,12,"Cordoba" +CO,14,"Guaviare" +CO,15,"Guainia" +CO,16,"Huila" +CO,17,"La Guajira" +CO,19,"Meta" +CO,20,"Narino" +CO,21,"Norte de Santander" +CO,22,"Putumayo" +CO,23,"Quindio" +CO,24,"Risaralda" +CO,25,"San Andres y Providencia" +CO,26,"Santander" +CO,27,"Sucre" +CO,28,"Tolima" +CO,29,"Valle del Cauca" +CO,30,"Vaupes" +CO,31,"Vichada" +CO,32,"Casanare" +CO,33,"Cundinamarca" +CO,34,"Distrito Especial" +CO,35,"Bolivar" +CO,36,"Boyaca" +CO,37,"Caldas" +CO,38,"Magdalena" +CR,01,"Alajuela" +CR,02,"Cartago" +CR,03,"Guanacaste" +CR,04,"Heredia" +CR,06,"Limon" +CR,07,"Puntarenas" +CR,08,"San Jose" +CU,01,"Pinar del Rio" +CU,02,"Ciudad de la Habana" +CU,03,"Matanzas" +CU,04,"Isla de la Juventud" +CU,05,"Camaguey" +CU,07,"Ciego de Avila" +CU,08,"Cienfuegos" +CU,09,"Granma" +CU,10,"Guantanamo" +CU,11,"La Habana" +CU,12,"Holguin" +CU,13,"Las Tunas" +CU,14,"Sancti Spiritus" +CU,15,"Santiago de Cuba" +CU,16,"Villa Clara" +CV,01,"Boa Vista" +CV,02,"Brava" +CV,04,"Maio" +CV,05,"Paul" +CV,07,"Ribeira Grande" +CV,08,"Sal" +CV,10,"Sao Nicolau" +CV,11,"Sao Vicente" +CV,13,"Mosteiros" +CV,14,"Praia" +CV,15,"Santa Catarina" +CV,16,"Santa Cruz" +CV,17,"Sao Domingos" +CV,18,"Sao Filipe" +CV,19,"Sao Miguel" +CV,20,"Tarrafal" +CY,01,"Famagusta" +CY,02,"Kyrenia" +CY,03,"Larnaca" +CY,04,"Nicosia" +CY,05,"Limassol" +CY,06,"Paphos" +CZ,52,"Hlavni mesto Praha" +CZ,78,"Jihomoravsky kraj" +CZ,79,"Jihocesky kraj" +CZ,80,"Vysocina" +CZ,81,"Karlovarsky kraj" +CZ,82,"Kralovehradecky kraj" +CZ,83,"Liberecky kraj" +CZ,84,"Olomoucky kraj" +CZ,85,"Moravskoslezsky kraj" +CZ,86,"Pardubicky kraj" +CZ,87,"Plzensky kraj" +CZ,88,"Stredocesky kraj" +CZ,89,"Ustecky kraj" +CZ,90,"Zlinsky kraj" +DE,01,"Baden-Wurttemberg" +DE,02,"Bayern" +DE,03,"Bremen" +DE,04,"Hamburg" +DE,05,"Hessen" +DE,06,"Niedersachsen" +DE,07,"Nordrhein-Westfalen" +DE,08,"Rheinland-Pfalz" +DE,09,"Saarland" +DE,10,"Schleswig-Holstein" +DE,11,"Brandenburg" +DE,12,"Mecklenburg-Vorpommern" +DE,13,"Sachsen" +DE,14,"Sachsen-Anhalt" +DE,15,"Thuringen" +DE,16,"Berlin" +DJ,01,"Ali Sabieh" +DJ,04,"Obock" +DJ,05,"Tadjoura" +DJ,06,"Dikhil" +DJ,07,"Djibouti" +DJ,08,"Arta" +DK,17,"Hovedstaden" +DK,18,"Midtjylland" +DK,19,"Nordjylland" +DK,20,"Sjelland" +DK,21,"Syddanmark" +DM,02,"Saint Andrew" +DM,03,"Saint David" +DM,04,"Saint George" +DM,05,"Saint John" +DM,06,"Saint Joseph" +DM,07,"Saint Luke" +DM,08,"Saint Mark" +DM,09,"Saint Patrick" +DM,10,"Saint Paul" +DM,11,"Saint Peter" +DO,01,"Azua" +DO,02,"Baoruco" +DO,03,"Barahona" +DO,04,"Dajabon" +DO,05,"Distrito Nacional" +DO,06,"Duarte" +DO,08,"Espaillat" +DO,09,"Independencia" +DO,10,"La Altagracia" +DO,11,"Elias Pina" +DO,12,"La Romana" +DO,14,"Maria Trinidad Sanchez" +DO,15,"Monte Cristi" +DO,16,"Pedernales" +DO,17,"Peravia" +DO,18,"Puerto Plata" +DO,19,"Salcedo" +DO,20,"Samana" +DO,21,"Sanchez Ramirez" +DO,23,"San Juan" +DO,24,"San Pedro De Macoris" +DO,25,"Santiago" +DO,26,"Santiago Rodriguez" +DO,27,"Valverde" +DO,28,"El Seibo" +DO,29,"Hato Mayor" +DO,30,"La Vega" +DO,31,"Monsenor Nouel" +DO,32,"Monte Plata" +DO,33,"San Cristobal" +DO,34,"Distrito Nacional" +DO,35,"Peravia" +DO,36,"San Jose de Ocoa" +DO,37,"Santo Domingo" +DZ,01,"Alger" +DZ,03,"Batna" +DZ,04,"Constantine" +DZ,06,"Medea" +DZ,07,"Mostaganem" +DZ,09,"Oran" +DZ,10,"Saida" +DZ,12,"Setif" +DZ,13,"Tiaret" +DZ,14,"Tizi Ouzou" +DZ,15,"Tlemcen" +DZ,18,"Bejaia" +DZ,19,"Biskra" +DZ,20,"Blida" +DZ,21,"Bouira" +DZ,22,"Djelfa" +DZ,23,"Guelma" +DZ,24,"Jijel" +DZ,25,"Laghouat" +DZ,26,"Mascara" +DZ,27,"M'sila" +DZ,29,"Oum el Bouaghi" +DZ,30,"Sidi Bel Abbes" +DZ,31,"Skikda" +DZ,33,"Tebessa" +DZ,34,"Adrar" +DZ,35,"Ain Defla" +DZ,36,"Ain Temouchent" +DZ,37,"Annaba" +DZ,38,"Bechar" +DZ,39,"Bordj Bou Arreridj" +DZ,40,"Boumerdes" +DZ,41,"Chlef" +DZ,42,"El Bayadh" +DZ,43,"El Oued" +DZ,44,"El Tarf" +DZ,45,"Ghardaia" +DZ,46,"Illizi" +DZ,47,"Khenchela" +DZ,48,"Mila" +DZ,49,"Naama" +DZ,50,"Ouargla" +DZ,51,"Relizane" +DZ,52,"Souk Ahras" +DZ,53,"Tamanghasset" +DZ,54,"Tindouf" +DZ,55,"Tipaza" +DZ,56,"Tissemsilt" +EC,01,"Galapagos" +EC,02,"Azuay" +EC,03,"Bolivar" +EC,04,"Canar" +EC,05,"Carchi" +EC,06,"Chimborazo" +EC,07,"Cotopaxi" +EC,08,"El Oro" +EC,09,"Esmeraldas" +EC,10,"Guayas" +EC,11,"Imbabura" +EC,12,"Loja" +EC,13,"Los Rios" +EC,14,"Manabi" +EC,15,"Morona-Santiago" +EC,17,"Pastaza" +EC,18,"Pichincha" +EC,19,"Tungurahua" +EC,20,"Zamora-Chinchipe" +EC,22,"Sucumbios" +EC,23,"Napo" +EC,24,"Orellana" +EE,01,"Harjumaa" +EE,02,"Hiiumaa" +EE,03,"Ida-Virumaa" +EE,04,"Jarvamaa" +EE,05,"Jogevamaa" +EE,06,"Kohtla-Jarve" +EE,07,"Laanemaa" +EE,08,"Laane-Virumaa" +EE,09,"Narva" +EE,10,"Parnu" +EE,11,"Parnumaa" +EE,12,"Polvamaa" +EE,13,"Raplamaa" +EE,14,"Saaremaa" +EE,15,"Sillamae" +EE,16,"Tallinn" +EE,17,"Tartu" +EE,18,"Tartumaa" +EE,19,"Valgamaa" +EE,20,"Viljandimaa" +EE,21,"Vorumaa" +EG,01,"Ad Daqahliyah" +EG,02,"Al Bahr al Ahmar" +EG,03,"Al Buhayrah" +EG,04,"Al Fayyum" +EG,05,"Al Gharbiyah" +EG,06,"Al Iskandariyah" +EG,07,"Al Isma'iliyah" +EG,08,"Al Jizah" +EG,09,"Al Minufiyah" +EG,10,"Al Minya" +EG,11,"Al Qahirah" +EG,12,"Al Qalyubiyah" +EG,13,"Al Wadi al Jadid" +EG,14,"Ash Sharqiyah" +EG,15,"As Suways" +EG,16,"Aswan" +EG,17,"Asyut" +EG,18,"Bani Suwayf" +EG,19,"Bur Sa'id" +EG,20,"Dumyat" +EG,21,"Kafr ash Shaykh" +EG,22,"Matruh" +EG,23,"Qina" +EG,24,"Suhaj" +EG,26,"Janub Sina'" +EG,27,"Shamal Sina'" +EG,28,"Al Uqsur" +ER,01,"Anseba" +ER,02,"Debub" +ER,03,"Debubawi K'eyih Bahri" +ER,04,"Gash Barka" +ER,05,"Ma'akel" +ER,06,"Semenawi K'eyih Bahri" +ES,07,"Islas Baleares" +ES,27,"La Rioja" +ES,29,"Madrid" +ES,31,"Murcia" +ES,32,"Navarra" +ES,34,"Asturias" +ES,39,"Cantabria" +ES,51,"Andalucia" +ES,52,"Aragon" +ES,53,"Canarias" +ES,54,"Castilla-La Mancha" +ES,55,"Castilla y Leon" +ES,56,"Catalonia" +ES,57,"Extremadura" +ES,58,"Galicia" +ES,59,"Pais Vasco" +ES,60,"Comunidad Valenciana" +ET,44,"Adis Abeba" +ET,45,"Afar" +ET,46,"Amara" +ET,47,"Binshangul Gumuz" +ET,48,"Dire Dawa" +ET,49,"Gambela Hizboch" +ET,50,"Hareri Hizb" +ET,51,"Oromiya" +ET,52,"Sumale" +ET,53,"Tigray" +ET,54,"YeDebub Biheroch Bihereseboch na Hizboch" +FI,01,"Aland" +FI,06,"Lapland" +FI,08,"Oulu" +FI,13,"Southern Finland" +FI,14,"Eastern Finland" +FI,15,"Western Finland" +FJ,01,"Central" +FJ,02,"Eastern" +FJ,03,"Northern" +FJ,04,"Rotuma" +FJ,05,"Western" +FM,01,"Kosrae" +FM,02,"Pohnpei" +FM,03,"Chuuk" +FM,04,"Yap" +FR,97,"Aquitaine" +FR,98,"Auvergne" +FR,99,"Basse-Normandie" +FR,A1,"Bourgogne" +FR,A2,"Bretagne" +FR,A3,"Centre" +FR,A4,"Champagne-Ardenne" +FR,A5,"Corse" +FR,A6,"Franche-Comte" +FR,A7,"Haute-Normandie" +FR,A8,"Ile-de-France" +FR,A9,"Languedoc-Roussillon" +FR,B1,"Limousin" +FR,B2,"Lorraine" +FR,B3,"Midi-Pyrenees" +FR,B4,"Nord-Pas-de-Calais" +FR,B5,"Pays de la Loire" +FR,B6,"Picardie" +FR,B7,"Poitou-Charentes" +FR,B8,"Provence-Alpes-Cote d'Azur" +FR,B9,"Rhone-Alpes" +FR,C1,"Alsace" +GA,01,"Estuaire" +GA,02,"Haut-Ogooue" +GA,03,"Moyen-Ogooue" +GA,04,"Ngounie" +GA,05,"Nyanga" +GA,06,"Ogooue-Ivindo" +GA,07,"Ogooue-Lolo" +GA,08,"Ogooue-Maritime" +GA,09,"Woleu-Ntem" +GB,A1,"Barking and Dagenham" +GB,A2,"Barnet" +GB,A3,"Barnsley" +GB,A4,"Bath and North East Somerset" +GB,A5,"Bedfordshire" +GB,A6,"Bexley" +GB,A7,"Birmingham" +GB,A8,"Blackburn with Darwen" +GB,A9,"Blackpool" +GB,B1,"Bolton" +GB,B2,"Bournemouth" +GB,B3,"Bracknell Forest" +GB,B4,"Bradford" +GB,B5,"Brent" +GB,B6,"Brighton and Hove" +GB,B7,"Bristol, City of" +GB,B8,"Bromley" +GB,B9,"Buckinghamshire" +GB,C1,"Bury" +GB,C2,"Calderdale" +GB,C3,"Cambridgeshire" +GB,C4,"Camden" +GB,C5,"Cheshire" +GB,C6,"Cornwall" +GB,C7,"Coventry" +GB,C8,"Croydon" +GB,C9,"Cumbria" +GB,D1,"Darlington" +GB,D2,"Derby" +GB,D3,"Derbyshire" +GB,D4,"Devon" +GB,D5,"Doncaster" +GB,D6,"Dorset" +GB,D7,"Dudley" +GB,D8,"Durham" +GB,D9,"Ealing" +GB,E1,"East Riding of Yorkshire" +GB,E2,"East Sussex" +GB,E3,"Enfield" +GB,E4,"Essex" +GB,E5,"Gateshead" +GB,E6,"Gloucestershire" +GB,E7,"Greenwich" +GB,E8,"Hackney" +GB,E9,"Halton" +GB,F1,"Hammersmith and Fulham" +GB,F2,"Hampshire" +GB,F3,"Haringey" +GB,F4,"Harrow" +GB,F5,"Hartlepool" +GB,F6,"Havering" +GB,F7,"Herefordshire" +GB,F8,"Hertford" +GB,F9,"Hillingdon" +GB,G1,"Hounslow" +GB,G2,"Isle of Wight" +GB,G3,"Islington" +GB,G4,"Kensington and Chelsea" +GB,G5,"Kent" +GB,G6,"Kingston upon Hull, City of" +GB,G7,"Kingston upon Thames" +GB,G8,"Kirklees" +GB,G9,"Knowsley" +GB,H1,"Lambeth" +GB,H2,"Lancashire" +GB,H3,"Leeds" +GB,H4,"Leicester" +GB,H5,"Leicestershire" +GB,H6,"Lewisham" +GB,H7,"Lincolnshire" +GB,H8,"Liverpool" +GB,H9,"London, City of" +GB,I1,"Luton" +GB,I2,"Manchester" +GB,I3,"Medway" +GB,I4,"Merton" +GB,I5,"Middlesbrough" +GB,I6,"Milton Keynes" +GB,I7,"Newcastle upon Tyne" +GB,I8,"Newham" +GB,I9,"Norfolk" +GB,J1,"Northamptonshire" +GB,J2,"North East Lincolnshire" +GB,J3,"North Lincolnshire" +GB,J4,"North Somerset" +GB,J5,"North Tyneside" +GB,J6,"Northumberland" +GB,J7,"North Yorkshire" +GB,J8,"Nottingham" +GB,J9,"Nottinghamshire" +GB,K1,"Oldham" +GB,K2,"Oxfordshire" +GB,K3,"Peterborough" +GB,K4,"Plymouth" +GB,K5,"Poole" +GB,K6,"Portsmouth" +GB,K7,"Reading" +GB,K8,"Redbridge" +GB,K9,"Redcar and Cleveland" +GB,L1,"Richmond upon Thames" +GB,L2,"Rochdale" +GB,L3,"Rotherham" +GB,L4,"Rutland" +GB,L5,"Salford" +GB,L6,"Shropshire" +GB,L7,"Sandwell" +GB,L8,"Sefton" +GB,L9,"Sheffield" +GB,M1,"Slough" +GB,M2,"Solihull" +GB,M3,"Somerset" +GB,M4,"Southampton" +GB,M5,"Southend-on-Sea" +GB,M6,"South Gloucestershire" +GB,M7,"South Tyneside" +GB,M8,"Southwark" +GB,M9,"Staffordshire" +GB,N1,"St. Helens" +GB,N2,"Stockport" +GB,N3,"Stockton-on-Tees" +GB,N4,"Stoke-on-Trent" +GB,N5,"Suffolk" +GB,N6,"Sunderland" +GB,N7,"Surrey" +GB,N8,"Sutton" +GB,N9,"Swindon" +GB,O1,"Tameside" +GB,O2,"Telford and Wrekin" +GB,O3,"Thurrock" +GB,O4,"Torbay" +GB,O5,"Tower Hamlets" +GB,O6,"Trafford" +GB,O7,"Wakefield" +GB,O8,"Walsall" +GB,O9,"Waltham Forest" +GB,P1,"Wandsworth" +GB,P2,"Warrington" +GB,P3,"Warwickshire" +GB,P4,"West Berkshire" +GB,P5,"Westminster" +GB,P6,"West Sussex" +GB,P7,"Wigan" +GB,P8,"Wiltshire" +GB,P9,"Windsor and Maidenhead" +GB,Q1,"Wirral" +GB,Q2,"Wokingham" +GB,Q3,"Wolverhampton" +GB,Q4,"Worcestershire" +GB,Q5,"York" +GB,Q6,"Antrim" +GB,Q7,"Ards" +GB,Q8,"Armagh" +GB,Q9,"Ballymena" +GB,R1,"Ballymoney" +GB,R2,"Banbridge" +GB,R3,"Belfast" +GB,R4,"Carrickfergus" +GB,R5,"Castlereagh" +GB,R6,"Coleraine" +GB,R7,"Cookstown" +GB,R8,"Craigavon" +GB,R9,"Down" +GB,S1,"Dungannon" +GB,S2,"Fermanagh" +GB,S3,"Larne" +GB,S4,"Limavady" +GB,S5,"Lisburn" +GB,S6,"Derry" +GB,S7,"Magherafelt" +GB,S8,"Moyle" +GB,S9,"Newry and Mourne" +GB,T1,"Newtownabbey" +GB,T2,"North Down" +GB,T3,"Omagh" +GB,T4,"Strabane" +GB,T5,"Aberdeen City" +GB,T6,"Aberdeenshire" +GB,T7,"Angus" +GB,T8,"Argyll and Bute" +GB,T9,"Scottish Borders, The" +GB,U1,"Clackmannanshire" +GB,U2,"Dumfries and Galloway" +GB,U3,"Dundee City" +GB,U4,"East Ayrshire" +GB,U5,"East Dunbartonshire" +GB,U6,"East Lothian" +GB,U7,"East Renfrewshire" +GB,U8,"Edinburgh, City of" +GB,U9,"Falkirk" +GB,V1,"Fife" +GB,V2,"Glasgow City" +GB,V3,"Highland" +GB,V4,"Inverclyde" +GB,V5,"Midlothian" +GB,V6,"Moray" +GB,V7,"North Ayrshire" +GB,V8,"North Lanarkshire" +GB,V9,"Orkney" +GB,W1,"Perth and Kinross" +GB,W2,"Renfrewshire" +GB,W3,"Shetland Islands" +GB,W4,"South Ayrshire" +GB,W5,"South Lanarkshire" +GB,W6,"Stirling" +GB,W7,"West Dunbartonshire" +GB,W8,"Eilean Siar" +GB,W9,"West Lothian" +GB,X1,"Isle of Anglesey" +GB,X2,"Blaenau Gwent" +GB,X3,"Bridgend" +GB,X4,"Caerphilly" +GB,X5,"Cardiff" +GB,X6,"Ceredigion" +GB,X7,"Carmarthenshire" +GB,X8,"Conwy" +GB,X9,"Denbighshire" +GB,Y1,"Flintshire" +GB,Y2,"Gwynedd" +GB,Y3,"Merthyr Tydfil" +GB,Y4,"Monmouthshire" +GB,Y5,"Neath Port Talbot" +GB,Y6,"Newport" +GB,Y7,"Pembrokeshire" +GB,Y8,"Powys" +GB,Y9,"Rhondda Cynon Taff" +GB,Z1,"Swansea" +GB,Z2,"Torfaen" +GB,Z3,"Vale of Glamorgan, The" +GB,Z4,"Wrexham" +GB,Z5,"Bedfordshire" +GB,Z6,"Central Bedfordshire" +GB,Z7,"Cheshire East" +GB,Z8,"Cheshire West and Chester" +GB,Z9,"Isles of Scilly" +GD,01,"Saint Andrew" +GD,02,"Saint David" +GD,03,"Saint George" +GD,04,"Saint John" +GD,05,"Saint Mark" +GD,06,"Saint Patrick" +GE,01,"Abashis Raioni" +GE,02,"Abkhazia" +GE,03,"Adigenis Raioni" +GE,04,"Ajaria" +GE,05,"Akhalgoris Raioni" +GE,06,"Akhalk'alak'is Raioni" +GE,07,"Akhalts'ikhis Raioni" +GE,08,"Akhmetis Raioni" +GE,09,"Ambrolauris Raioni" +GE,10,"Aspindzis Raioni" +GE,11,"Baghdat'is Raioni" +GE,12,"Bolnisis Raioni" +GE,13,"Borjomis Raioni" +GE,14,"Chiat'ura" +GE,15,"Ch'khorotsqus Raioni" +GE,16,"Ch'okhatauris Raioni" +GE,17,"Dedop'listsqaros Raioni" +GE,18,"Dmanisis Raioni" +GE,19,"Dushet'is Raioni" +GE,20,"Gardabanis Raioni" +GE,21,"Gori" +GE,22,"Goris Raioni" +GE,23,"Gurjaanis Raioni" +GE,24,"Javis Raioni" +GE,25,"K'arelis Raioni" +GE,26,"Kaspis Raioni" +GE,27,"Kharagaulis Raioni" +GE,28,"Khashuris Raioni" +GE,29,"Khobis Raioni" +GE,30,"Khonis Raioni" +GE,31,"K'ut'aisi" +GE,32,"Lagodekhis Raioni" +GE,33,"Lanch'khut'is Raioni" +GE,34,"Lentekhis Raioni" +GE,35,"Marneulis Raioni" +GE,36,"Martvilis Raioni" +GE,37,"Mestiis Raioni" +GE,38,"Mts'khet'is Raioni" +GE,39,"Ninotsmindis Raioni" +GE,40,"Onis Raioni" +GE,41,"Ozurget'is Raioni" +GE,42,"P'ot'i" +GE,43,"Qazbegis Raioni" +GE,44,"Qvarlis Raioni" +GE,45,"Rust'avi" +GE,46,"Sach'kheris Raioni" +GE,47,"Sagarejos Raioni" +GE,48,"Samtrediis Raioni" +GE,49,"Senakis Raioni" +GE,50,"Sighnaghis Raioni" +GE,51,"T'bilisi" +GE,52,"T'elavis Raioni" +GE,53,"T'erjolis Raioni" +GE,54,"T'et'ritsqaros Raioni" +GE,55,"T'ianet'is Raioni" +GE,56,"Tqibuli" +GE,57,"Ts'ageris Raioni" +GE,58,"Tsalenjikhis Raioni" +GE,59,"Tsalkis Raioni" +GE,60,"Tsqaltubo" +GE,61,"Vanis Raioni" +GE,62,"Zestap'onis Raioni" +GE,63,"Zugdidi" +GE,64,"Zugdidis Raioni" +GH,01,"Greater Accra" +GH,02,"Ashanti" +GH,03,"Brong-Ahafo" +GH,04,"Central" +GH,05,"Eastern" +GH,06,"Northern" +GH,08,"Volta" +GH,09,"Western" +GH,10,"Upper East" +GH,11,"Upper West" +GL,01,"Nordgronland" +GL,02,"Ostgronland" +GL,03,"Vestgronland" +GM,01,"Banjul" +GM,02,"Lower River" +GM,03,"Central River" +GM,04,"Upper River" +GM,05,"Western" +GM,07,"North Bank" +GN,01,"Beyla" +GN,02,"Boffa" +GN,03,"Boke" +GN,04,"Conakry" +GN,05,"Dabola" +GN,06,"Dalaba" +GN,07,"Dinguiraye" +GN,09,"Faranah" +GN,10,"Forecariah" +GN,11,"Fria" +GN,12,"Gaoual" +GN,13,"Gueckedou" +GN,15,"Kerouane" +GN,16,"Kindia" +GN,17,"Kissidougou" +GN,18,"Koundara" +GN,19,"Kouroussa" +GN,21,"Macenta" +GN,22,"Mali" +GN,23,"Mamou" +GN,25,"Pita" +GN,27,"Telimele" +GN,28,"Tougue" +GN,29,"Yomou" +GN,30,"Coyah" +GN,31,"Dubreka" +GN,32,"Kankan" +GN,33,"Koubia" +GN,34,"Labe" +GN,35,"Lelouma" +GN,36,"Lola" +GN,37,"Mandiana" +GN,38,"Nzerekore" +GN,39,"Siguiri" +GQ,03,"Annobon" +GQ,04,"Bioko Norte" +GQ,05,"Bioko Sur" +GQ,06,"Centro Sur" +GQ,07,"Kie-Ntem" +GQ,08,"Litoral" +GQ,09,"Wele-Nzas" +GR,01,"Evros" +GR,02,"Rodhopi" +GR,03,"Xanthi" +GR,04,"Drama" +GR,05,"Serrai" +GR,06,"Kilkis" +GR,07,"Pella" +GR,08,"Florina" +GR,09,"Kastoria" +GR,10,"Grevena" +GR,11,"Kozani" +GR,12,"Imathia" +GR,13,"Thessaloniki" +GR,14,"Kavala" +GR,15,"Khalkidhiki" +GR,16,"Pieria" +GR,17,"Ioannina" +GR,18,"Thesprotia" +GR,19,"Preveza" +GR,20,"Arta" +GR,21,"Larisa" +GR,22,"Trikala" +GR,23,"Kardhitsa" +GR,24,"Magnisia" +GR,25,"Kerkira" +GR,26,"Levkas" +GR,27,"Kefallinia" +GR,28,"Zakinthos" +GR,29,"Fthiotis" +GR,30,"Evritania" +GR,31,"Aitolia kai Akarnania" +GR,32,"Fokis" +GR,33,"Voiotia" +GR,34,"Evvoia" +GR,35,"Attiki" +GR,36,"Argolis" +GR,37,"Korinthia" +GR,38,"Akhaia" +GR,39,"Ilia" +GR,40,"Messinia" +GR,41,"Arkadhia" +GR,42,"Lakonia" +GR,43,"Khania" +GR,44,"Rethimni" +GR,45,"Iraklion" +GR,46,"Lasithi" +GR,47,"Dhodhekanisos" +GR,48,"Samos" +GR,49,"Kikladhes" +GR,50,"Khios" +GR,51,"Lesvos" +GT,01,"Alta Verapaz" +GT,02,"Baja Verapaz" +GT,03,"Chimaltenango" +GT,04,"Chiquimula" +GT,05,"El Progreso" +GT,06,"Escuintla" +GT,07,"Guatemala" +GT,08,"Huehuetenango" +GT,09,"Izabal" +GT,10,"Jalapa" +GT,11,"Jutiapa" +GT,12,"Peten" +GT,13,"Quetzaltenango" +GT,14,"Quiche" +GT,15,"Retalhuleu" +GT,16,"Sacatepequez" +GT,17,"San Marcos" +GT,18,"Santa Rosa" +GT,19,"Solola" +GT,20,"Suchitepequez" +GT,21,"Totonicapan" +GT,22,"Zacapa" +GW,01,"Bafata" +GW,02,"Quinara" +GW,04,"Oio" +GW,05,"Bolama" +GW,06,"Cacheu" +GW,07,"Tombali" +GW,10,"Gabu" +GW,11,"Bissau" +GW,12,"Biombo" +GY,10,"Barima-Waini" +GY,11,"Cuyuni-Mazaruni" +GY,12,"Demerara-Mahaica" +GY,13,"East Berbice-Corentyne" +GY,14,"Essequibo Islands-West Demerara" +GY,15,"Mahaica-Berbice" +GY,16,"Pomeroon-Supenaam" +GY,17,"Potaro-Siparuni" +GY,18,"Upper Demerara-Berbice" +GY,19,"Upper Takutu-Upper Essequibo" +HN,01,"Atlantida" +HN,02,"Choluteca" +HN,03,"Colon" +HN,04,"Comayagua" +HN,05,"Copan" +HN,06,"Cortes" +HN,07,"El Paraiso" +HN,08,"Francisco Morazan" +HN,09,"Gracias a Dios" +HN,10,"Intibuca" +HN,11,"Islas de la Bahia" +HN,12,"La Paz" +HN,13,"Lempira" +HN,14,"Ocotepeque" +HN,15,"Olancho" +HN,16,"Santa Barbara" +HN,17,"Valle" +HN,18,"Yoro" +HR,01,"Bjelovarsko-Bilogorska" +HR,02,"Brodsko-Posavska" +HR,03,"Dubrovacko-Neretvanska" +HR,04,"Istarska" +HR,05,"Karlovacka" +HR,06,"Koprivnicko-Krizevacka" +HR,07,"Krapinsko-Zagorska" +HR,08,"Licko-Senjska" +HR,09,"Medimurska" +HR,10,"Osjecko-Baranjska" +HR,11,"Pozesko-Slavonska" +HR,12,"Primorsko-Goranska" +HR,13,"Sibensko-Kninska" +HR,14,"Sisacko-Moslavacka" +HR,15,"Splitsko-Dalmatinska" +HR,16,"Varazdinska" +HR,17,"Viroviticko-Podravska" +HR,18,"Vukovarsko-Srijemska" +HR,19,"Zadarska" +HR,20,"Zagrebacka" +HR,21,"Grad Zagreb" +HT,03,"Nord-Ouest" +HT,06,"Artibonite" +HT,07,"Centre" +HT,09,"Nord" +HT,10,"Nord-Est" +HT,11,"Ouest" +HT,12,"Sud" +HT,13,"Sud-Est" +HT,14,"Grand' Anse" +HT,15,"Nippes" +HU,01,"Bacs-Kiskun" +HU,02,"Baranya" +HU,03,"Bekes" +HU,04,"Borsod-Abauj-Zemplen" +HU,05,"Budapest" +HU,06,"Csongrad" +HU,07,"Debrecen" +HU,08,"Fejer" +HU,09,"Gyor-Moson-Sopron" +HU,10,"Hajdu-Bihar" +HU,11,"Heves" +HU,12,"Komarom-Esztergom" +HU,13,"Miskolc" +HU,14,"Nograd" +HU,15,"Pecs" +HU,16,"Pest" +HU,17,"Somogy" +HU,18,"Szabolcs-Szatmar-Bereg" +HU,19,"Szeged" +HU,20,"Jasz-Nagykun-Szolnok" +HU,21,"Tolna" +HU,22,"Vas" +HU,23,"Veszprem" +HU,24,"Zala" +HU,25,"Gyor" +HU,26,"Bekescsaba" +HU,27,"Dunaujvaros" +HU,28,"Eger" +HU,29,"Hodmezovasarhely" +HU,30,"Kaposvar" +HU,31,"Kecskemet" +HU,32,"Nagykanizsa" +HU,33,"Nyiregyhaza" +HU,34,"Sopron" +HU,35,"Szekesfehervar" +HU,36,"Szolnok" +HU,37,"Szombathely" +HU,38,"Tatabanya" +HU,39,"Veszprem" +HU,40,"Zalaegerszeg" +HU,41,"Salgotarjan" +HU,42,"Szekszard" +HU,43,"Erd" +ID,01,"Aceh" +ID,02,"Bali" +ID,03,"Bengkulu" +ID,04,"Jakarta Raya" +ID,05,"Jambi" +ID,07,"Jawa Tengah" +ID,08,"Jawa Timur" +ID,10,"Yogyakarta" +ID,11,"Kalimantan Barat" +ID,12,"Kalimantan Selatan" +ID,13,"Kalimantan Tengah" +ID,14,"Kalimantan Timur" +ID,15,"Lampung" +ID,17,"Nusa Tenggara Barat" +ID,18,"Nusa Tenggara Timur" +ID,21,"Sulawesi Tengah" +ID,22,"Sulawesi Tenggara" +ID,24,"Sumatera Barat" +ID,26,"Sumatera Utara" +ID,28,"Maluku" +ID,29,"Maluku Utara" +ID,30,"Jawa Barat" +ID,31,"Sulawesi Utara" +ID,32,"Sumatera Selatan" +ID,33,"Banten" +ID,34,"Gorontalo" +ID,35,"Kepulauan Bangka Belitung" +ID,36,"Papua" +ID,37,"Riau" +ID,38,"Sulawesi Selatan" +ID,39,"Irian Jaya Barat" +ID,40,"Kepulauan Riau" +ID,41,"Sulawesi Barat" +IE,01,"Carlow" +IE,02,"Cavan" +IE,03,"Clare" +IE,04,"Cork" +IE,06,"Donegal" +IE,07,"Dublin" +IE,10,"Galway" +IE,11,"Kerry" +IE,12,"Kildare" +IE,13,"Kilkenny" +IE,14,"Leitrim" +IE,15,"Laois" +IE,16,"Limerick" +IE,18,"Longford" +IE,19,"Louth" +IE,20,"Mayo" +IE,21,"Meath" +IE,22,"Monaghan" +IE,23,"Offaly" +IE,24,"Roscommon" +IE,25,"Sligo" +IE,26,"Tipperary" +IE,27,"Waterford" +IE,29,"Westmeath" +IE,30,"Wexford" +IE,31,"Wicklow" +IL,01,"HaDarom" +IL,02,"HaMerkaz" +IL,03,"HaZafon" +IL,04,"Hefa" +IL,05,"Tel Aviv" +IL,06,"Yerushalayim" +IN,01,"Andaman and Nicobar Islands" +IN,02,"Andhra Pradesh" +IN,03,"Assam" +IN,05,"Chandigarh" +IN,06,"Dadra and Nagar Haveli" +IN,07,"Delhi" +IN,09,"Gujarat" +IN,10,"Haryana" +IN,11,"Himachal Pradesh" +IN,12,"Jammu and Kashmir" +IN,13,"Kerala" +IN,14,"Lakshadweep" +IN,16,"Maharashtra" +IN,17,"Manipur" +IN,18,"Meghalaya" +IN,19,"Karnataka" +IN,20,"Nagaland" +IN,21,"Orissa" +IN,22,"Puducherry" +IN,23,"Punjab" +IN,24,"Rajasthan" +IN,25,"Tamil Nadu" +IN,26,"Tripura" +IN,28,"West Bengal" +IN,29,"Sikkim" +IN,30,"Arunachal Pradesh" +IN,31,"Mizoram" +IN,32,"Daman and Diu" +IN,33,"Goa" +IN,34,"Bihar" +IN,35,"Madhya Pradesh" +IN,36,"Uttar Pradesh" +IN,37,"Chhattisgarh" +IN,38,"Jharkhand" +IN,39,"Uttarakhand" +IQ,01,"Al Anbar" +IQ,02,"Al Basrah" +IQ,03,"Al Muthanna" +IQ,04,"Al Qadisiyah" +IQ,05,"As Sulaymaniyah" +IQ,06,"Babil" +IQ,07,"Baghdad" +IQ,08,"Dahuk" +IQ,09,"Dhi Qar" +IQ,10,"Diyala" +IQ,11,"Arbil" +IQ,12,"Karbala'" +IQ,13,"At Ta'mim" +IQ,14,"Maysan" +IQ,15,"Ninawa" +IQ,16,"Wasit" +IQ,17,"An Najaf" +IQ,18,"Salah ad Din" +IR,01,"Azarbayjan-e Bakhtari" +IR,03,"Chahar Mahall va Bakhtiari" +IR,04,"Sistan va Baluchestan" +IR,05,"Kohkiluyeh va Buyer Ahmadi" +IR,07,"Fars" +IR,08,"Gilan" +IR,09,"Hamadan" +IR,10,"Ilam" +IR,11,"Hormozgan" +IR,12,"Kerman" +IR,13,"Bakhtaran" +IR,15,"Khuzestan" +IR,16,"Kordestan" +IR,17,"Mazandaran" +IR,18,"Semnan Province" +IR,19,"Markazi" +IR,21,"Zanjan" +IR,22,"Bushehr" +IR,23,"Lorestan" +IR,24,"Markazi" +IR,25,"Semnan" +IR,26,"Tehran" +IR,27,"Zanjan" +IR,28,"Esfahan" +IR,29,"Kerman" +IR,30,"Khorasan" +IR,31,"Yazd" +IR,32,"Ardabil" +IR,33,"East Azarbaijan" +IR,34,"Markazi" +IR,35,"Mazandaran" +IR,36,"Zanjan" +IR,37,"Golestan" +IR,38,"Qazvin" +IR,39,"Qom" +IR,40,"Yazd" +IR,41,"Khorasan-e Janubi" +IR,42,"Khorasan-e Razavi" +IR,43,"Khorasan-e Shemali" +IR,44,"Alborz" +IS,03,"Arnessysla" +IS,05,"Austur-Hunavatnssysla" +IS,06,"Austur-Skaftafellssysla" +IS,07,"Borgarfjardarsysla" +IS,09,"Eyjafjardarsysla" +IS,10,"Gullbringusysla" +IS,15,"Kjosarsysla" +IS,17,"Myrasysla" +IS,20,"Nordur-Mulasysla" +IS,21,"Nordur-Tingeyjarsysla" +IS,23,"Rangarvallasysla" +IS,28,"Skagafjardarsysla" +IS,29,"Snafellsnes- og Hnappadalssysla" +IS,30,"Strandasysla" +IS,31,"Sudur-Mulasysla" +IS,32,"Sudur-Tingeyjarsysla" +IS,34,"Vestur-Bardastrandarsysla" +IS,35,"Vestur-Hunavatnssysla" +IS,36,"Vestur-Isafjardarsysla" +IS,37,"Vestur-Skaftafellssysla" +IS,38,"Austurland" +IS,39,"Hofuoborgarsvaoio" +IS,40,"Norourland Eystra" +IS,41,"Norourland Vestra" +IS,42,"Suourland" +IS,43,"Suournes" +IS,44,"Vestfiroir" +IS,45,"Vesturland" +IT,01,"Abruzzi" +IT,02,"Basilicata" +IT,03,"Calabria" +IT,04,"Campania" +IT,05,"Emilia-Romagna" +IT,06,"Friuli-Venezia Giulia" +IT,07,"Lazio" +IT,08,"Liguria" +IT,09,"Lombardia" +IT,10,"Marche" +IT,11,"Molise" +IT,12,"Piemonte" +IT,13,"Puglia" +IT,14,"Sardegna" +IT,15,"Sicilia" +IT,16,"Toscana" +IT,17,"Trentino-Alto Adige" +IT,18,"Umbria" +IT,19,"Valle d'Aosta" +IT,20,"Veneto" +JM,01,"Clarendon" +JM,02,"Hanover" +JM,04,"Manchester" +JM,07,"Portland" +JM,08,"Saint Andrew" +JM,09,"Saint Ann" +JM,10,"Saint Catherine" +JM,11,"Saint Elizabeth" +JM,12,"Saint James" +JM,13,"Saint Mary" +JM,14,"Saint Thomas" +JM,15,"Trelawny" +JM,16,"Westmoreland" +JM,17,"Kingston" +JO,02,"Al Balqa'" +JO,09,"Al Karak" +JO,12,"At Tafilah" +JO,15,"Al Mafraq" +JO,16,"Amman" +JO,17,"Az Zaraqa" +JO,18,"Irbid" +JO,19,"Ma'an" +JO,20,"Ajlun" +JO,21,"Al Aqabah" +JO,22,"Jarash" +JO,23,"Madaba" +JP,01,"Aichi" +JP,02,"Akita" +JP,03,"Aomori" +JP,04,"Chiba" +JP,05,"Ehime" +JP,06,"Fukui" +JP,07,"Fukuoka" +JP,08,"Fukushima" +JP,09,"Gifu" +JP,10,"Gumma" +JP,11,"Hiroshima" +JP,12,"Hokkaido" +JP,13,"Hyogo" +JP,14,"Ibaraki" +JP,15,"Ishikawa" +JP,16,"Iwate" +JP,17,"Kagawa" +JP,18,"Kagoshima" +JP,19,"Kanagawa" +JP,20,"Kochi" +JP,21,"Kumamoto" +JP,22,"Kyoto" +JP,23,"Mie" +JP,24,"Miyagi" +JP,25,"Miyazaki" +JP,26,"Nagano" +JP,27,"Nagasaki" +JP,28,"Nara" +JP,29,"Niigata" +JP,30,"Oita" +JP,31,"Okayama" +JP,32,"Osaka" +JP,33,"Saga" +JP,34,"Saitama" +JP,35,"Shiga" +JP,36,"Shimane" +JP,37,"Shizuoka" +JP,38,"Tochigi" +JP,39,"Tokushima" +JP,40,"Tokyo" +JP,41,"Tottori" +JP,42,"Toyama" +JP,43,"Wakayama" +JP,44,"Yamagata" +JP,45,"Yamaguchi" +JP,46,"Yamanashi" +JP,47,"Okinawa" +KE,01,"Central" +KE,02,"Coast" +KE,03,"Eastern" +KE,05,"Nairobi Area" +KE,06,"North-Eastern" +KE,07,"Nyanza" +KE,08,"Rift Valley" +KE,09,"Western" +KG,01,"Bishkek" +KG,02,"Chuy" +KG,03,"Jalal-Abad" +KG,04,"Naryn" +KG,05,"Osh" +KG,06,"Talas" +KG,07,"Ysyk-Kol" +KG,08,"Osh" +KG,09,"Batken" +KH,01,"Batdambang" +KH,02,"Kampong Cham" +KH,03,"Kampong Chhnang" +KH,04,"Kampong Speu" +KH,05,"Kampong Thum" +KH,06,"Kampot" +KH,07,"Kandal" +KH,08,"Koh Kong" +KH,09,"Kracheh" +KH,10,"Mondulkiri" +KH,11,"Phnum Penh" +KH,12,"Pursat" +KH,13,"Preah Vihear" +KH,14,"Prey Veng" +KH,15,"Ratanakiri Kiri" +KH,16,"Siem Reap" +KH,17,"Stung Treng" +KH,18,"Svay Rieng" +KH,19,"Takeo" +KH,22,"Phnum Penh" +KH,23,"Ratanakiri" +KH,25,"Banteay Meanchey" +KH,28,"Preah Seihanu" +KH,29,"Batdambang" +KH,30,"Pailin" +KI,01,"Gilbert Islands" +KI,02,"Line Islands" +KI,03,"Phoenix Islands" +KM,01,"Anjouan" +KM,02,"Grande Comore" +KM,03,"Moheli" +KN,01,"Christ Church Nichola Town" +KN,02,"Saint Anne Sandy Point" +KN,03,"Saint George Basseterre" +KN,04,"Saint George Gingerland" +KN,05,"Saint James Windward" +KN,06,"Saint John Capisterre" +KN,07,"Saint John Figtree" +KN,08,"Saint Mary Cayon" +KN,09,"Saint Paul Capisterre" +KN,10,"Saint Paul Charlestown" +KN,11,"Saint Peter Basseterre" +KN,12,"Saint Thomas Lowland" +KN,13,"Saint Thomas Middle Island" +KN,15,"Trinity Palmetto Point" +KP,01,"Chagang-do" +KP,03,"Hamgyong-namdo" +KP,06,"Hwanghae-namdo" +KP,07,"Hwanghae-bukto" +KP,08,"Kaesong-si" +KP,09,"Kangwon-do" +KP,11,"P'yongan-bukto" +KP,12,"P'yongyang-si" +KP,13,"Yanggang-do" +KP,14,"Namp'o-si" +KP,15,"P'yongan-namdo" +KP,17,"Hamgyong-bukto" +KP,18,"Najin Sonbong-si" +KR,01,"Cheju-do" +KR,03,"Cholla-bukto" +KR,05,"Ch'ungch'ong-bukto" +KR,06,"Kangwon-do" +KR,10,"Pusan-jikhalsi" +KR,11,"Seoul-t'ukpyolsi" +KR,12,"Inch'on-jikhalsi" +KR,13,"Kyonggi-do" +KR,14,"Kyongsang-bukto" +KR,15,"Taegu-jikhalsi" +KR,16,"Cholla-namdo" +KR,17,"Ch'ungch'ong-namdo" +KR,18,"Kwangju-jikhalsi" +KR,19,"Taejon-jikhalsi" +KR,20,"Kyongsang-namdo" +KR,21,"Ulsan-gwangyoksi" +KW,01,"Al Ahmadi" +KW,02,"Al Kuwayt" +KW,05,"Al Jahra" +KW,07,"Al Farwaniyah" +KW,08,"Hawalli" +KW,09,"Mubarak al Kabir" +KY,01,"Creek" +KY,02,"Eastern" +KY,03,"Midland" +KY,04,"South Town" +KY,05,"Spot Bay" +KY,06,"Stake Bay" +KY,07,"West End" +KY,08,"Western" +KZ,01,"Almaty" +KZ,02,"Almaty City" +KZ,03,"Aqmola" +KZ,04,"Aqtobe" +KZ,05,"Astana" +KZ,06,"Atyrau" +KZ,07,"West Kazakhstan" +KZ,08,"Bayqonyr" +KZ,09,"Mangghystau" +KZ,10,"South Kazakhstan" +KZ,11,"Pavlodar" +KZ,12,"Qaraghandy" +KZ,13,"Qostanay" +KZ,14,"Qyzylorda" +KZ,15,"East Kazakhstan" +KZ,16,"North Kazakhstan" +KZ,17,"Zhambyl" +LA,01,"Attapu" +LA,02,"Champasak" +LA,03,"Houaphan" +LA,04,"Khammouan" +LA,05,"Louang Namtha" +LA,07,"Oudomxai" +LA,08,"Phongsali" +LA,09,"Saravan" +LA,10,"Savannakhet" +LA,11,"Vientiane" +LA,13,"Xaignabouri" +LA,14,"Xiangkhoang" +LA,17,"Louangphrabang" +LB,01,"Beqaa" +LB,02,"Al Janub" +LB,03,"Liban-Nord" +LB,04,"Beyrouth" +LB,05,"Mont-Liban" +LB,06,"Liban-Sud" +LB,07,"Nabatiye" +LB,08,"Beqaa" +LB,09,"Liban-Nord" +LB,10,"Aakk,r" +LB,11,"Baalbek-Hermel" +LC,01,"Anse-la-Raye" +LC,02,"Dauphin" +LC,03,"Castries" +LC,04,"Choiseul" +LC,05,"Dennery" +LC,06,"Gros-Islet" +LC,07,"Laborie" +LC,08,"Micoud" +LC,09,"Soufriere" +LC,10,"Vieux-Fort" +LC,11,"Praslin" +LI,01,"Balzers" +LI,02,"Eschen" +LI,03,"Gamprin" +LI,04,"Mauren" +LI,05,"Planken" +LI,06,"Ruggell" +LI,07,"Schaan" +LI,08,"Schellenberg" +LI,09,"Triesen" +LI,10,"Triesenberg" +LI,11,"Vaduz" +LI,21,"Gbarpolu" +LI,22,"River Gee" +LK,29,"Central" +LK,30,"North Central" +LK,32,"North Western" +LK,33,"Sabaragamuwa" +LK,34,"Southern" +LK,35,"Uva" +LK,36,"Western" +LK,37,"Eastern" +LK,38,"Northern" +LR,01,"Bong" +LR,04,"Grand Cape Mount" +LR,05,"Lofa" +LR,06,"Maryland" +LR,07,"Monrovia" +LR,09,"Nimba" +LR,10,"Sino" +LR,11,"Grand Bassa" +LR,12,"Grand Cape Mount" +LR,13,"Maryland" +LR,14,"Montserrado" +LR,17,"Margibi" +LR,18,"River Cess" +LR,19,"Grand Gedeh" +LR,20,"Lofa" +LR,21,"Gbarpolu" +LR,22,"River Gee" +LS,10,"Berea" +LS,11,"Butha-Buthe" +LS,12,"Leribe" +LS,13,"Mafeteng" +LS,14,"Maseru" +LS,15,"Mohales Hoek" +LS,16,"Mokhotlong" +LS,17,"Qachas Nek" +LS,18,"Quthing" +LS,19,"Thaba-Tseka" +LT,56,"Alytaus Apskritis" +LT,57,"Kauno Apskritis" +LT,58,"Klaipedos Apskritis" +LT,59,"Marijampoles Apskritis" +LT,60,"Panevezio Apskritis" +LT,61,"Siauliu Apskritis" +LT,62,"Taurages Apskritis" +LT,63,"Telsiu Apskritis" +LT,64,"Utenos Apskritis" +LT,65,"Vilniaus Apskritis" +LU,01,"Diekirch" +LU,02,"Grevenmacher" +LU,03,"Luxembourg" +LV,01,"Aizkraukles" +LV,02,"Aluksnes" +LV,03,"Balvu" +LV,04,"Bauskas" +LV,05,"Cesu" +LV,06,"Daugavpils" +LV,07,"Daugavpils" +LV,08,"Dobeles" +LV,09,"Gulbenes" +LV,10,"Jekabpils" +LV,11,"Jelgava" +LV,12,"Jelgavas" +LV,13,"Jurmala" +LV,14,"Kraslavas" +LV,15,"Kuldigas" +LV,16,"Liepaja" +LV,17,"Liepajas" +LV,18,"Limbazu" +LV,19,"Ludzas" +LV,20,"Madonas" +LV,21,"Ogres" +LV,22,"Preilu" +LV,23,"Rezekne" +LV,24,"Rezeknes" +LV,25,"Riga" +LV,26,"Rigas" +LV,27,"Saldus" +LV,28,"Talsu" +LV,29,"Tukuma" +LV,30,"Valkas" +LV,31,"Valmieras" +LV,32,"Ventspils" +LV,33,"Ventspils" +LY,03,"Al Aziziyah" +LY,05,"Al Jufrah" +LY,08,"Al Kufrah" +LY,13,"Ash Shati'" +LY,30,"Murzuq" +LY,34,"Sabha" +LY,41,"Tarhunah" +LY,42,"Tubruq" +LY,45,"Zlitan" +LY,47,"Ajdabiya" +LY,48,"Al Fatih" +LY,49,"Al Jabal al Akhdar" +LY,50,"Al Khums" +LY,51,"An Nuqat al Khams" +LY,52,"Awbari" +LY,53,"Az Zawiyah" +LY,54,"Banghazi" +LY,55,"Darnah" +LY,56,"Ghadamis" +LY,57,"Gharyan" +LY,58,"Misratah" +LY,59,"Sawfajjin" +LY,60,"Surt" +LY,61,"Tarabulus" +LY,62,"Yafran" +MA,45,"Grand Casablanca" +MA,46,"Fes-Boulemane" +MA,47,"Marrakech-Tensift-Al Haouz" +MA,48,"Meknes-Tafilalet" +MA,49,"Rabat-Sale-Zemmour-Zaer" +MA,50,"Chaouia-Ouardigha" +MA,51,"Doukkala-Abda" +MA,52,"Gharb-Chrarda-Beni Hssen" +MA,53,"Guelmim-Es Smara" +MA,54,"Oriental" +MA,55,"Souss-Massa-Dr,a" +MA,56,"Tadla-Azilal" +MA,57,"Tanger-Tetouan" +MA,58,"Taza-Al Hoceima-Taounate" +MA,59,"La,youne-Boujdour-Sakia El Hamra" +MC,01,"La Condamine" +MC,02,"Monaco" +MC,03,"Monte-Carlo" +MD,51,"Gagauzia" +MD,57,"Chisinau" +MD,58,"Stinga Nistrului" +MD,59,"Anenii Noi" +MD,60,"Balti" +MD,61,"Basarabeasca" +MD,62,"Bender" +MD,63,"Briceni" +MD,64,"Cahul" +MD,65,"Cantemir" +MD,66,"Calarasi" +MD,67,"Causeni" +MD,68,"Cimislia" +MD,69,"Criuleni" +MD,70,"Donduseni" +MD,71,"Drochia" +MD,72,"Dubasari" +MD,73,"Edinet" +MD,74,"Falesti" +MD,75,"Floresti" +MD,76,"Glodeni" +MD,77,"Hincesti" +MD,78,"Ialoveni" +MD,79,"Leova" +MD,80,"Nisporeni" +MD,81,"Ocnita" +MD,82,"Orhei" +MD,83,"Rezina" +MD,84,"Riscani" +MD,85,"Singerei" +MD,86,"Soldanesti" +MD,87,"Soroca" +MD,88,"Stefan-Voda" +MD,89,"Straseni" +MD,90,"Taraclia" +MD,91,"Telenesti" +MD,92,"Ungheni" +MG,01,"Antsiranana" +MG,02,"Fianarantsoa" +MG,03,"Mahajanga" +MG,04,"Toamasina" +MG,05,"Antananarivo" +MG,06,"Toliara" +MK,01,"Aracinovo" +MK,02,"Bac" +MK,03,"Belcista" +MK,04,"Berovo" +MK,05,"Bistrica" +MK,06,"Bitola" +MK,07,"Blatec" +MK,08,"Bogdanci" +MK,09,"Bogomila" +MK,10,"Bogovinje" +MK,11,"Bosilovo" +MK,12,"Brvenica" +MK,13,"Cair" +MK,14,"Capari" +MK,15,"Caska" +MK,16,"Cegrane" +MK,17,"Centar" +MK,18,"Centar Zupa" +MK,19,"Cesinovo" +MK,20,"Cucer-Sandevo" +MK,21,"Debar" +MK,22,"Delcevo" +MK,23,"Delogozdi" +MK,24,"Demir Hisar" +MK,25,"Demir Kapija" +MK,26,"Dobrusevo" +MK,27,"Dolna Banjica" +MK,28,"Dolneni" +MK,29,"Dorce Petrov" +MK,30,"Drugovo" +MK,31,"Dzepciste" +MK,32,"Gazi Baba" +MK,33,"Gevgelija" +MK,34,"Gostivar" +MK,35,"Gradsko" +MK,36,"Ilinden" +MK,37,"Izvor" +MK,38,"Jegunovce" +MK,39,"Kamenjane" +MK,40,"Karbinci" +MK,41,"Karpos" +MK,42,"Kavadarci" +MK,43,"Kicevo" +MK,44,"Kisela Voda" +MK,45,"Klecevce" +MK,46,"Kocani" +MK,47,"Konce" +MK,48,"Kondovo" +MK,49,"Konopiste" +MK,50,"Kosel" +MK,51,"Kratovo" +MK,52,"Kriva Palanka" +MK,53,"Krivogastani" +MK,54,"Krusevo" +MK,55,"Kuklis" +MK,56,"Kukurecani" +MK,57,"Kumanovo" +MK,58,"Labunista" +MK,59,"Lipkovo" +MK,60,"Lozovo" +MK,61,"Lukovo" +MK,62,"Makedonska Kamenica" +MK,63,"Makedonski Brod" +MK,64,"Mavrovi Anovi" +MK,65,"Meseista" +MK,66,"Miravci" +MK,67,"Mogila" +MK,68,"Murtino" +MK,69,"Negotino" +MK,70,"Negotino-Polosko" +MK,71,"Novaci" +MK,72,"Novo Selo" +MK,73,"Oblesevo" +MK,74,"Ohrid" +MK,75,"Orasac" +MK,76,"Orizari" +MK,77,"Oslomej" +MK,78,"Pehcevo" +MK,79,"Petrovec" +MK,80,"Plasnica" +MK,81,"Podares" +MK,82,"Prilep" +MK,83,"Probistip" +MK,84,"Radovis" +MK,85,"Rankovce" +MK,86,"Resen" +MK,87,"Rosoman" +MK,88,"Rostusa" +MK,89,"Samokov" +MK,90,"Saraj" +MK,91,"Sipkovica" +MK,92,"Sopiste" +MK,93,"Sopotnica" +MK,94,"Srbinovo" +MK,95,"Staravina" +MK,96,"Star Dojran" +MK,97,"Staro Nagoricane" +MK,98,"Stip" +MK,99,"Struga" +MK,A1,"Strumica" +MK,A2,"Studenicani" +MK,A3,"Suto Orizari" +MK,A4,"Sveti Nikole" +MK,A5,"Tearce" +MK,A6,"Tetovo" +MK,A7,"Topolcani" +MK,A8,"Valandovo" +MK,A9,"Vasilevo" +MK,B1,"Veles" +MK,B2,"Velesta" +MK,B3,"Vevcani" +MK,B4,"Vinica" +MK,B5,"Vitoliste" +MK,B6,"Vranestica" +MK,B7,"Vrapciste" +MK,B8,"Vratnica" +MK,B9,"Vrutok" +MK,C1,"Zajas" +MK,C2,"Zelenikovo" +MK,C3,"Zelino" +MK,C4,"Zitose" +MK,C5,"Zletovo" +MK,C6,"Zrnovci" +MK,C8,"Cair" +MK,C9,"Caska" +MK,D2,"Debar" +MK,D3,"Demir Hisar" +MK,D4,"Gostivar" +MK,D5,"Jegunovce" +MK,D6,"Kavadarci" +MK,D7,"Kumanovo" +MK,D8,"Makedonski Brod" +MK,E2,"Ohrid" +MK,E3,"Prilep" +MK,E5,"Dojran" +MK,E6,"Struga" +MK,E7,"Strumica" +MK,E8,"Tetovo" +MK,E9,"Valandovo" +MK,F1,"Veles" +MK,F2,"Aerodrom" +ML,01,"Bamako" +ML,03,"Kayes" +ML,04,"Mopti" +ML,05,"Segou" +ML,06,"Sikasso" +ML,07,"Koulikoro" +ML,08,"Tombouctou" +ML,09,"Gao" +ML,10,"Kidal" +MM,01,"Rakhine State" +MM,02,"Chin State" +MM,03,"Irrawaddy" +MM,04,"Kachin State" +MM,05,"Karan State" +MM,06,"Kayah State" +MM,07,"Magwe" +MM,08,"Mandalay" +MM,09,"Pegu" +MM,10,"Sagaing" +MM,11,"Shan State" +MM,12,"Tenasserim" +MM,13,"Mon State" +MM,14,"Rangoon" +MM,17,"Yangon" +MN,01,"Arhangay" +MN,02,"Bayanhongor" +MN,03,"Bayan-Olgiy" +MN,05,"Darhan" +MN,06,"Dornod" +MN,07,"Dornogovi" +MN,08,"Dundgovi" +MN,09,"Dzavhan" +MN,10,"Govi-Altay" +MN,11,"Hentiy" +MN,12,"Hovd" +MN,13,"Hovsgol" +MN,14,"Omnogovi" +MN,15,"Ovorhangay" +MN,16,"Selenge" +MN,17,"Suhbaatar" +MN,18,"Tov" +MN,19,"Uvs" +MN,20,"Ulaanbaatar" +MN,21,"Bulgan" +MN,22,"Erdenet" +MN,23,"Darhan-Uul" +MN,24,"Govisumber" +MN,25,"Orhon" +MO,01,"Ilhas" +MO,02,"Macau" +MR,01,"Hodh Ech Chargui" +MR,02,"Hodh El Gharbi" +MR,03,"Assaba" +MR,04,"Gorgol" +MR,05,"Brakna" +MR,06,"Trarza" +MR,07,"Adrar" +MR,08,"Dakhlet Nouadhibou" +MR,09,"Tagant" +MR,10,"Guidimaka" +MR,11,"Tiris Zemmour" +MR,12,"Inchiri" +MS,01,"Saint Anthony" +MS,02,"Saint Georges" +MS,03,"Saint Peter" +MU,12,"Black River" +MU,13,"Flacq" +MU,14,"Grand Port" +MU,15,"Moka" +MU,16,"Pamplemousses" +MU,17,"Plaines Wilhems" +MU,18,"Port Louis" +MU,19,"Riviere du Rempart" +MU,20,"Savanne" +MU,21,"Agalega Islands" +MU,22,"Cargados Carajos" +MU,23,"Rodrigues" +MV,01,"Seenu" +MV,05,"Laamu" +MV,30,"Alifu" +MV,31,"Baa" +MV,32,"Dhaalu" +MV,33,"Faafu " +MV,34,"Gaafu Alifu" +MV,35,"Gaafu Dhaalu" +MV,36,"Haa Alifu" +MV,37,"Haa Dhaalu" +MV,38,"Kaafu" +MV,39,"Lhaviyani" +MV,40,"Maale" +MV,41,"Meemu" +MV,42,"Gnaviyani" +MV,43,"Noonu" +MV,44,"Raa" +MV,45,"Shaviyani" +MV,46,"Thaa" +MV,47,"Vaavu" +MW,02,"Chikwawa" +MW,03,"Chiradzulu" +MW,04,"Chitipa" +MW,05,"Thyolo" +MW,06,"Dedza" +MW,07,"Dowa" +MW,08,"Karonga" +MW,09,"Kasungu" +MW,11,"Lilongwe" +MW,12,"Mangochi" +MW,13,"Mchinji" +MW,15,"Mzimba" +MW,16,"Ntcheu" +MW,17,"Nkhata Bay" +MW,18,"Nkhotakota" +MW,19,"Nsanje" +MW,20,"Ntchisi" +MW,21,"Rumphi" +MW,22,"Salima" +MW,23,"Zomba" +MW,24,"Blantyre" +MW,25,"Mwanza" +MW,26,"Balaka" +MW,27,"Likoma" +MW,28,"Machinga" +MW,29,"Mulanje" +MW,30,"Phalombe" +MX,01,"Aguascalientes" +MX,02,"Baja California" +MX,03,"Baja California Sur" +MX,04,"Campeche" +MX,05,"Chiapas" +MX,06,"Chihuahua" +MX,07,"Coahuila de Zaragoza" +MX,08,"Colima" +MX,09,"Distrito Federal" +MX,10,"Durango" +MX,11,"Guanajuato" +MX,12,"Guerrero" +MX,13,"Hidalgo" +MX,14,"Jalisco" +MX,15,"Mexico" +MX,16,"Michoacan de Ocampo" +MX,17,"Morelos" +MX,18,"Nayarit" +MX,19,"Nuevo Leon" +MX,20,"Oaxaca" +MX,21,"Puebla" +MX,22,"Queretaro de Arteaga" +MX,23,"Quintana Roo" +MX,24,"San Luis Potosi" +MX,25,"Sinaloa" +MX,26,"Sonora" +MX,27,"Tabasco" +MX,28,"Tamaulipas" +MX,29,"Tlaxcala" +MX,30,"Veracruz-Llave" +MX,31,"Yucatan" +MX,32,"Zacatecas" +MY,01,"Johor" +MY,02,"Kedah" +MY,03,"Kelantan" +MY,04,"Melaka" +MY,05,"Negeri Sembilan" +MY,06,"Pahang" +MY,07,"Perak" +MY,08,"Perlis" +MY,09,"Pulau Pinang" +MY,11,"Sarawak" +MY,12,"Selangor" +MY,13,"Terengganu" +MY,14,"Kuala Lumpur" +MY,15,"Labuan" +MY,16,"Sabah" +MY,17,"Putrajaya" +MZ,01,"Cabo Delgado" +MZ,02,"Gaza" +MZ,03,"Inhambane" +MZ,04,"Maputo" +MZ,05,"Sofala" +MZ,06,"Nampula" +MZ,07,"Niassa" +MZ,08,"Tete" +MZ,09,"Zambezia" +MZ,10,"Manica" +MZ,11,"Maputo" +NA,01,"Bethanien" +NA,02,"Caprivi Oos" +NA,03,"Boesmanland" +NA,04,"Gobabis" +NA,05,"Grootfontein" +NA,06,"Kaokoland" +NA,07,"Karibib" +NA,08,"Keetmanshoop" +NA,09,"Luderitz" +NA,10,"Maltahohe" +NA,11,"Okahandja" +NA,12,"Omaruru" +NA,13,"Otjiwarongo" +NA,14,"Outjo" +NA,15,"Owambo" +NA,16,"Rehoboth" +NA,17,"Swakopmund" +NA,18,"Tsumeb" +NA,20,"Karasburg" +NA,21,"Windhoek" +NA,22,"Damaraland" +NA,23,"Hereroland Oos" +NA,24,"Hereroland Wes" +NA,25,"Kavango" +NA,26,"Mariental" +NA,27,"Namaland" +NA,28,"Caprivi" +NA,29,"Erongo" +NA,30,"Hardap" +NA,31,"Karas" +NA,32,"Kunene" +NA,33,"Ohangwena" +NA,34,"Okavango" +NA,35,"Omaheke" +NA,36,"Omusati" +NA,37,"Oshana" +NA,38,"Oshikoto" +NA,39,"Otjozondjupa" +NE,01,"Agadez" +NE,02,"Diffa" +NE,03,"Dosso" +NE,04,"Maradi" +NE,05,"Niamey" +NE,06,"Tahoua" +NE,07,"Zinder" +NE,08,"Niamey" +NG,05,"Lagos" +NG,11,"Federal Capital Territory" +NG,16,"Ogun" +NG,21,"Akwa Ibom" +NG,22,"Cross River" +NG,23,"Kaduna" +NG,24,"Katsina" +NG,25,"Anambra" +NG,26,"Benue" +NG,27,"Borno" +NG,28,"Imo" +NG,29,"Kano" +NG,30,"Kwara" +NG,31,"Niger" +NG,32,"Oyo" +NG,35,"Adamawa" +NG,36,"Delta" +NG,37,"Edo" +NG,39,"Jigawa" +NG,40,"Kebbi" +NG,41,"Kogi" +NG,42,"Osun" +NG,43,"Taraba" +NG,44,"Yobe" +NG,45,"Abia" +NG,46,"Bauchi" +NG,47,"Enugu" +NG,48,"Ondo" +NG,49,"Plateau" +NG,50,"Rivers" +NG,51,"Sokoto" +NG,52,"Bayelsa" +NG,53,"Ebonyi" +NG,54,"Ekiti" +NG,55,"Gombe" +NG,56,"Nassarawa" +NG,57,"Zamfara" +NI,01,"Boaco" +NI,02,"Carazo" +NI,03,"Chinandega" +NI,04,"Chontales" +NI,05,"Esteli" +NI,06,"Granada" +NI,07,"Jinotega" +NI,08,"Leon" +NI,09,"Madriz" +NI,10,"Managua" +NI,11,"Masaya" +NI,12,"Matagalpa" +NI,13,"Nueva Segovia" +NI,14,"Rio San Juan" +NI,15,"Rivas" +NI,16,"Zelaya" +NI,17,"Autonoma Atlantico Norte" +NI,18,"Region Autonoma Atlantico Sur" +NL,01,"Drenthe" +NL,02,"Friesland" +NL,03,"Gelderland" +NL,04,"Groningen" +NL,05,"Limburg" +NL,06,"Noord-Brabant" +NL,07,"Noord-Holland" +NL,09,"Utrecht" +NL,10,"Zeeland" +NL,11,"Zuid-Holland" +NL,15,"Overijssel" +NL,16,"Flevoland" +NO,01,"Akershus" +NO,02,"Aust-Agder" +NO,04,"Buskerud" +NO,05,"Finnmark" +NO,06,"Hedmark" +NO,07,"Hordaland" +NO,08,"More og Romsdal" +NO,09,"Nordland" +NO,10,"Nord-Trondelag" +NO,11,"Oppland" +NO,12,"Oslo" +NO,13,"Ostfold" +NO,14,"Rogaland" +NO,15,"Sogn og Fjordane" +NO,16,"Sor-Trondelag" +NO,17,"Telemark" +NO,18,"Troms" +NO,19,"Vest-Agder" +NO,20,"Vestfold" +NP,01,"Bagmati" +NP,02,"Bheri" +NP,03,"Dhawalagiri" +NP,04,"Gandaki" +NP,05,"Janakpur" +NP,06,"Karnali" +NP,07,"Kosi" +NP,08,"Lumbini" +NP,09,"Mahakali" +NP,10,"Mechi" +NP,11,"Narayani" +NP,12,"Rapti" +NP,13,"Sagarmatha" +NP,14,"Seti" +NR,01,"Aiwo" +NR,02,"Anabar" +NR,03,"Anetan" +NR,04,"Anibare" +NR,05,"Baiti" +NR,06,"Boe" +NR,07,"Buada" +NR,08,"Denigomodu" +NR,09,"Ewa" +NR,10,"Ijuw" +NR,11,"Meneng" +NR,12,"Nibok" +NR,13,"Uaboe" +NR,14,"Yaren" +NZ,10,"Chatham Islands" +NZ,E7,"Auckland" +NZ,E8,"Bay of Plenty" +NZ,E9,"Canterbury" +NZ,F1,"Gisborne" +NZ,F2,"Hawke's Bay" +NZ,F3,"Manawatu-Wanganui" +NZ,F4,"Marlborough" +NZ,F5,"Nelson" +NZ,F6,"Northland" +NZ,F7,"Otago" +NZ,F8,"Southland" +NZ,F9,"Taranaki" +NZ,G1,"Waikato" +NZ,G2,"Wellington" +NZ,G3,"West Coast" +OM,01,"Ad Dakhiliyah" +OM,02,"Al Batinah" +OM,03,"Al Wusta" +OM,04,"Ash Sharqiyah" +OM,05,"Az Zahirah" +OM,06,"Masqat" +OM,07,"Musandam" +OM,08,"Zufar" +PA,01,"Bocas del Toro" +PA,02,"Chiriqui" +PA,03,"Cocle" +PA,04,"Colon" +PA,05,"Darien" +PA,06,"Herrera" +PA,07,"Los Santos" +PA,08,"Panama" +PA,09,"San Blas" +PA,10,"Veraguas" +PE,01,"Amazonas" +PE,02,"Ancash" +PE,03,"Apurimac" +PE,04,"Arequipa" +PE,05,"Ayacucho" +PE,06,"Cajamarca" +PE,07,"Callao" +PE,08,"Cusco" +PE,09,"Huancavelica" +PE,10,"Huanuco" +PE,11,"Ica" +PE,12,"Junin" +PE,13,"La Libertad" +PE,14,"Lambayeque" +PE,15,"Lima" +PE,16,"Loreto" +PE,17,"Madre de Dios" +PE,18,"Moquegua" +PE,19,"Pasco" +PE,20,"Piura" +PE,21,"Puno" +PE,22,"San Martin" +PE,23,"Tacna" +PE,24,"Tumbes" +PE,25,"Ucayali" +PG,01,"Central" +PG,02,"Gulf" +PG,03,"Milne Bay" +PG,04,"Northern" +PG,05,"Southern Highlands" +PG,06,"Western" +PG,07,"North Solomons" +PG,08,"Chimbu" +PG,09,"Eastern Highlands" +PG,10,"East New Britain" +PG,11,"East Sepik" +PG,12,"Madang" +PG,13,"Manus" +PG,14,"Morobe" +PG,15,"New Ireland" +PG,16,"Western Highlands" +PG,17,"West New Britain" +PG,18,"Sandaun" +PG,19,"Enga" +PG,20,"National Capital" +PH,01,"Abra" +PH,02,"Agusan del Norte" +PH,03,"Agusan del Sur" +PH,04,"Aklan" +PH,05,"Albay" +PH,06,"Antique" +PH,07,"Bataan" +PH,08,"Batanes" +PH,09,"Batangas" +PH,10,"Benguet" +PH,11,"Bohol" +PH,12,"Bukidnon" +PH,13,"Bulacan" +PH,14,"Cagayan" +PH,15,"Camarines Norte" +PH,16,"Camarines Sur" +PH,17,"Camiguin" +PH,18,"Capiz" +PH,19,"Catanduanes" +PH,20,"Cavite" +PH,21,"Cebu" +PH,22,"Basilan" +PH,23,"Eastern Samar" +PH,24,"Davao" +PH,25,"Davao del Sur" +PH,26,"Davao Oriental" +PH,27,"Ifugao" +PH,28,"Ilocos Norte" +PH,29,"Ilocos Sur" +PH,30,"Iloilo" +PH,31,"Isabela" +PH,32,"Kalinga-Apayao" +PH,33,"Laguna" +PH,34,"Lanao del Norte" +PH,35,"Lanao del Sur" +PH,36,"La Union" +PH,37,"Leyte" +PH,38,"Marinduque" +PH,39,"Masbate" +PH,40,"Mindoro Occidental" +PH,41,"Mindoro Oriental" +PH,42,"Misamis Occidental" +PH,43,"Misamis Oriental" +PH,44,"Mountain" +PH,45,"Negros Occidental" +PH,46,"Negros Oriental" +PH,47,"Nueva Ecija" +PH,48,"Nueva Vizcaya" +PH,49,"Palawan" +PH,50,"Pampanga" +PH,51,"Pangasinan" +PH,53,"Rizal" +PH,54,"Romblon" +PH,55,"Samar" +PH,56,"Maguindanao" +PH,57,"North Cotabato" +PH,58,"Sorsogon" +PH,59,"Southern Leyte" +PH,60,"Sulu" +PH,61,"Surigao del Norte" +PH,62,"Surigao del Sur" +PH,63,"Tarlac" +PH,64,"Zambales" +PH,65,"Zamboanga del Norte" +PH,66,"Zamboanga del Sur" +PH,67,"Northern Samar" +PH,68,"Quirino" +PH,69,"Siquijor" +PH,70,"South Cotabato" +PH,71,"Sultan Kudarat" +PH,72,"Tawitawi" +PH,A1,"Angeles" +PH,A2,"Bacolod" +PH,A3,"Bago" +PH,A4,"Baguio" +PH,A5,"Bais" +PH,A6,"Basilan City" +PH,A7,"Batangas City" +PH,A8,"Butuan" +PH,A9,"Cabanatuan" +PH,B1,"Cadiz" +PH,B2,"Cagayan de Oro" +PH,B3,"Calbayog" +PH,B4,"Caloocan" +PH,B5,"Canlaon" +PH,B6,"Cavite City" +PH,B7,"Cebu City" +PH,B8,"Cotabato" +PH,B9,"Dagupan" +PH,C1,"Danao" +PH,C2,"Dapitan" +PH,C3,"Davao City" +PH,C4,"Dipolog" +PH,C5,"Dumaguete" +PH,C6,"General Santos" +PH,C7,"Gingoog" +PH,C8,"Iligan" +PH,C9,"Iloilo City" +PH,D1,"Iriga" +PH,D2,"La Carlota" +PH,D3,"Laoag" +PH,D4,"Lapu-Lapu" +PH,D5,"Legaspi" +PH,D6,"Lipa" +PH,D7,"Lucena" +PH,D8,"Mandaue" +PH,D9,"Manila" +PH,E1,"Marawi" +PH,E2,"Naga" +PH,E3,"Olongapo" +PH,E4,"Ormoc" +PH,E5,"Oroquieta" +PH,E6,"Ozamis" +PH,E7,"Pagadian" +PH,E8,"Palayan" +PH,E9,"Pasay" +PH,F1,"Puerto Princesa" +PH,F2,"Quezon City" +PH,F3,"Roxas" +PH,F4,"San Carlos" +PH,F5,"San Carlos" +PH,F6,"San Jose" +PH,F7,"San Pablo" +PH,F8,"Silay" +PH,F9,"Surigao" +PH,G1,"Tacloban" +PH,G2,"Tagaytay" +PH,G3,"Tagbilaran" +PH,G4,"Tangub" +PH,G5,"Toledo" +PH,G6,"Trece Martires" +PH,G7,"Zamboanga" +PH,G8,"Aurora" +PH,H2,"Quezon" +PH,H3,"Negros Occidental" +PH,H9,"Biliran" +PH,I6,"Compostela Valley" +PH,I7,"Davao del Norte" +PH,J3,"Guimaras" +PH,J4,"Himamaylan" +PH,J7,"Kalinga" +PH,K1,"Las Pinas" +PH,K5,"Malabon" +PH,K6,"Malaybalay" +PH,L4,"Muntinlupa" +PH,L5,"Navotas" +PH,L7,"Paranaque" +PH,L9,"Passi" +PH,P1,"Zambales" +PH,M5,"San Jose del Monte" +PH,M6,"San Juan" +PH,M8,"Santiago" +PH,M9,"Sarangani" +PH,N1,"Sipalay" +PH,N3,"Surigao del Norte" +PH,P2,"Zamboanga" +PK,01,"Federally Administered Tribal Areas" +PK,02,"Balochistan" +PK,03,"North-West Frontier" +PK,04,"Punjab" +PK,05,"Sindh" +PK,06,"Azad Kashmir" +PK,07,"Northern Areas" +PK,08,"Islamabad" +PL,72,"Dolnoslaskie" +PL,73,"Kujawsko-Pomorskie" +PL,74,"Lodzkie" +PL,75,"Lubelskie" +PL,76,"Lubuskie" +PL,77,"Malopolskie" +PL,78,"Mazowieckie" +PL,79,"Opolskie" +PL,80,"Podkarpackie" +PL,81,"Podlaskie" +PL,82,"Pomorskie" +PL,83,"Slaskie" +PL,84,"Swietokrzyskie" +PL,85,"Warminsko-Mazurskie" +PL,86,"Wielkopolskie" +PL,87,"Zachodniopomorskie" +PS,GZ,"Gaza" +PS,WE,"West Bank" +PT,02,"Aveiro" +PT,03,"Beja" +PT,04,"Braga" +PT,05,"Braganca" +PT,06,"Castelo Branco" +PT,07,"Coimbra" +PT,08,"Evora" +PT,09,"Faro" +PT,10,"Madeira" +PT,11,"Guarda" +PT,13,"Leiria" +PT,14,"Lisboa" +PT,16,"Portalegre" +PT,17,"Porto" +PT,18,"Santarem" +PT,19,"Setubal" +PT,20,"Viana do Castelo" +PT,21,"Vila Real" +PT,22,"Viseu" +PT,23,"Azores" +PY,01,"Alto Parana" +PY,02,"Amambay" +PY,04,"Caaguazu" +PY,05,"Caazapa" +PY,06,"Central" +PY,07,"Concepcion" +PY,08,"Cordillera" +PY,10,"Guaira" +PY,11,"Itapua" +PY,12,"Misiones" +PY,13,"Neembucu" +PY,15,"Paraguari" +PY,16,"Presidente Hayes" +PY,17,"San Pedro" +PY,19,"Canindeyu" +PY,22,"Asuncion" +PY,23,"Alto Paraguay" +PY,24,"Boqueron" +QA,01,"Ad Dawhah" +QA,02,"Al Ghuwariyah" +QA,03,"Al Jumaliyah" +QA,04,"Al Khawr" +QA,05,"Al Wakrah Municipality" +QA,06,"Ar Rayyan" +QA,08,"Madinat ach Shamal" +QA,09,"Umm Salal" +QA,10,"Al Wakrah" +QA,11,"Jariyan al Batnah" +QA,12,"Umm Sa'id" +RO,01,"Alba" +RO,02,"Arad" +RO,03,"Arges" +RO,04,"Bacau" +RO,05,"Bihor" +RO,06,"Bistrita-Nasaud" +RO,07,"Botosani" +RO,08,"Braila" +RO,09,"Brasov" +RO,10,"Bucuresti" +RO,11,"Buzau" +RO,12,"Caras-Severin" +RO,13,"Cluj" +RO,14,"Constanta" +RO,15,"Covasna" +RO,16,"Dambovita" +RO,17,"Dolj" +RO,18,"Galati" +RO,19,"Gorj" +RO,20,"Harghita" +RO,21,"Hunedoara" +RO,22,"Ialomita" +RO,23,"Iasi" +RO,25,"Maramures" +RO,26,"Mehedinti" +RO,27,"Mures" +RO,28,"Neamt" +RO,29,"Olt" +RO,30,"Prahova" +RO,31,"Salaj" +RO,32,"Satu Mare" +RO,33,"Sibiu" +RO,34,"Suceava" +RO,35,"Teleorman" +RO,36,"Timis" +RO,37,"Tulcea" +RO,38,"Vaslui" +RO,39,"Valcea" +RO,40,"Vrancea" +RO,41,"Calarasi" +RO,42,"Giurgiu" +RO,43,"Ilfov" +RS,01,"Kosovo" +RS,02,"Vojvodina" +RU,01,"Adygeya, Republic of" +RU,02,"Aginsky Buryatsky AO" +RU,03,"Gorno-Altay" +RU,04,"Altaisky krai" +RU,05,"Amur" +RU,06,"Arkhangel'sk" +RU,07,"Astrakhan'" +RU,08,"Bashkortostan" +RU,09,"Belgorod" +RU,10,"Bryansk" +RU,11,"Buryat" +RU,12,"Chechnya" +RU,13,"Chelyabinsk" +RU,14,"Chita" +RU,15,"Chukot" +RU,16,"Chuvashia" +RU,17,"Dagestan" +RU,18,"Evenk" +RU,19,"Ingush" +RU,20,"Irkutsk" +RU,21,"Ivanovo" +RU,22,"Kabardin-Balkar" +RU,23,"Kaliningrad" +RU,24,"Kalmyk" +RU,25,"Kaluga" +RU,26,"Kamchatka" +RU,27,"Karachay-Cherkess" +RU,28,"Karelia" +RU,29,"Kemerovo" +RU,30,"Khabarovsk" +RU,31,"Khakass" +RU,32,"Khanty-Mansiy" +RU,33,"Kirov" +RU,34,"Komi" +RU,36,"Koryak" +RU,37,"Kostroma" +RU,38,"Krasnodar" +RU,39,"Krasnoyarsk" +RU,40,"Kurgan" +RU,41,"Kursk" +RU,42,"Leningrad" +RU,43,"Lipetsk" +RU,44,"Magadan" +RU,45,"Mariy-El" +RU,46,"Mordovia" +RU,47,"Moskva" +RU,48,"Moscow City" +RU,49,"Murmansk" +RU,50,"Nenets" +RU,51,"Nizhegorod" +RU,52,"Novgorod" +RU,53,"Novosibirsk" +RU,54,"Omsk" +RU,55,"Orenburg" +RU,56,"Orel" +RU,57,"Penza" +RU,58,"Perm'" +RU,59,"Primor'ye" +RU,60,"Pskov" +RU,61,"Rostov" +RU,62,"Ryazan'" +RU,63,"Sakha" +RU,64,"Sakhalin" +RU,65,"Samara" +RU,66,"Saint Petersburg City" +RU,67,"Saratov" +RU,68,"North Ossetia" +RU,69,"Smolensk" +RU,70,"Stavropol'" +RU,71,"Sverdlovsk" +RU,72,"Tambovskaya oblast" +RU,73,"Tatarstan" +RU,74,"Taymyr" +RU,75,"Tomsk" +RU,76,"Tula" +RU,77,"Tver'" +RU,78,"Tyumen'" +RU,79,"Tuva" +RU,80,"Udmurt" +RU,81,"Ul'yanovsk" +RU,83,"Vladimir" +RU,84,"Volgograd" +RU,85,"Vologda" +RU,86,"Voronezh" +RU,87,"Yamal-Nenets" +RU,88,"Yaroslavl'" +RU,89,"Yevrey" +RU,90,"Permskiy Kray" +RU,91,"Krasnoyarskiy Kray" +RU,92,"Kamchatskiy Kray" +RU,93,"Zabaykal'skiy Kray" +RW,01,"Butare" +RW,06,"Gitarama" +RW,07,"Kibungo" +RW,09,"Kigali" +RW,11,"Est" +RW,12,"Kigali" +RW,13,"Nord" +RW,14,"Ouest" +RW,15,"Sud" +SA,02,"Al Bahah" +SA,05,"Al Madinah" +SA,06,"Ash Sharqiyah" +SA,08,"Al Qasim" +SA,10,"Ar Riyad" +SA,11,"Asir Province" +SA,13,"Ha'il" +SA,14,"Makkah" +SA,15,"Al Hudud ash Shamaliyah" +SA,16,"Najran" +SA,17,"Jizan" +SA,19,"Tabuk" +SA,20,"Al Jawf" +SB,03,"Malaita" +SB,06,"Guadalcanal" +SB,07,"Isabel" +SB,08,"Makira" +SB,09,"Temotu" +SB,10,"Central" +SB,11,"Western" +SB,12,"Choiseul" +SB,13,"Rennell and Bellona" +SC,01,"Anse aux Pins" +SC,02,"Anse Boileau" +SC,03,"Anse Etoile" +SC,04,"Anse Louis" +SC,05,"Anse Royale" +SC,06,"Baie Lazare" +SC,07,"Baie Sainte Anne" +SC,08,"Beau Vallon" +SC,09,"Bel Air" +SC,10,"Bel Ombre" +SC,11,"Cascade" +SC,12,"Glacis" +SC,13,"Grand' Anse" +SC,14,"Grand' Anse" +SC,15,"La Digue" +SC,16,"La Riviere Anglaise" +SC,17,"Mont Buxton" +SC,18,"Mont Fleuri" +SC,19,"Plaisance" +SC,20,"Pointe La Rue" +SC,21,"Port Glaud" +SC,22,"Saint Louis" +SC,23,"Takamaka" +SD,27,"Al Wusta" +SD,28,"Al Istiwa'iyah" +SD,29,"Al Khartum" +SD,30,"Ash Shamaliyah" +SD,31,"Ash Sharqiyah" +SD,32,"Bahr al Ghazal" +SD,33,"Darfur" +SD,34,"Kurdufan" +SD,35,"Upper Nile" +SD,40,"Al Wahadah State" +SD,44,"Central Equatoria State" +SD,49,"Southern Darfur" +SD,50,"Southern Kordofan" +SD,52,"Kassala" +SD,53,"River Nile" +SD,55,"Northern Darfur" +SE,02,"Blekinge Lan" +SE,03,"Gavleborgs Lan" +SE,05,"Gotlands Lan" +SE,06,"Hallands Lan" +SE,07,"Jamtlands Lan" +SE,08,"Jonkopings Lan" +SE,09,"Kalmar Lan" +SE,10,"Dalarnas Lan" +SE,12,"Kronobergs Lan" +SE,14,"Norrbottens Lan" +SE,15,"Orebro Lan" +SE,16,"Ostergotlands Lan" +SE,18,"Sodermanlands Lan" +SE,21,"Uppsala Lan" +SE,22,"Varmlands Lan" +SE,23,"Vasterbottens Lan" +SE,24,"Vasternorrlands Lan" +SE,25,"Vastmanlands Lan" +SE,26,"Stockholms Lan" +SE,27,"Skane Lan" +SE,28,"Vastra Gotaland" +SH,01,"Ascension" +SH,02,"Saint Helena" +SH,03,"Tristan da Cunha" +SI,01,"Ajdovscina Commune" +SI,02,"Beltinci Commune" +SI,03,"Bled Commune" +SI,04,"Bohinj Commune" +SI,05,"Borovnica Commune" +SI,06,"Bovec Commune" +SI,07,"Brda Commune" +SI,08,"Brezice Commune" +SI,09,"Brezovica Commune" +SI,11,"Celje Commune" +SI,12,"Cerklje na Gorenjskem Commune" +SI,13,"Cerknica Commune" +SI,14,"Cerkno Commune" +SI,15,"Crensovci Commune" +SI,16,"Crna na Koroskem Commune" +SI,17,"Crnomelj Commune" +SI,19,"Divaca Commune" +SI,20,"Dobrepolje Commune" +SI,22,"Dol pri Ljubljani Commune" +SI,24,"Dornava Commune" +SI,25,"Dravograd Commune" +SI,26,"Duplek Commune" +SI,27,"Gorenja vas-Poljane Commune" +SI,28,"Gorisnica Commune" +SI,29,"Gornja Radgona Commune" +SI,30,"Gornji Grad Commune" +SI,31,"Gornji Petrovci Commune" +SI,32,"Grosuplje Commune" +SI,34,"Hrastnik Commune" +SI,35,"Hrpelje-Kozina Commune" +SI,36,"Idrija Commune" +SI,37,"Ig Commune" +SI,38,"Ilirska Bistrica Commune" +SI,39,"Ivancna Gorica Commune" +SI,40,"Izola-Isola Commune" +SI,42,"Jursinci Commune" +SI,44,"Kanal Commune" +SI,45,"Kidricevo Commune" +SI,46,"Kobarid Commune" +SI,47,"Kobilje Commune" +SI,49,"Komen Commune" +SI,50,"Koper-Capodistria Urban Commune" +SI,51,"Kozje Commune" +SI,52,"Kranj Commune" +SI,53,"Kranjska Gora Commune" +SI,54,"Krsko Commune" +SI,55,"Kungota Commune" +SI,57,"Lasko Commune" +SI,61,"Ljubljana Urban Commune" +SI,62,"Ljubno Commune" +SI,64,"Logatec Commune" +SI,66,"Loski Potok Commune" +SI,68,"Lukovica Commune" +SI,71,"Medvode Commune" +SI,72,"Menges Commune" +SI,73,"Metlika Commune" +SI,74,"Mezica Commune" +SI,76,"Mislinja Commune" +SI,77,"Moravce Commune" +SI,78,"Moravske Toplice Commune" +SI,79,"Mozirje Commune" +SI,80,"Murska Sobota Urban Commune" +SI,81,"Muta Commune" +SI,82,"Naklo Commune" +SI,83,"Nazarje Commune" +SI,84,"Nova Gorica Urban Commune" +SI,86,"Odranci Commune" +SI,87,"Ormoz Commune" +SI,88,"Osilnica Commune" +SI,89,"Pesnica Commune" +SI,91,"Pivka Commune" +SI,92,"Podcetrtek Commune" +SI,94,"Postojna Commune" +SI,97,"Puconci Commune" +SI,98,"Race-Fram Commune" +SI,99,"Radece Commune" +SI,A1,"Radenci Commune" +SI,A2,"Radlje ob Dravi Commune" +SI,A3,"Radovljica Commune" +SI,A6,"Rogasovci Commune" +SI,A7,"Rogaska Slatina Commune" +SI,A8,"Rogatec Commune" +SI,B1,"Semic Commune" +SI,B2,"Sencur Commune" +SI,B3,"Sentilj Commune" +SI,B4,"Sentjernej Commune" +SI,B6,"Sevnica Commune" +SI,B7,"Sezana Commune" +SI,B8,"Skocjan Commune" +SI,B9,"Skofja Loka Commune" +SI,C1,"Skofljica Commune" +SI,C2,"Slovenj Gradec Urban Commune" +SI,C4,"Slovenske Konjice Commune" +SI,C5,"Smarje pri Jelsah Commune" +SI,C6,"Smartno ob Paki Commune" +SI,C7,"Sostanj Commune" +SI,C8,"Starse Commune" +SI,C9,"Store Commune" +SI,D1,"Sveti Jurij Commune" +SI,D2,"Tolmin Commune" +SI,D3,"Trbovlje Commune" +SI,D4,"Trebnje Commune" +SI,D5,"Trzic Commune" +SI,D6,"Turnisce Commune" +SI,D7,"Velenje Urban Commune" +SI,D8,"Velike Lasce Commune" +SI,E1,"Vipava Commune" +SI,E2,"Vitanje Commune" +SI,E3,"Vodice Commune" +SI,E5,"Vrhnika Commune" +SI,E6,"Vuzenica Commune" +SI,E7,"Zagorje ob Savi Commune" +SI,E9,"Zavrc Commune" +SI,F1,"Zelezniki Commune" +SI,F2,"Ziri Commune" +SI,F3,"Zrece Commune" +SI,F4,"Benedikt Commune" +SI,F5,"Bistrica ob Sotli Commune" +SI,F6,"Bloke Commune" +SI,F7,"Braslovce Commune" +SI,F8,"Cankova Commune" +SI,F9,"Cerkvenjak Commune" +SI,G1,"Destrnik Commune" +SI,G2,"Dobje Commune" +SI,G3,"Dobrna Commune" +SI,G4,"Dobrova-Horjul-Polhov Gradec Commune" +SI,G5,"Dobrovnik-Dobronak Commune" +SI,G6,"Dolenjske Toplice Commune" +SI,G7,"Domzale Commune" +SI,G8,"Grad Commune" +SI,G9,"Hajdina Commune" +SI,H1,"Hoce-Slivnica Commune" +SI,H2,"Hodos-Hodos Commune" +SI,H3,"Horjul Commune" +SI,H4,"Jesenice Commune" +SI,H5,"Jezersko Commune" +SI,H6,"Kamnik Commune" +SI,H7,"Kocevje Commune" +SI,H8,"Komenda Commune" +SI,H9,"Kostel Commune" +SI,I1,"Krizevci Commune" +SI,I2,"Kuzma Commune" +SI,I3,"Lenart Commune" +SI,I4,"Lendava-Lendva Commune" +SI,I5,"Litija Commune" +SI,I6,"Ljutomer Commune" +SI,I7,"Loska Dolina Commune" +SI,I8,"Lovrenc na Pohorju Commune" +SI,I9,"Luce Commune" +SI,J1,"Majsperk Commune" +SI,J2,"Maribor Commune" +SI,J3,"Markovci Commune" +SI,J4,"Miklavz na Dravskem polju Commune" +SI,J5,"Miren-Kostanjevica Commune" +SI,J6,"Mirna Pec Commune" +SI,J7,"Novo mesto Urban Commune" +SI,J8,"Oplotnica Commune" +SI,J9,"Piran-Pirano Commune" +SI,K1,"Podlehnik Commune" +SI,K2,"Podvelka Commune" +SI,K3,"Polzela Commune" +SI,K4,"Prebold Commune" +SI,K5,"Preddvor Commune" +SI,K6,"Prevalje Commune" +SI,K7,"Ptuj Urban Commune" +SI,K8,"Ravne na Koroskem Commune" +SI,K9,"Razkrizje Commune" +SI,L1,"Ribnica Commune" +SI,L2,"Ribnica na Pohorju Commune" +SI,L3,"Ruse Commune" +SI,L4,"Salovci Commune" +SI,L5,"Selnica ob Dravi Commune" +SI,L6,"Sempeter-Vrtojba Commune" +SI,L7,"Sentjur pri Celju Commune" +SI,L8,"Slovenska Bistrica Commune" +SI,L9,"Smartno pri Litiji Commune" +SI,M1,"Sodrazica Commune" +SI,M2,"Solcava Commune" +SI,M3,"Sveta Ana Commune" +SI,M4,"Sveti Andraz v Slovenskih goricah Commune" +SI,M5,"Tabor Commune" +SI,M6,"Tisina Commune" +SI,M7,"Trnovska vas Commune" +SI,M8,"Trzin Commune" +SI,M9,"Velika Polana Commune" +SI,N1,"Verzej Commune" +SI,N2,"Videm Commune" +SI,N3,"Vojnik Commune" +SI,N4,"Vransko Commune" +SI,N5,"Zalec Commune" +SI,N6,"Zetale Commune" +SI,N7,"Zirovnica Commune" +SI,N8,"Zuzemberk Commune" +SI,N9,"Apace Commune" +SI,O1,"Cirkulane Commune" +SI,O2,"Gorje" +SI,O3,"Kostanjevica na Krki" +SI,O4,"Log-Dragomer" +SI,O5,"Makole" +SI,O6,"Mirna" +SI,O7,"Mokronog-Trebelno" +SI,O8,"Poljcane" +SI,O9,"Recica ob Savinji" +SI,P1,"Rence-Vogrsko" +SI,P2,"Sentrupert" +SI,P3,"Smarjesk Toplice" +SI,P4,"Sredisce ob Dravi" +SI,P5,"Straza" +SI,P7,"Sveti Jurij v Slovenskih Goricah" +SK,01,"Banska Bystrica" +SK,02,"Bratislava" +SK,03,"Kosice" +SK,04,"Nitra" +SK,05,"Presov" +SK,06,"Trencin" +SK,07,"Trnava" +SK,08,"Zilina" +SL,01,"Eastern" +SL,02,"Northern" +SL,03,"Southern" +SL,04,"Western Area" +SM,01,"Acquaviva" +SM,02,"Chiesanuova" +SM,03,"Domagnano" +SM,04,"Faetano" +SM,05,"Fiorentino" +SM,06,"Borgo Maggiore" +SM,07,"San Marino" +SM,08,"Monte Giardino" +SM,09,"Serravalle" +SN,01,"Dakar" +SN,03,"Diourbel" +SN,05,"Tambacounda" +SN,07,"Thies" +SN,09,"Fatick" +SN,10,"Kaolack" +SN,11,"Kolda" +SN,12,"Ziguinchor" +SN,13,"Louga" +SN,14,"Saint-Louis" +SN,15,"Matam" +SO,01,"Bakool" +SO,02,"Banaadir" +SO,03,"Bari" +SO,04,"Bay" +SO,05,"Galguduud" +SO,06,"Gedo" +SO,07,"Hiiraan" +SO,08,"Jubbada Dhexe" +SO,09,"Jubbada Hoose" +SO,10,"Mudug" +SO,11,"Nugaal" +SO,12,"Sanaag" +SO,13,"Shabeellaha Dhexe" +SO,14,"Shabeellaha Hoose" +SO,16,"Woqooyi Galbeed" +SO,18,"Nugaal" +SO,19,"Togdheer" +SO,20,"Woqooyi Galbeed" +SO,21,"Awdal" +SO,22,"Sool" +SR,10,"Brokopondo" +SR,11,"Commewijne" +SR,12,"Coronie" +SR,13,"Marowijne" +SR,14,"Nickerie" +SR,15,"Para" +SR,16,"Paramaribo" +SR,17,"Saramacca" +SR,18,"Sipaliwini" +SR,19,"Wanica" +SS,01,"Central Equatoria" +SS,02,"Eastern Equatoria" +SS,03,"Jonglei" +SS,04,"Lakes" +SS,05,"Northern Bahr el Ghazal" +SS,06,"Unity" +SS,07,"Upper Nile" +SS,08,"Warrap" +SS,09,"Western Bahr el Ghazal" +SS,10,"Western Equatoria" +ST,01,"Principe" +ST,02,"Sao Tome" +SV,01,"Ahuachapan" +SV,02,"Cabanas" +SV,03,"Chalatenango" +SV,04,"Cuscatlan" +SV,05,"La Libertad" +SV,06,"La Paz" +SV,07,"La Union" +SV,08,"Morazan" +SV,09,"San Miguel" +SV,10,"San Salvador" +SV,11,"Santa Ana" +SV,12,"San Vicente" +SV,13,"Sonsonate" +SV,14,"Usulutan" +SY,01,"Al Hasakah" +SY,02,"Al Ladhiqiyah" +SY,03,"Al Qunaytirah" +SY,04,"Ar Raqqah" +SY,05,"As Suwayda'" +SY,06,"Dar" +SY,07,"Dayr az Zawr" +SY,08,"Rif Dimashq" +SY,09,"Halab" +SY,10,"Hamah" +SY,11,"Hims" +SY,12,"Idlib" +SY,13,"Dimashq" +SY,14,"Tartus" +SZ,01,"Hhohho" +SZ,02,"Lubombo" +SZ,03,"Manzini" +SZ,04,"Shiselweni" +SZ,05,"Praslin" +TD,01,"Batha" +TD,02,"Biltine" +TD,03,"Borkou-Ennedi-Tibesti" +TD,04,"Chari-Baguirmi" +TD,05,"Guera" +TD,06,"Kanem" +TD,07,"Lac" +TD,08,"Logone Occidental" +TD,09,"Logone Oriental" +TD,10,"Mayo-Kebbi" +TD,11,"Moyen-Chari" +TD,12,"Ouaddai" +TD,13,"Salamat" +TD,14,"Tandjile" +TG,22,"Centrale" +TG,23,"Kara" +TG,24,"Maritime" +TG,25,"Plateaux" +TG,26,"Savanes" +TH,01,"Mae Hong Son" +TH,02,"Chiang Mai" +TH,03,"Chiang Rai" +TH,04,"Nan" +TH,05,"Lamphun" +TH,06,"Lampang" +TH,07,"Phrae" +TH,08,"Tak" +TH,09,"Sukhothai" +TH,10,"Uttaradit" +TH,11,"Kamphaeng Phet" +TH,12,"Phitsanulok" +TH,13,"Phichit" +TH,14,"Phetchabun" +TH,15,"Uthai Thani" +TH,16,"Nakhon Sawan" +TH,17,"Nong Khai" +TH,18,"Loei" +TH,20,"Sakon Nakhon" +TH,21,"Nakhon Phanom" +TH,22,"Khon Kaen" +TH,23,"Kalasin" +TH,24,"Maha Sarakham" +TH,25,"Roi Et" +TH,26,"Chaiyaphum" +TH,27,"Nakhon Ratchasima" +TH,28,"Buriram" +TH,29,"Surin" +TH,30,"Sisaket" +TH,31,"Narathiwat" +TH,32,"Chai Nat" +TH,33,"Sing Buri" +TH,34,"Lop Buri" +TH,35,"Ang Thong" +TH,36,"Phra Nakhon Si Ayutthaya" +TH,37,"Saraburi" +TH,38,"Nonthaburi" +TH,39,"Pathum Thani" +TH,40,"Krung Thep" +TH,41,"Phayao" +TH,42,"Samut Prakan" +TH,43,"Nakhon Nayok" +TH,44,"Chachoengsao" +TH,45,"Prachin Buri" +TH,46,"Chon Buri" +TH,47,"Rayong" +TH,48,"Chanthaburi" +TH,49,"Trat" +TH,50,"Kanchanaburi" +TH,51,"Suphan Buri" +TH,52,"Ratchaburi" +TH,53,"Nakhon Pathom" +TH,54,"Samut Songkhram" +TH,55,"Samut Sakhon" +TH,56,"Phetchaburi" +TH,57,"Prachuap Khiri Khan" +TH,58,"Chumphon" +TH,59,"Ranong" +TH,60,"Surat Thani" +TH,61,"Phangnga" +TH,62,"Phuket" +TH,63,"Krabi" +TH,64,"Nakhon Si Thammarat" +TH,65,"Trang" +TH,66,"Phatthalung" +TH,67,"Satun" +TH,68,"Songkhla" +TH,69,"Pattani" +TH,70,"Yala" +TH,71,"Ubon Ratchathani" +TH,72,"Yasothon" +TH,73,"Nakhon Phanom" +TH,74,"Prachin Buri" +TH,75,"Ubon Ratchathani" +TH,76,"Udon Thani" +TH,77,"Amnat Charoen" +TH,78,"Mukdahan" +TH,79,"Nong Bua Lamphu" +TH,80,"Sa Kaeo" +TH,81,"Bueng Kan" +TJ,01,"Kuhistoni Badakhshon" +TJ,02,"Khatlon" +TJ,03,"Sughd" +TJ,04,"Dushanbe" +TJ,05,"Nohiyahoi Tobei Jumhuri" +TL,06,"Dili" +TM,01,"Ahal" +TM,02,"Balkan" +TM,03,"Dashoguz" +TM,04,"Lebap" +TM,05,"Mary" +TN,02,"Kasserine" +TN,03,"Kairouan" +TN,06,"Jendouba" +TN,10,"Qafsah" +TN,14,"El Kef" +TN,15,"Al Mahdia" +TN,16,"Al Munastir" +TN,17,"Bajah" +TN,18,"Bizerte" +TN,19,"Nabeul" +TN,22,"Siliana" +TN,23,"Sousse" +TN,27,"Ben Arous" +TN,28,"Madanin" +TN,29,"Gabes" +TN,31,"Kebili" +TN,32,"Sfax" +TN,33,"Sidi Bou Zid" +TN,34,"Tataouine" +TN,35,"Tozeur" +TN,36,"Tunis" +TN,37,"Zaghouan" +TN,38,"Aiana" +TN,39,"Manouba" +TO,01,"Ha" +TO,02,"Tongatapu" +TO,03,"Vava" +TR,02,"Adiyaman" +TR,03,"Afyonkarahisar" +TR,04,"Agri" +TR,05,"Amasya" +TR,07,"Antalya" +TR,08,"Artvin" +TR,09,"Aydin" +TR,10,"Balikesir" +TR,11,"Bilecik" +TR,12,"Bingol" +TR,13,"Bitlis" +TR,14,"Bolu" +TR,15,"Burdur" +TR,16,"Bursa" +TR,17,"Canakkale" +TR,19,"Corum" +TR,20,"Denizli" +TR,21,"Diyarbakir" +TR,22,"Edirne" +TR,23,"Elazig" +TR,24,"Erzincan" +TR,25,"Erzurum" +TR,26,"Eskisehir" +TR,28,"Giresun" +TR,31,"Hatay" +TR,32,"Mersin" +TR,33,"Isparta" +TR,34,"Istanbul" +TR,35,"Izmir" +TR,37,"Kastamonu" +TR,38,"Kayseri" +TR,39,"Kirklareli" +TR,40,"Kirsehir" +TR,41,"Kocaeli" +TR,43,"Kutahya" +TR,44,"Malatya" +TR,45,"Manisa" +TR,46,"Kahramanmaras" +TR,48,"Mugla" +TR,49,"Mus" +TR,50,"Nevsehir" +TR,52,"Ordu" +TR,53,"Rize" +TR,54,"Sakarya" +TR,55,"Samsun" +TR,57,"Sinop" +TR,58,"Sivas" +TR,59,"Tekirdag" +TR,60,"Tokat" +TR,61,"Trabzon" +TR,62,"Tunceli" +TR,63,"Sanliurfa" +TR,64,"Usak" +TR,65,"Van" +TR,66,"Yozgat" +TR,68,"Ankara" +TR,69,"Gumushane" +TR,70,"Hakkari" +TR,71,"Konya" +TR,72,"Mardin" +TR,73,"Nigde" +TR,74,"Siirt" +TR,75,"Aksaray" +TR,76,"Batman" +TR,77,"Bayburt" +TR,78,"Karaman" +TR,79,"Kirikkale" +TR,80,"Sirnak" +TR,81,"Adana" +TR,82,"Cankiri" +TR,83,"Gaziantep" +TR,84,"Kars" +TR,85,"Zonguldak" +TR,86,"Ardahan" +TR,87,"Bartin" +TR,88,"Igdir" +TR,89,"Karabuk" +TR,90,"Kilis" +TR,91,"Osmaniye" +TR,92,"Yalova" +TR,93,"Duzce" +TT,01,"Arima" +TT,02,"Caroni" +TT,03,"Mayaro" +TT,04,"Nariva" +TT,05,"Port-of-Spain" +TT,06,"Saint Andrew" +TT,07,"Saint David" +TT,08,"Saint George" +TT,09,"Saint Patrick" +TT,10,"San Fernando" +TT,11,"Tobago" +TT,12,"Victoria" +TW,01,"Fu-chien" +TW,02,"Kao-hsiung" +TW,03,"T'ai-pei" +TW,04,"T'ai-wan" +TZ,02,"Pwani" +TZ,03,"Dodoma" +TZ,04,"Iringa" +TZ,05,"Kigoma" +TZ,06,"Kilimanjaro" +TZ,07,"Lindi" +TZ,08,"Mara" +TZ,09,"Mbeya" +TZ,10,"Morogoro" +TZ,11,"Mtwara" +TZ,12,"Mwanza" +TZ,13,"Pemba North" +TZ,14,"Ruvuma" +TZ,15,"Shinyanga" +TZ,16,"Singida" +TZ,17,"Tabora" +TZ,18,"Tanga" +TZ,19,"Kagera" +TZ,20,"Pemba South" +TZ,21,"Zanzibar Central" +TZ,22,"Zanzibar North" +TZ,23,"Dar es Salaam" +TZ,24,"Rukwa" +TZ,25,"Zanzibar Urban" +TZ,26,"Arusha" +TZ,27,"Manyara" +UA,01,"Cherkas'ka Oblast'" +UA,02,"Chernihivs'ka Oblast'" +UA,03,"Chernivets'ka Oblast'" +UA,04,"Dnipropetrovs'ka Oblast'" +UA,05,"Donets'ka Oblast'" +UA,06,"Ivano-Frankivs'ka Oblast'" +UA,07,"Kharkivs'ka Oblast'" +UA,08,"Khersons'ka Oblast'" +UA,09,"Khmel'nyts'ka Oblast'" +UA,10,"Kirovohrads'ka Oblast'" +UA,11,"Krym" +UA,12,"Kyyiv" +UA,13,"Kyyivs'ka Oblast'" +UA,14,"Luhans'ka Oblast'" +UA,15,"L'vivs'ka Oblast'" +UA,16,"Mykolayivs'ka Oblast'" +UA,17,"Odes'ka Oblast'" +UA,18,"Poltavs'ka Oblast'" +UA,19,"Rivnens'ka Oblast'" +UA,20,"Sevastopol'" +UA,21,"Sums'ka Oblast'" +UA,22,"Ternopil's'ka Oblast'" +UA,23,"Vinnyts'ka Oblast'" +UA,24,"Volyns'ka Oblast'" +UA,25,"Zakarpats'ka Oblast'" +UA,26,"Zaporiz'ka Oblast'" +UA,27,"Zhytomyrs'ka Oblast'" +UG,26,"Apac" +UG,28,"Bundibugyo" +UG,29,"Bushenyi" +UG,30,"Gulu" +UG,31,"Hoima" +UG,33,"Jinja" +UG,36,"Kalangala" +UG,37,"Kampala" +UG,38,"Kamuli" +UG,39,"Kapchorwa" +UG,40,"Kasese" +UG,41,"Kibale" +UG,42,"Kiboga" +UG,43,"Kisoro" +UG,45,"Kotido" +UG,46,"Kumi" +UG,47,"Lira" +UG,50,"Masindi" +UG,52,"Mbarara" +UG,56,"Mubende" +UG,58,"Nebbi" +UG,59,"Ntungamo" +UG,60,"Pallisa" +UG,61,"Rakai" +UG,65,"Adjumani" +UG,66,"Bugiri" +UG,67,"Busia" +UG,69,"Katakwi" +UG,70,"Luwero" +UG,71,"Masaka" +UG,72,"Moyo" +UG,73,"Nakasongola" +UG,74,"Sembabule" +UG,76,"Tororo" +UG,77,"Arua" +UG,78,"Iganga" +UG,79,"Kabarole" +UG,80,"Kaberamaido" +UG,81,"Kamwenge" +UG,82,"Kanungu" +UG,83,"Kayunga" +UG,84,"Kitgum" +UG,85,"Kyenjojo" +UG,86,"Mayuge" +UG,87,"Mbale" +UG,88,"Moroto" +UG,89,"Mpigi" +UG,90,"Mukono" +UG,91,"Nakapiripirit" +UG,92,"Pader" +UG,93,"Rukungiri" +UG,94,"Sironko" +UG,95,"Soroti" +UG,96,"Wakiso" +UG,97,"Yumbe" +US,AA,"Armed Forces Americas" +US,AE,"Armed Forces Europe, Middle East, & Canada" +US,AK,"Alaska" +US,AL,"Alabama" +US,AP,"Armed Forces Pacific" +US,AR,"Arkansas" +US,AS,"American Samoa" +US,AZ,"Arizona" +US,CA,"California" +US,CO,"Colorado" +US,CT,"Connecticut" +US,DC,"District of Columbia" +US,DE,"Delaware" +US,FL,"Florida" +US,FM,"Federated States of Micronesia" +US,GA,"Georgia" +US,GU,"Guam" +US,HI,"Hawaii" +US,IA,"Iowa" +US,ID,"Idaho" +US,IL,"Illinois" +US,IN,"Indiana" +US,KS,"Kansas" +US,KY,"Kentucky" +US,LA,"Louisiana" +US,MA,"Massachusetts" +US,MD,"Maryland" +US,ME,"Maine" +US,MH,"Marshall Islands" +US,MI,"Michigan" +US,MN,"Minnesota" +US,MO,"Missouri" +US,MP,"Northern Mariana Islands" +US,MS,"Mississippi" +US,MT,"Montana" +US,NC,"North Carolina" +US,ND,"North Dakota" +US,NE,"Nebraska" +US,NH,"New Hampshire" +US,NJ,"New Jersey" +US,NM,"New Mexico" +US,NV,"Nevada" +US,NY,"New York" +US,OH,"Ohio" +US,OK,"Oklahoma" +US,OR,"Oregon" +US,PA,"Pennsylvania" +US,PW,"Palau" +US,RI,"Rhode Island" +US,SC,"South Carolina" +US,SD,"South Dakota" +US,TN,"Tennessee" +US,TX,"Texas" +US,UT,"Utah" +US,VA,"Virginia" +US,VI,"Virgin Islands" +US,VT,"Vermont" +US,WA,"Washington" +US,WI,"Wisconsin" +US,WV,"West Virginia" +US,WY,"Wyoming" +UY,01,"Artigas" +UY,02,"Canelones" +UY,03,"Cerro Largo" +UY,04,"Colonia" +UY,05,"Durazno" +UY,06,"Flores" +UY,07,"Florida" +UY,08,"Lavalleja" +UY,09,"Maldonado" +UY,10,"Montevideo" +UY,11,"Paysandu" +UY,12,"Rio Negro" +UY,13,"Rivera" +UY,14,"Rocha" +UY,15,"Salto" +UY,16,"San Jose" +UY,17,"Soriano" +UY,18,"Tacuarembo" +UY,19,"Treinta y Tres" +UZ,01,"Andijon" +UZ,02,"Bukhoro" +UZ,03,"Farghona" +UZ,04,"Jizzakh" +UZ,05,"Khorazm" +UZ,06,"Namangan" +UZ,07,"Nawoiy" +UZ,08,"Qashqadaryo" +UZ,09,"Qoraqalpoghiston" +UZ,10,"Samarqand" +UZ,11,"Sirdaryo" +UZ,12,"Surkhondaryo" +UZ,13,"Toshkent" +UZ,14,"Toshkent" +UZ,15,"Jizzax" +VC,01,"Charlotte" +VC,02,"Saint Andrew" +VC,03,"Saint David" +VC,04,"Saint George" +VC,05,"Saint Patrick" +VC,06,"Grenadines" +VE,01,"Amazonas" +VE,02,"Anzoategui" +VE,03,"Apure" +VE,04,"Aragua" +VE,05,"Barinas" +VE,06,"Bolivar" +VE,07,"Carabobo" +VE,08,"Cojedes" +VE,09,"Delta Amacuro" +VE,11,"Falcon" +VE,12,"Guarico" +VE,13,"Lara" +VE,14,"Merida" +VE,15,"Miranda" +VE,16,"Monagas" +VE,17,"Nueva Esparta" +VE,18,"Portuguesa" +VE,19,"Sucre" +VE,20,"Tachira" +VE,21,"Trujillo" +VE,22,"Yaracuy" +VE,23,"Zulia" +VE,24,"Dependencias Federales" +VE,25,"Distrito Federal" +VE,26,"Vargas" +VN,01,"An Giang" +VN,03,"Ben Tre" +VN,05,"Cao Bang" +VN,09,"Dong Thap" +VN,13,"Hai Phong" +VN,20,"Ho Chi Minh" +VN,21,"Kien Giang" +VN,23,"Lam Dong" +VN,24,"Long An" +VN,30,"Quang Ninh" +VN,32,"Son La" +VN,33,"Tay Ninh" +VN,34,"Thanh Hoa" +VN,35,"Thai Binh" +VN,37,"Tien Giang" +VN,39,"Lang Son" +VN,43,"Dong Nai" +VN,44,"Ha Noi" +VN,45,"Ba Ria-Vung Tau" +VN,46,"Binh Dinh" +VN,47,"Binh Thuan" +VN,49,"Gia Lai" +VN,50,"Ha Giang" +VN,52,"Ha Tinh" +VN,53,"Hoa Binh" +VN,54,"Khanh Hoa" +VN,55,"Kon Tum" +VN,58,"Nghe An" +VN,59,"Ninh Binh" +VN,60,"Ninh Thuan" +VN,61,"Phu Yen" +VN,62,"Quang Binh" +VN,63,"Quang Ngai" +VN,64,"Quang Tri" +VN,65,"Soc Trang" +VN,66,"Thua Thien-Hue" +VN,67,"Tra Vinh" +VN,68,"Tuyen Quang" +VN,69,"Vinh Long" +VN,70,"Yen Bai" +VN,71,"Bac Giang" +VN,72,"Bac Kan" +VN,73,"Bac Lieu" +VN,74,"Bac Ninh" +VN,75,"Binh Duong" +VN,76,"Binh Phuoc" +VN,77,"Ca Mau" +VN,78,"Da Nang" +VN,79,"Hai Duong" +VN,80,"Ha Nam" +VN,81,"Hung Yen" +VN,82,"Nam Dinh" +VN,83,"Phu Tho" +VN,84,"Quang Nam" +VN,85,"Thai Nguyen" +VN,86,"Vinh Phuc" +VN,87,"Can Tho" +VN,88,"Dac Lak" +VN,89,"Lai Chau" +VN,90,"Lao Cai" +VN,91,"Dak Nong" +VN,92,"Dien Bien" +VN,93,"Hau Giang" +VU,05,"Ambrym" +VU,06,"Aoba" +VU,07,"Torba" +VU,08,"Efate" +VU,09,"Epi" +VU,10,"Malakula" +VU,11,"Paama" +VU,12,"Pentecote" +VU,13,"Sanma" +VU,14,"Shepherd" +VU,15,"Tafea" +VU,16,"Malampa" +VU,17,"Penama" +VU,18,"Shefa" +WS,02,"Aiga-i-le-Tai" +WS,03,"Atua" +WS,04,"Fa" +WS,05,"Gaga" +WS,06,"Va" +WS,07,"Gagaifomauga" +WS,08,"Palauli" +WS,09,"Satupa" +WS,10,"Tuamasaga" +WS,11,"Vaisigano" +YE,01,"Abyan" +YE,02,"Adan" +YE,03,"Al Mahrah" +YE,04,"Hadramawt" +YE,05,"Shabwah" +YE,06,"Lahij" +YE,07,"Al Bayda'" +YE,08,"Al Hudaydah" +YE,09,"Al Jawf" +YE,10,"Al Mahwit" +YE,11,"Dhamar" +YE,12,"Hajjah" +YE,13,"Ibb" +YE,14,"Ma'rib" +YE,15,"Sa'dah" +YE,16,"San'a'" +YE,17,"Taizz" +YE,18,"Ad Dali" +YE,19,"Amran" +YE,20,"Al Bayda'" +YE,21,"Al Jawf" +YE,22,"Hajjah" +YE,23,"Ibb" +YE,24,"Lahij" +YE,25,"Taizz" +ZA,01,"North-Western Province" +ZA,02,"KwaZulu-Natal" +ZA,03,"Free State" +ZA,05,"Eastern Cape" +ZA,06,"Gauteng" +ZA,07,"Mpumalanga" +ZA,08,"Northern Cape" +ZA,09,"Limpopo" +ZA,10,"North-West" +ZA,11,"Western Cape" +ZM,01,"Western" +ZM,02,"Central" +ZM,03,"Eastern" +ZM,04,"Luapula" +ZM,05,"Northern" +ZM,06,"North-Western" +ZM,07,"Southern" +ZM,08,"Copperbelt" +ZM,09,"Lusaka" +ZW,01,"Manicaland" +ZW,02,"Midlands" +ZW,03,"Mashonaland Central" +ZW,04,"Mashonaland East" +ZW,05,"Mashonaland West" +ZW,06,"Matabeleland North" +ZW,07,"Matabeleland South" +ZW,08,"Masvingo" +ZW,09,"Bulawayo" +ZW,10,"Harare" diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..8c38178 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,38 @@ +check_PROGRAMS = test-geoip test-geoip-invalid-file + +noinst_PROGRAMS = benchmark test-geoip-region test-geoip-city test-geoip-org test-geoip-domain test-geoip-asnum test-geoip-isp test-geoip-netspeed + +EXTRA_PROGRAMS = benchmark \ + test-geoip-region \ + test-geoip-city \ + test-geoip-org \ + test-geoip-domain \ + test-geoip-asnum \ + test-geoip-isp \ + test-geoip-netspeed + +LDADD = $(top_builddir)/libGeoIP/libGeoIP.la +AM_CPPFLAGS = -I$(top_srcdir)/libGeoIP -DSRCDIR=\"$(top_srcdir)\" -Wall + +test_geoip_SOURCES = test-geoip.c + +test_geoip_invalid_file_SOURCES = test-geoip-invalid-file.c + +test_geoip_region_SOURCES = test-geoip-region.c + +test_geoip_org_SOURCES = test-geoip-org.c + +test_geoip_domain_SOURCES = test-geoip-domain.c + +test_geoip_isp_SOURCES = test-geoip-isp.c + +test_geoip_asnum_SOURCES = test-geoip-asnum.c + +test_geoip_netspeed_SOURCES = test-geoip-netspeed.c + +test_geoip_city_SOURCES = test-geoip-city.c + +benchmark_SOURCES = benchmark.c + +EXTRA_DIST = Makefile.vc city_test.txt country_test.txt country_test2.txt country_test_name.txt region_test.txt +TESTS = test-geoip test-geoip-invalid-file diff --git a/test/Makefile.vc b/test/Makefile.vc new file mode 100644 index 0000000..db80c10 --- /dev/null +++ b/test/Makefile.vc @@ -0,0 +1,29 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +COMPILER=cl + +LINK = link -nologo + +CFLAGS=-DWIN32 -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DSRCDIR=\"../\" + +GEOIPLIB = ..\libGeoIP\GeoIP.lib + +EXTRA_LIBS= advapi32.lib wsock32.lib + +AR=lib + +TEST: benchmark.exe test-geoip.exe + +benchmark.exe: benchmark.c + $(CC1) -c benchmark.c + $(LINK) benchmark.obj $(GEOIPLIB) + +test-geoip.exe: test-geoip.c + $(CC1) -c test-geoip.c + $(LINK) test-geoip.obj $(GEOIPLIB) + diff --git a/test/benchmark.c b/test/benchmark.c new file mode 100644 index 0000000..2d7925a --- /dev/null +++ b/test/benchmark.c @@ -0,0 +1,183 @@ +#include "GeoIP.h" +#include "GeoIPCity.h" +#include <stdio.h> +#if !defined(_MSC_VER) +#include <sys/time.h> +#endif + +char *ipstring[4] = { + "24.24.24.24", "80.24.24.80", "200.24.24.40", "68.24.24.46"}; + +int numipstrings = 4; + +#if defined(_WIN32) +#define DATADIR SRCDIR "/data/" +#else +#define DATADIR "/usr/local/share/GeoIP/" +#endif + +#define GEOIP_OPEN(basename, flg) \ + do { \ + i = GeoIP_open(DATADIR basename, (flg) | GEOIP_SILENCE); \ + if (i == NULL) { \ + printf("error: %s%s does not exist\n", DATADIR, basename); \ + return; \ + /* or a 'longjmp(geo_jmp,1)'? */ \ + } \ + } while (0) + +#if !defined(_WIN32) +struct timeval timer_t1; +struct timeval timer_t2; +#else /* !defined(_WIN32) */ +FILETIME timer_t1; /* 100 ns */ +FILETIME timer_t2; +#endif /* !defined(_WIN32) */ + +#if !defined(_WIN32) +void timerstart(void) { gettimeofday(&timer_t1, NULL); } + +double timerstop(void) { + int a1 = 0; + int a2 = 0; + double r = 0; + gettimeofday(&timer_t2, NULL); + a1 = timer_t2.tv_sec - timer_t1.tv_sec; + a2 = timer_t2.tv_usec - timer_t1.tv_usec; + if (a1 < 0) { + a1 = a1 - 1; + a2 = a2 + 1000000; + } + r = (((double)a1) + (((double)a2) / 1000000)); + return r; +} +#else /* !defined(_WIN32) */ +void timerstart(void) { GetSystemTimeAsFileTime(&timer_t1); } + +double timerstop(void) { + __int64 delta; /* VC6 can't convert an unsigned int64 to to double */ + GetSystemTimeAsFileTime(&timer_t2); + delta = FILETIME_TO_USEC(timer_t2) - FILETIME_TO_USEC(timer_t1); + return ((double)delta) / 1E6; +} +#endif /* !defined(_WIN32) */ + +void testgeoipcountry(int flags, const char *msg, int numlookups) { + double t = 0; + int i4 = 0; + int i2 = 0; + GeoIP *i = NULL; + + GEOIP_OPEN("GeoIP.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + GeoIP_country_name_by_addr(i, ipstring[i4]); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +void testgeoiporg(int flags, const char *msg, int numlookups) { + GeoIP *i = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + + GEOIP_OPEN("GeoIPOrg.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + free(GeoIP_name_by_addr(i, ipstring[i4])); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +void testgeoipregion(int flags, const char *msg, int numlookups) { + GeoIP *i = NULL; + GeoIPRegion *i3 = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + + GEOIP_OPEN("GeoIPRegion.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + i3 = GeoIP_region_by_addr(i, ipstring[i4]); + GeoIPRegion_delete(i3); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +void testgeoipcity(int flags, const char *msg, int numlookups) { + GeoIP *i = NULL; + GeoIPRecord *i3 = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + + GEOIP_OPEN("GeoLiteCity.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + i3 = GeoIP_record_by_addr(i, ipstring[i4]); + GeoIPRecord_delete(i3); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +int main(void) { + int time = 300 * numipstrings; + testgeoipcountry(0, "GeoIP Country", 100 * time); + testgeoipcountry( + GEOIP_CHECK_CACHE, "GeoIP Country with GEOIP_CHECK_CACHE", 100 * time); + testgeoipcountry(GEOIP_MEMORY_CACHE, + "GeoIP Country with GEOIP_MEMORY_CACHE", + 1000 * time); + testgeoipcountry( + GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE, + "GeoIP Country with GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE", + 1000 * time); + + testgeoipregion(0, "GeoIP Region", 100 * time); + testgeoipregion( + GEOIP_CHECK_CACHE, "GeoIP Region with GEOIP_CHECK_CACHE", 100 * time); + testgeoipregion(GEOIP_MEMORY_CACHE, + "GeoIP Region with GEOIP_MEMORY_CACHE", + 1000 * time); + testgeoipregion( + GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE, + "GeoIP Region with GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE", + 1000 * time); + + testgeoiporg(0, "GeoIP Org", 50 * time); + testgeoiporg( + GEOIP_INDEX_CACHE, "GeoIP Org with GEOIP_INDEX_CACHE", 200 * time); + testgeoiporg(GEOIP_INDEX_CACHE | GEOIP_CHECK_CACHE, + "GeoIP Org with GEOIP_INDEX_CACHE and GEOIP_CHECK_CACHE", + 200 * time); + testgeoiporg( + GEOIP_MEMORY_CACHE, "GeoIP Org with GEOIP_MEMORY_CACHE", 500 * time); + + testgeoipcity(0, "GeoIP City", 50 * time); + testgeoipcity( + GEOIP_INDEX_CACHE, "GeoIP City with GEOIP_INDEX_CACHE", 200 * time); + testgeoipcity(GEOIP_INDEX_CACHE | GEOIP_CHECK_CACHE, + "GeoIP City with GEOIP_INDEX_CACHE and GEOIP_CHECK_CACHE", + 200 * time); + testgeoipcity( + GEOIP_MEMORY_CACHE, "GeoIP City with GEOIP_MEMORY_CACHE", 500 * time); + return 0; +} diff --git a/test/city_test.txt b/test/city_test.txt new file mode 100644 index 0000000..2ba04ac --- /dev/null +++ b/test/city_test.txt @@ -0,0 +1,2 @@ +24.24.24.24 # Should return Ithaca, NY, US +80.24.24.24 # Should return Madrid, 29, ES diff --git a/test/country_test.txt b/test/country_test.txt new file mode 100644 index 0000000..a395b75 --- /dev/null +++ b/test/country_test.txt @@ -0,0 +1,61 @@ +12.87.118.0 US USA +63.147.126.103 FR FRA +64.17.254.216 US USA +65.23.121.221 US USA +65.116.3.80 US USA +66.92.181.240 US USA +67.43.156.0 A1 A1 +67.43.156.64 A1 A1 +67.43.156.128 A1 A1 +67.43.156.192 A1 A1 +69.218.251.16 US USA +70.46.123.145 US USA +71.138.104.240 US USA +72.214.6.72 GB GBR +74.0.137.194 US USA +75.77.211.208 US USA +78.26.70.208 IT ITA +81.2.69.160 GB GBR +82.99.17.96 NO NOR +83.206.36.224 FR FRA +85.88.2.224 DE DEU +89.92.212.0 FR FRA +89.92.212.32 FR FRA +89.92.212.80 FR FRA +89.92.212.94 FR FRA +89.92.212.95 FR FRA +89.92.212.96 FR FRA +89.92.212.144 FR FRA +89.92.212.224 FR FRA +89.92.212.248 FR FRA +89.92.212.252 FR FRA +89.92.213.0 FR FRA +89.92.213.16 FR FRA +89.92.213.32 FR FRA +89.92.213.44 FR FRA +89.92.213.48 FR FRA +89.92.213.64 FR FRA +89.92.213.80 FR FRA +89.92.213.88 FR FRA +89.92.213.96 FR FRA +89.92.213.104 FR FRA +89.92.213.108 FR FRA +89.92.213.110 FR FRA +89.92.213.112 FR FRA +89.92.213.166 FR FRA +89.92.213.167 FR FRA +89.92.213.168 FR FRA +89.92.213.176 FR FRA +89.92.213.192 FR FRA +89.92.213.200 FR FRA +89.92.213.224 FR FRA +89.160.20.112 SE SWE +142.217.214.0 CA CAN +143.217.214.0 VN VNM +204.128.241.208 CA CAN +208.110.217.107 US USA +216.83.171.192 US USA +216.160.83.56 US USA +222.230.136.0 JP JPN +222.230.137.0 JP JPN +223.0.0.0 FR FRA diff --git a/test/country_test2.txt b/test/country_test2.txt new file mode 100644 index 0000000..30c5982 --- /dev/null +++ b/test/country_test2.txt @@ -0,0 +1,61 @@ +12.87.118.0 US +63.147.126.103 FR +64.17.254.216 US +65.23.121.221 US +65.116.3.80 US +66.92.181.240 US +67.43.156.0 A1 +67.43.156.64 A1 +67.43.156.128 A1 +67.43.156.192 A1 +69.218.251.16 US +70.46.123.145 US +71.138.104.240 US +72.214.6.72 GB +74.0.137.194 US +75.77.211.208 US +78.26.70.208 IT +81.2.69.160 GB +82.99.17.96 NO +83.206.36.224 FR +85.88.2.224 DE +89.92.212.0 FR +89.92.212.32 FR +89.92.212.80 FR +89.92.212.94 FR +89.92.212.95 FR +89.92.212.96 FR +89.92.212.144 FR +89.92.212.224 FR +89.92.212.248 FR +89.92.212.252 FR +89.92.213.0 FR +89.92.213.16 FR +89.92.213.32 FR +89.92.213.44 FR +89.92.213.48 FR +89.92.213.64 FR +89.92.213.80 FR +89.92.213.88 FR +89.92.213.96 FR +89.92.213.104 FR +89.92.213.108 FR +89.92.213.110 FR +89.92.213.112 FR +89.92.213.166 FR +89.92.213.167 FR +89.92.213.168 FR +89.92.213.176 FR +89.92.213.192 FR +89.92.213.200 FR +89.92.213.224 FR +89.160.20.112 SE +142.217.214.0 CA +143.217.214.0 VN +204.128.241.208 CA +208.110.217.107 US +216.83.171.192 US +216.160.83.56 US +222.230.136.0 JP +222.230.137.0 JP +223.0.0.0 FR diff --git a/test/country_test_name.txt b/test/country_test_name.txt new file mode 100644 index 0000000..ce71409 --- /dev/null +++ b/test/country_test_name.txt @@ -0,0 +1 @@ +yahoo.com US diff --git a/test/fail_test.txt b/test/fail_test.txt new file mode 100644 index 0000000..902ee09 --- /dev/null +++ b/test/fail_test.txt @@ -0,0 +1 @@ +136.253.10.148 AU diff --git a/test/proxy_test.txt b/test/proxy_test.txt new file mode 100644 index 0000000..b11a2e1 --- /dev/null +++ b/test/proxy_test.txt @@ -0,0 +1,17 @@ +66.119.33.170 3 +139.134.64.157 2 +12.148.160.0 1 +24.24.24.21 0 +24.24.24.22 0 +24.24.24.23 0 +24.24.24.24 0 +24.24.24.25 0 +24.24.24.26 0 +145.253.2.25 1 +203.26.24.212 1 +195.229.241.233 1 +200.158.23.208 2 +80.247.152.5 2 +200.161.189.226 2 +66.119.33.135 3 +80.58.39.42 3 diff --git a/test/region_test.txt b/test/region_test.txt new file mode 100644 index 0000000..2828a57 --- /dev/null +++ b/test/region_test.txt @@ -0,0 +1,24 @@ +216.236.135.152 US USA +24.24.24.24 US USA +147.251.48.1 CZ CZE +203.174.65.12 JP JPN +212.208.74.140 FR FRA +200.219.192.106 BR BRA +134.102.101.18 DE DEU +193.75.148.28 BE BEL +194.244.83.2 IT ITA +203.15.106.23 AU AUS +196.31.1.1 ZA ZAF +151.28.39.114 IT ITA +151.38.70.94 IT ITA +193.56.4.124 FR FRA +195.142.146.198 TR TUR +211.232.0.0 KR KOR +211.240.0.0 KR KOR +193.194.4.0 MA MAR +139.20.112.104 DE DEU +139.20.112.3 DE DEU +145.236.125.211 HU HUN +yahoo.com US USA +amazon.com US USA +www.uspto.gov US USA diff --git a/test/test-geoip-asnum.c b/test/test-geoip-asnum.c new file mode 100644 index 0000000..56d1cc8 --- /dev/null +++ b/test/test-geoip-asnum.c @@ -0,0 +1,56 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-asnum.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *org; + char host[50]; + + gi = GeoIP_open("../data/GeoIPASNum.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("asnum_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening asnum_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_org_by_name(gi, (const char *)host); + + if (org != NULL) { + printf("%s\t%s\n", host, _mk_NA(org)); + } + } + + GeoIP_delete(gi); + fclose(f); + return 0; +} diff --git a/test/test-geoip-city.c b/test/test-geoip-city.c new file mode 100644 index 0000000..93568e0 --- /dev/null +++ b/test/test-geoip-city.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-city.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + GeoIPRecord *gir; + char host[50]; + const char *time_zone = NULL; + char **ret; + + gi = GeoIP_open("../data/GeoIPCity.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("city_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening city_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + gir = GeoIP_record_by_name(gi, (const char *)host); + + if (gir != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *)host); + time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, + gir->region); + printf("%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d\t%s\t%s\t%s\n", + host, + _mk_NA(gir->country_code), + _mk_NA(gir->region), + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude, + gir->metro_code, + gir->area_code, + _mk_NA(time_zone), + ret[0], + ret[1]); + GeoIP_range_by_ip_delete(ret); + GeoIPRecord_delete(gir); + } + } + GeoIP_delete(gi); + fclose(f); + return 0; +} diff --git a/test/test-geoip-domain.c b/test/test-geoip-domain.c new file mode 100644 index 0000000..d8ac609 --- /dev/null +++ b/test/test-geoip-domain.c @@ -0,0 +1,67 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-org.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *domain; + char host[50]; + char **ret; + + gi = GeoIP_open("../data/GeoIPDomain.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("domain_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening domain_test.txt\n"); + exit(1); + } + + printf("IP\tdomain\tnetmask\tbeginIp\tendIp\n"); + while (fscanf(f, "%s", host) != EOF) { + domain = GeoIP_name_by_name(gi, (const char *)host); + + if (domain != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *)host); + + printf("%s\t%s\t%d\t%s\t%s\n", + host, + _mk_NA(domain), + GeoIP_last_netmask(gi), + ret[0], + ret[1]); + GeoIP_range_by_ip_delete(ret); + free(domain); + } + } + + fclose(f); + GeoIP_delete(gi); + return 0; +} diff --git a/test/test-geoip-invalid-file.c b/test/test-geoip-invalid-file.c new file mode 100644 index 0000000..10fe246 --- /dev/null +++ b/test/test-geoip-invalid-file.c @@ -0,0 +1,29 @@ +#include "GeoIP.h" + +int main(void) { + GeoIP *gi = GeoIP_open(SRCDIR "/README.md", GEOIP_MEMORY_CACHE); + + /* We don't detect invalid files at load, unfortunately. */ + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + return 1; + } + + const char *country = GeoIP_country_code_by_addr(gi, "24.24.24.24"); + if (country != NULL) { + fprintf(stderr, + "Received a non-NULL value on an invalid database from " + "GeoIP_country_code_by_addr\n"); + return 1; + } + + country = GeoIP_country_code_by_addr_v6(gi, "24.24.24.24"); + if (country != NULL) { + fprintf(stderr, + "Received a non-NULL value on an invalid database from " + "GeoIP_country_code_by_addr_v6\n"); + return 1; + } + + return 0; +} diff --git a/test/test-geoip-isp.c b/test/test-geoip-isp.c new file mode 100644 index 0000000..e4c3bb4 --- /dev/null +++ b/test/test-geoip-isp.c @@ -0,0 +1,58 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-isp.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *org; + char host[50]; + + gi = GeoIP_open("../data/GeoIPISP.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("isp_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening isp_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_org_by_name(gi, (const char *)host); + + if (org != NULL) { + printf("%s\t%s\n", host, _mk_NA(org)); + free(org); + } + } + + fclose(f); + GeoIP_delete(gi); + + return 0; +} diff --git a/test/test-geoip-netspeed.c b/test/test-geoip-netspeed.c new file mode 100644 index 0000000..44aac64 --- /dev/null +++ b/test/test-geoip-netspeed.c @@ -0,0 +1,59 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-netspeed.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + int netspeed; + char host[50]; + + gi = GeoIP_open("../data/GeoIPNetSpeed.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("netspeed_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening netspeed_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + netspeed = GeoIP_id_by_name(gi, (const char *)host); + if (netspeed == GEOIP_UNKNOWN_SPEED) { + printf("%s\tUnknown\n", host); + } else if (netspeed == GEOIP_DIALUP_SPEED) { + printf("%s\tDialup\n", host); + } else if (netspeed == GEOIP_CABLEDSL_SPEED) { + printf("%s\tCable/DSL\n", host); + } else if (netspeed == GEOIP_CORPORATE_SPEED) { + printf("%s\tCorporate\n", host); + } + } + fclose(f); + GeoIP_delete(gi); + + return 0; +} diff --git a/test/test-geoip-org.c b/test/test-geoip-org.c new file mode 100644 index 0000000..e42ed53 --- /dev/null +++ b/test/test-geoip-org.c @@ -0,0 +1,67 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-org.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *org; + char host[50]; + char **ret; + + gi = GeoIP_open("../data/GeoIPOrg.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("org_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening org_test.txt\n"); + exit(1); + } + + printf("IP\torganization\tnetmask\tbeginIp\tendIp\n"); + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_name_by_name(gi, (const char *)host); + + if (org != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *)host); + + printf("%s\t%s\t%d\t%s\t%s\n", + host, + _mk_NA(org), + GeoIP_last_netmask(gi), + ret[0], + ret[1]); + GeoIP_range_by_ip_delete(ret); + free(org); + } + } + + fclose(f); + GeoIP_delete(gi); + return 0; +} diff --git a/test/test-geoip-region.c b/test/test-geoip-region.c new file mode 100644 index 0000000..839bf45 --- /dev/null +++ b/test/test-geoip-region.c @@ -0,0 +1,118 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-region.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include <sys/types.h> /* For uint32_t */ +#ifdef HAVE_STDINT_H +#include <stdint.h> /* For uint32_t */ +#endif +#if !defined(_WIN32) +#include <netdb.h> /* For gethostbyname */ +#include <netinet/in.h> /* For ntohl */ +#else +#include <windows.h> +#include <winsock.h> +#endif +#include <assert.h> + +unsigned long inetaddr(const char *name) { + struct hostent *host; + struct in_addr inaddr; + + host = gethostbyname(name); + assert(host); + inaddr.s_addr = *((uint32_t *)host->h_addr_list[0]); + return inaddr.s_addr; +} + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(void) { + GeoIP *gi; + GeoIPRegion *gir, giRegion; + + FILE *f; + char ipAddress[30]; + char expectedCountry[3]; + char expectedCountry3[4]; + const char *time_zone; + + gi = GeoIP_open("../data/GeoIPRegion.dat", GEOIP_MEMORY_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("region_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening region_test.txt\n"); + exit(1); + } + + gir = GeoIP_region_by_addr(gi, "10.0.0.0"); + if (gir != NULL) { + printf("lookup of private IP address: country = %s, region = %s\n", + gir->country_code, + gir->region); + } + + while (fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3) != + EOF) { + printf("ip = %s\n", ipAddress); + + gir = GeoIP_region_by_name(gi, ipAddress); + if (gir != NULL) { + time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, + gir->region); + printf("%s, %s, %s, %s\n", + gir->country_code, + (!gir->region[0]) ? "N/A" : gir->region, + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(time_zone)); + } else { + printf("NULL!\n"); + } + + GeoIP_assign_region_by_inetaddr(gi, inetaddr(ipAddress), &giRegion); + if (gir != NULL) { + assert(giRegion.country_code[0]); + assert(!strcmp(gir->country_code, giRegion.country_code)); + if (gir->region[0]) { + assert(giRegion.region[0]); + assert(!strcmp(gir->region, giRegion.region)); + } else { + assert(!giRegion.region[0]); + } + } else { + assert(!giRegion.country_code[0]); + } + + if (gir != NULL) { + GeoIPRegion_delete(gir); + } + } + + GeoIP_delete(gi); + fclose(f); + return 0; +} diff --git a/test/test-geoip.c b/test/test-geoip.c new file mode 100644 index 0000000..909e63c --- /dev/null +++ b/test/test-geoip.c @@ -0,0 +1,146 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +int main(void) { + FILE *f; + char *db_info; + char ipAddress[30]; + char expectedCountry[3]; + char expectedCountry3[4]; + const char *returnedCountry; + GeoIP *gi; + int failed = 0; + int test_num = 1; + + int i; + for (i = 0; i < 2; ++i) { + if (0 == i) { + /* Read from filesystem, check for updated file */ + gi = GeoIP_open(SRCDIR "/data/GeoIP.dat", + GEOIP_STANDARD | GEOIP_CHECK_CACHE); + } else { + /* Read from memory, faster but takes up more memory */ + gi = GeoIP_open(SRCDIR "/data/GeoIP.dat", GEOIP_MEMORY_CACHE); + } + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + db_info = GeoIP_database_info(gi); + if (!db_info || strcmp(db_info, + "GEO-106 20160621 Build 1 Copyright (c) 2016 " + "MaxMind Inc All Rights Reserved")) { + fprintf(stderr, "Error reading database info (got %s).\n", db_info); + free(db_info); + failed = 1; + } + + /* make sure GeoIP deals with invalid query gracefully */ + returnedCountry = GeoIP_country_code_by_addr(gi, NULL); + if (returnedCountry != NULL) { + fprintf(stderr, + "Invalid Query test failed, got non NULL, expected NULL\n"); + failed = 1; + } + + returnedCountry = GeoIP_country_code_by_name(gi, NULL); + if (returnedCountry != NULL) { + fprintf(stderr, + "Invalid Query test failed, got non NULL, expected NULL\n"); + failed = 1; + } + + f = fopen(SRCDIR "/test/country_test.txt", "r"); + + while ( + fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3) != + EOF) { + returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr, + "Test addr %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code_by_name(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr, + "Test name %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code3_by_addr(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry3) != 0) { + fprintf(stderr, + "Test addr %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code3_by_name(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry3) != 0) { + fprintf(stderr, + "Test name %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + test_num++; + } + fclose(f); + + f = fopen(SRCDIR "/test/country_test2.txt", "r"); + while (fscanf(f, "%s%s", ipAddress, expectedCountry) != EOF) { + returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr, + "Test addr %d %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + test_num++; + } + fclose(f); + GeoIP_delete(gi); + } + return failed; +} diff --git a/timezone/generate_timeZone.pl b/timezone/generate_timeZone.pl new file mode 100755 index 0000000..8c4c742 --- /dev/null +++ b/timezone/generate_timeZone.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl +use strict; +use warnings; +use autodie; + +use Text::CSV_XS (); + +# Obtain timezone.txt from http://www.maxmind.com/timezone.txt + +# Used to generate timeZone.c +# usage: ./generate_timeZone.pl > ../libGeoIP/timeZone.c + +my $tz; + +open my $fh, '<:encoding(latin1)', 'timezone.txt'; + +my $csv = Text::CSV_XS->new( { binary => 1, auto_diag => 1 } ); + +print "#include <string.h> \n"; +print + "const char* GeoIP_time_zone_by_country_and_region(const char * country,const char * region) {\n"; +print " const char* timezone = NULL;\n"; +print " if (country == NULL) {\n"; +print " return NULL;\n"; +print " }\n"; +print " if (region == NULL) {\n"; +print ' region = "";', "\n"; +print " }\n"; + +<$fh>; # skip first line +while ( my $row = $csv->getline($fh) ) { + my ( $country, $region, $timezone ) = @{$row}; + die "$_ $.\n" unless $timezone; + $tz->{$country}->{ $region || q{} } = $timezone; +} + +my $first_country; + +$first_country = 0; +for my $c ( sort keys %$tz ) { + print(' if'); + $first_country ||= $c; + my $def = delete $tz->{$c}->{q{}}; + if ( my @reg = sort keys %{ $tz->{$c} } ) { + my @tz = map { $tz->{$c}->{$_} } @reg; + + printf( qq! ( strcmp (country, "%s") == 0 ) {\n!, $c ); + for ( 0 .. $#reg ) { + + # have regions + + print( ( $_ == 0 ) ? ' if' : ' else if' ); + printf( qq! ( strcmp (region, "%s") == 0 ) {\n!, $reg[$_] ); + printf( qq! return "%s";\n!, $tz[$_] ); + printf(qq! }\n!); + } + if ( defined $def ) { + printf( qq! else { return "%s"; }\n!, $def ); + } + else { + print " else {\n return NULL;\n }\n"; + } + print qq[ }\n]; + } + else { + + # only default tz + printf( qq! ( strcmp (country, "%s") == 0 ) {\n!, $c ); + printf( qq! return "%s";\n!, $def ); + printf(qq! }\n!); + + } +} + +print qq[ return timezone;\n}\n]; diff --git a/timezone/timezone.txt b/timezone/timezone.txt new file mode 100644 index 0000000..e35c760 --- /dev/null +++ b/timezone/timezone.txt @@ -0,0 +1,717 @@ +"country","region","timezone" +AD,,"Europe/Andorra" +AE,,"Asia/Dubai" +AF,,"Asia/Kabul" +AG,,"America/Antigua" +AI,,"America/Anguilla" +AL,,"Europe/Tirane" +AM,,"Asia/Yerevan" +AN,,"America/Curacao" +AO,,"Africa/Luanda" +AQ,,"Antarctica/South_Pole" +AR,01,"America/Argentina/Buenos_Aires" +AR,02,"America/Argentina/Catamarca" +AR,03,"America/Argentina/Tucuman" +AR,04,"America/Argentina/Rio_Gallegos" +AR,05,"America/Argentina/Cordoba" +AR,06,"America/Argentina/Tucuman" +AR,07,"America/Argentina/Buenos_Aires" +AR,08,"America/Argentina/Buenos_Aires" +AR,09,"America/Argentina/Tucuman" +AR,10,"America/Argentina/Jujuy" +AR,11,"America/Argentina/San_Luis" +AR,12,"America/Argentina/La_Rioja" +AR,13,"America/Argentina/Mendoza" +AR,14,"America/Argentina/Buenos_Aires" +AR,15,"America/Argentina/San_Luis" +AR,16,"America/Argentina/Buenos_Aires" +AR,17,"America/Argentina/Salta" +AR,18,"America/Argentina/San_Juan" +AR,19,"America/Argentina/San_Luis" +AR,20,"America/Argentina/Rio_Gallegos" +AR,21,"America/Argentina/Buenos_Aires" +AR,22,"America/Argentina/Catamarca" +AR,23,"America/Argentina/Ushuaia" +AR,24,"America/Argentina/Tucuman" +AS,,"Pacific/Pago_Pago" +AT,,"Europe/Vienna" +AU,01,"Australia/Sydney" +AU,02,"Australia/Sydney" +AU,03,"Australia/Darwin" +AU,04,"Australia/Brisbane" +AU,05,"Australia/Adelaide" +AU,06,"Australia/Hobart" +AU,07,"Australia/Melbourne" +AU,08,"Australia/Perth" +AW,,"America/Aruba" +AX,,"Europe/Mariehamn" +AZ,,"Asia/Baku" +BA,,"Europe/Sarajevo" +BB,,"America/Barbados" +BD,,"Asia/Dhaka" +BE,,"Europe/Brussels" +BF,,"Africa/Ouagadougou" +BG,,"Europe/Sofia" +BH,,"Asia/Bahrain" +BI,,"Africa/Bujumbura" +BJ,,"Africa/Porto-Novo" +BL,,"America/St_Barthelemy" +BM,,"Atlantic/Bermuda" +BN,,"Asia/Brunei" +BO,,"America/La_Paz" +BQ,,"America/Curacao" +BR,01,"America/Rio_Branco" +BR,02,"America/Maceio" +BR,03,"America/Sao_Paulo" +BR,04,"America/Manaus" +BR,05,"America/Bahia" +BR,06,"America/Fortaleza" +BR,07,"America/Sao_Paulo" +BR,08,"America/Sao_Paulo" +BR,11,"America/Campo_Grande" +BR,13,"America/Belem" +BR,14,"America/Cuiaba" +BR,15,"America/Sao_Paulo" +BR,16,"America/Belem" +BR,17,"America/Recife" +BR,18,"America/Sao_Paulo" +BR,20,"America/Fortaleza" +BR,21,"America/Sao_Paulo" +BR,22,"America/Recife" +BR,23,"America/Sao_Paulo" +BR,24,"America/Porto_Velho" +BR,25,"America/Boa_Vista" +BR,26,"America/Sao_Paulo" +BR,27,"America/Sao_Paulo" +BR,28,"America/Maceio" +BR,29,"America/Sao_Paulo" +BR,30,"America/Recife" +BR,31,"America/Araguaina" +BS,,"America/Nassau" +BT,,"Asia/Thimphu" +BV,,"Antarctica/Syowa" +BW,,"Africa/Gaborone" +BY,,"Europe/Minsk" +BZ,,"America/Belize" +CA,AB,"America/Edmonton" +CA,BC,"America/Vancouver" +CA,MB,"America/Winnipeg" +CA,NB,"America/Halifax" +CA,NL,"America/St_Johns" +CA,NS,"America/Halifax" +CA,NT,"America/Yellowknife" +CA,NU,"America/Rankin_Inlet" +CA,ON,"America/Toronto" +CA,PE,"America/Halifax" +CA,QC,"America/Montreal" +CA,SK,"America/Regina" +CA,YT,"America/Whitehorse" +CC,,"Indian/Cocos" +CD,01,"Africa/Kinshasa" +CD,02,"Africa/Kinshasa" +CD,03,"Africa/Kinshasa" +CD,04,"Africa/Lubumbashi" +CD,05,"Africa/Lubumbashi" +CD,06,"Africa/Kinshasa" +CD,07,"Africa/Lubumbashi" +CD,08,"Africa/Kinshasa" +CD,09,"Africa/Lubumbashi" +CD,10,"Africa/Lubumbashi" +CD,11,"Africa/Lubumbashi" +CD,12,"Africa/Lubumbashi" +CF,,"Africa/Bangui" +CG,,"Africa/Brazzaville" +CH,,"Europe/Zurich" +CI,,"Africa/Abidjan" +CK,,"Pacific/Rarotonga" +CL,,"America/Santiago" +CM,,"Africa/Lagos" +CN,01,"Asia/Shanghai" +CN,02,"Asia/Shanghai" +CN,03,"Asia/Shanghai" +CN,04,"Asia/Shanghai" +CN,05,"Asia/Harbin" +CN,06,"Asia/Chongqing" +CN,07,"Asia/Shanghai" +CN,08,"Asia/Harbin" +CN,09,"Asia/Shanghai" +CN,10,"Asia/Shanghai" +CN,11,"Asia/Chongqing" +CN,12,"Asia/Shanghai" +CN,13,"Asia/Urumqi" +CN,14,"Asia/Chongqing" +CN,15,"Asia/Chongqing" +CN,16,"Asia/Chongqing" +CN,18,"Asia/Chongqing" +CN,19,"Asia/Harbin" +CN,20,"Asia/Harbin" +CN,21,"Asia/Chongqing" +CN,22,"Asia/Harbin" +CN,23,"Asia/Shanghai" +CN,24,"Asia/Chongqing" +CN,25,"Asia/Shanghai" +CN,26,"Asia/Chongqing" +CN,28,"Asia/Shanghai" +CN,29,"Asia/Chongqing" +CN,30,"Asia/Chongqing" +CN,31,"Asia/Chongqing" +CN,32,"Asia/Chongqing" +CN,33,"Asia/Chongqing" +CO,,"America/Bogota" +CR,,"America/Costa_Rica" +CU,,"America/Havana" +CV,,"Atlantic/Cape_Verde" +CW,,"America/Curacao" +CX,,"Indian/Christmas" +CY,,"Asia/Nicosia" +CZ,,"Europe/Prague" +DE,,"Europe/Berlin" +DJ,,"Africa/Djibouti" +DK,,"Europe/Copenhagen" +DM,,"America/Dominica" +DO,,"America/Santo_Domingo" +DZ,,"Africa/Algiers" +EC,01,"Pacific/Galapagos" +EC,02,"America/Guayaquil" +EC,03,"America/Guayaquil" +EC,04,"America/Guayaquil" +EC,05,"America/Guayaquil" +EC,06,"America/Guayaquil" +EC,07,"America/Guayaquil" +EC,08,"America/Guayaquil" +EC,09,"America/Guayaquil" +EC,10,"America/Guayaquil" +EC,11,"America/Guayaquil" +EC,12,"America/Guayaquil" +EC,13,"America/Guayaquil" +EC,14,"America/Guayaquil" +EC,15,"America/Guayaquil" +EC,17,"America/Guayaquil" +EC,18,"America/Guayaquil" +EC,19,"America/Guayaquil" +EC,20,"America/Guayaquil" +EC,22,"America/Guayaquil" +EC,24,"America/Guayaquil" +EE,,"Europe/Tallinn" +EG,,"Africa/Cairo" +EH,,"Africa/El_Aaiun" +ER,,"Africa/Asmara" +ES,07,"Europe/Madrid" +ES,27,"Europe/Madrid" +ES,29,"Europe/Madrid" +ES,31,"Europe/Madrid" +ES,32,"Europe/Madrid" +ES,34,"Europe/Madrid" +ES,39,"Europe/Madrid" +ES,51,"Africa/Ceuta" +ES,52,"Europe/Madrid" +ES,53,"Atlantic/Canary" +ES,54,"Europe/Madrid" +ES,55,"Europe/Madrid" +ES,56,"Europe/Madrid" +ES,57,"Europe/Madrid" +ES,58,"Europe/Madrid" +ES,59,"Europe/Madrid" +ES,60,"Europe/Madrid" +ET,,"Africa/Addis_Ababa" +FI,,"Europe/Helsinki" +FJ,,"Pacific/Fiji" +FK,,"Atlantic/Stanley" +FM,,"Pacific/Pohnpei" +FO,,"Atlantic/Faroe" +FR,,"Europe/Paris" +FX,,"Europe/Paris" +GA,,"Africa/Libreville" +GB,,"Europe/London" +GD,,"America/Grenada" +GE,,"Asia/Tbilisi" +GF,,"America/Cayenne" +GG,,"Europe/Guernsey" +GH,,"Africa/Accra" +GI,,"Europe/Gibraltar" +GL,01,"America/Thule" +GL,02,"America/Godthab" +GL,03,"America/Godthab" +GM,,"Africa/Banjul" +GN,,"Africa/Conakry" +GP,,"America/Guadeloupe" +GQ,,"Africa/Malabo" +GR,,"Europe/Athens" +GS,,"Atlantic/South_Georgia" +GT,,"America/Guatemala" +GU,,"Pacific/Guam" +GW,,"Africa/Bissau" +GY,,"America/Guyana" +HK,,"Asia/Hong_Kong" +HN,,"America/Tegucigalpa" +HR,,"Europe/Zagreb" +HT,,"America/Port-au-Prince" +HU,,"Europe/Budapest" +ID,01,"Asia/Pontianak" +ID,02,"Asia/Makassar" +ID,03,"Asia/Jakarta" +ID,04,"Asia/Jakarta" +ID,05,"Asia/Jakarta" +ID,06,"Asia/Jakarta" +ID,07,"Asia/Jakarta" +ID,08,"Asia/Jakarta" +ID,09,"Asia/Jayapura" +ID,10,"Asia/Jakarta" +ID,11,"Asia/Pontianak" +ID,12,"Asia/Makassar" +ID,13,"Asia/Makassar" +ID,14,"Asia/Makassar" +ID,15,"Asia/Jakarta" +ID,16,"Asia/Makassar" +ID,17,"Asia/Makassar" +ID,18,"Asia/Makassar" +ID,19,"Asia/Pontianak" +ID,20,"Asia/Makassar" +ID,21,"Asia/Makassar" +ID,22,"Asia/Makassar" +ID,23,"Asia/Makassar" +ID,24,"Asia/Jakarta" +ID,25,"Asia/Pontianak" +ID,26,"Asia/Pontianak" +ID,28,"Asia/Jayapura" +ID,29,"Asia/Makassar" +ID,30,"Asia/Jakarta" +ID,31,"Asia/Makassar" +ID,32,"Asia/Jakarta" +ID,33,"Asia/Jakarta" +ID,34,"Asia/Makassar" +ID,35,"Asia/Pontianak" +ID,36,"Asia/Jayapura" +ID,37,"Asia/Pontianak" +ID,38,"Asia/Makassar" +ID,39,"Asia/Jayapura" +ID,40,"Asia/Pontianak" +ID,41,"Asia/Makassar" +IE,,"Europe/Dublin" +IL,,"Asia/Jerusalem" +IM,,"Europe/Isle_of_Man" +IN,,"Asia/Kolkata" +IO,,"Indian/Chagos" +IQ,,"Asia/Baghdad" +IR,,"Asia/Tehran" +IS,,"Atlantic/Reykjavik" +IT,,"Europe/Rome" +JE,,"Europe/Jersey" +JM,,"America/Jamaica" +JO,,"Asia/Amman" +JP,,"Asia/Tokyo" +KE,,"Africa/Nairobi" +KG,,"Asia/Bishkek" +KH,,"Asia/Phnom_Penh" +KI,,"Pacific/Tarawa" +KM,,"Indian/Comoro" +KN,,"America/St_Kitts" +KP,,"Asia/Pyongyang" +KR,,"Asia/Seoul" +KW,,"Asia/Kuwait" +KY,,"America/Cayman" +KZ,01,"Asia/Almaty" +KZ,02,"Asia/Almaty" +KZ,03,"Asia/Qyzylorda" +KZ,04,"Asia/Aqtobe" +KZ,05,"Asia/Qyzylorda" +KZ,06,"Asia/Aqtau" +KZ,07,"Asia/Oral" +KZ,08,"Asia/Qyzylorda" +KZ,09,"Asia/Aqtau" +KZ,10,"Asia/Qyzylorda" +KZ,11,"Asia/Almaty" +KZ,12,"Asia/Qyzylorda" +KZ,13,"Asia/Aqtobe" +KZ,14,"Asia/Qyzylorda" +KZ,15,"Asia/Almaty" +KZ,16,"Asia/Aqtobe" +KZ,17,"Asia/Almaty" +LA,,"Asia/Vientiane" +LB,,"Asia/Beirut" +LC,,"America/St_Lucia" +LI,,"Europe/Vaduz" +LK,,"Asia/Colombo" +LR,,"Africa/Monrovia" +LS,,"Africa/Maseru" +LT,,"Europe/Vilnius" +LU,,"Europe/Luxembourg" +LV,,"Europe/Riga" +LY,,"Africa/Tripoli" +MA,,"Africa/Casablanca" +MC,,"Europe/Monaco" +MD,,"Europe/Chisinau" +ME,,"Europe/Podgorica" +MF,,"America/Marigot" +MG,,"Indian/Antananarivo" +MH,,"Pacific/Kwajalein" +MK,,"Europe/Skopje" +ML,,"Africa/Bamako" +MM,,"Asia/Rangoon" +MN,06,"Asia/Choibalsan" +MN,11,"Asia/Ulaanbaatar" +MN,17,"Asia/Choibalsan" +MN,19,"Asia/Hovd" +MN,20,"Asia/Ulaanbaatar" +MN,21,"Asia/Ulaanbaatar" +MN,25,"Asia/Ulaanbaatar" +MO,,"Asia/Macau" +MP,,"Pacific/Saipan" +MQ,,"America/Martinique" +MR,,"Africa/Nouakchott" +MS,,"America/Montserrat" +MT,,"Europe/Malta" +MU,,"Indian/Mauritius" +MV,,"Indian/Maldives" +MW,,"Africa/Blantyre" +MX,01,"America/Mexico_City" +MX,02,"America/Tijuana" +MX,03,"America/Hermosillo" +MX,04,"America/Merida" +MX,05,"America/Mexico_City" +MX,06,"America/Chihuahua" +MX,07,"America/Monterrey" +MX,08,"America/Mexico_City" +MX,09,"America/Mexico_City" +MX,10,"America/Mazatlan" +MX,11,"America/Mexico_City" +MX,12,"America/Mexico_City" +MX,13,"America/Mexico_City" +MX,14,"America/Mazatlan" +MX,15,"America/Chihuahua" +MX,16,"America/Mexico_City" +MX,17,"America/Mexico_City" +MX,18,"America/Mazatlan" +MX,19,"America/Monterrey" +MX,20,"America/Mexico_City" +MX,21,"America/Mexico_City" +MX,22,"America/Mexico_City" +MX,23,"America/Cancun" +MX,24,"America/Mexico_City" +MX,25,"America/Mazatlan" +MX,26,"America/Hermosillo" +MX,27,"America/Merida" +MX,28,"America/Monterrey" +MX,29,"America/Mexico_City" +MX,30,"America/Mexico_City" +MX,31,"America/Merida" +MX,32,"America/Monterrey" +MY,01,"Asia/Kuala_Lumpur" +MY,02,"Asia/Kuala_Lumpur" +MY,03,"Asia/Kuala_Lumpur" +MY,04,"Asia/Kuala_Lumpur" +MY,05,"Asia/Kuala_Lumpur" +MY,06,"Asia/Kuala_Lumpur" +MY,07,"Asia/Kuala_Lumpur" +MY,08,"Asia/Kuala_Lumpur" +MY,09,"Asia/Kuala_Lumpur" +MY,11,"Asia/Kuching" +MY,12,"Asia/Kuala_Lumpur" +MY,13,"Asia/Kuala_Lumpur" +MY,14,"Asia/Kuala_Lumpur" +MY,15,"Asia/Kuching" +MY,16,"Asia/Kuching" +MZ,,"Africa/Maputo" +NA,,"Africa/Windhoek" +NC,,"Pacific/Noumea" +NE,,"Africa/Niamey" +NF,,"Pacific/Norfolk" +NG,,"Africa/Lagos" +NI,,"America/Managua" +NL,,"Europe/Amsterdam" +NO,,"Europe/Oslo" +NP,,"Asia/Kathmandu" +NR,,"Pacific/Nauru" +NU,,"Pacific/Niue" +NZ,85,"Pacific/Auckland" +NZ,E7,"Pacific/Auckland" +NZ,E8,"Pacific/Auckland" +NZ,E9,"Pacific/Auckland" +NZ,F1,"Pacific/Auckland" +NZ,F2,"Pacific/Auckland" +NZ,F3,"Pacific/Auckland" +NZ,F4,"Pacific/Auckland" +NZ,F5,"Pacific/Auckland" +NZ,F6,"Pacific/Auckland" +NZ,F7,"Pacific/Chatham" +NZ,F8,"Pacific/Auckland" +NZ,F9,"Pacific/Auckland" +NZ,G1,"Pacific/Auckland" +NZ,G2,"Pacific/Auckland" +NZ,G3,"Pacific/Auckland" +OM,,"Asia/Muscat" +PA,,"America/Panama" +PE,,"America/Lima" +PF,,"Pacific/Marquesas" +PG,,"Pacific/Port_Moresby" +PH,,"Asia/Manila" +PK,,"Asia/Karachi" +PL,,"Europe/Warsaw" +PM,,"America/Miquelon" +PN,,"Pacific/Pitcairn" +PR,,"America/Puerto_Rico" +PS,,"Asia/Gaza" +PT,02,"Europe/Lisbon" +PT,03,"Europe/Lisbon" +PT,04,"Europe/Lisbon" +PT,05,"Europe/Lisbon" +PT,06,"Europe/Lisbon" +PT,07,"Europe/Lisbon" +PT,08,"Europe/Lisbon" +PT,09,"Europe/Lisbon" +PT,10,"Atlantic/Madeira" +PT,11,"Europe/Lisbon" +PT,13,"Europe/Lisbon" +PT,14,"Europe/Lisbon" +PT,16,"Europe/Lisbon" +PT,17,"Europe/Lisbon" +PT,18,"Europe/Lisbon" +PT,19,"Europe/Lisbon" +PT,20,"Europe/Lisbon" +PT,21,"Europe/Lisbon" +PT,22,"Europe/Lisbon" +PT,23,"Atlantic/Azores" +PW,,"Pacific/Palau" +PY,,"America/Asuncion" +QA,,"Asia/Qatar" +RE,,"Indian/Reunion" +RO,,"Europe/Bucharest" +RS,,"Europe/Belgrade" +RU,01,"Europe/Volgograd" +RU,02,"Asia/Irkutsk" +RU,03,"Asia/Novokuznetsk" +RU,04,"Asia/Novosibirsk" +RU,05,"Asia/Vladivostok" +RU,06,"Europe/Moscow" +RU,07,"Europe/Volgograd" +RU,08,"Europe/Samara" +RU,09,"Europe/Moscow" +RU,10,"Europe/Moscow" +RU,11,"Asia/Irkutsk" +RU,12,"Europe/Volgograd" +RU,13,"Asia/Yekaterinburg" +RU,14,"Asia/Irkutsk" +RU,15,"Asia/Anadyr" +RU,16,"Europe/Samara" +RU,17,"Europe/Volgograd" +RU,18,"Asia/Krasnoyarsk" +RU,20,"Asia/Irkutsk" +RU,21,"Europe/Moscow" +RU,22,"Europe/Volgograd" +RU,23,"Europe/Kaliningrad" +RU,24,"Europe/Volgograd" +RU,25,"Europe/Moscow" +RU,26,"Asia/Kamchatka" +RU,27,"Europe/Volgograd" +RU,28,"Europe/Moscow" +RU,29,"Asia/Novokuznetsk" +RU,30,"Asia/Vladivostok" +RU,31,"Asia/Krasnoyarsk" +RU,32,"Asia/Omsk" +RU,33,"Asia/Yekaterinburg" +RU,34,"Asia/Yekaterinburg" +RU,35,"Asia/Yekaterinburg" +RU,36,"Asia/Anadyr" +RU,37,"Europe/Moscow" +RU,38,"Europe/Volgograd" +RU,39,"Asia/Krasnoyarsk" +RU,40,"Asia/Yekaterinburg" +RU,41,"Europe/Moscow" +RU,42,"Europe/Moscow" +RU,43,"Europe/Moscow" +RU,44,"Asia/Magadan" +RU,45,"Europe/Samara" +RU,46,"Europe/Samara" +RU,47,"Europe/Moscow" +RU,48,"Europe/Moscow" +RU,49,"Europe/Moscow" +RU,50,"Asia/Yekaterinburg" +RU,51,"Europe/Moscow" +RU,52,"Europe/Moscow" +RU,53,"Asia/Novosibirsk" +RU,54,"Asia/Omsk" +RU,55,"Europe/Samara" +RU,56,"Europe/Moscow" +RU,57,"Europe/Samara" +RU,58,"Asia/Yekaterinburg" +RU,59,"Asia/Vladivostok" +RU,60,"Europe/Kaliningrad" +RU,61,"Europe/Volgograd" +RU,62,"Europe/Moscow" +RU,63,"Asia/Yakutsk" +RU,64,"Asia/Sakhalin" +RU,65,"Europe/Samara" +RU,66,"Europe/Moscow" +RU,67,"Europe/Samara" +RU,68,"Europe/Volgograd" +RU,69,"Europe/Moscow" +RU,70,"Europe/Volgograd" +RU,71,"Asia/Yekaterinburg" +RU,72,"Europe/Moscow" +RU,73,"Europe/Samara" +RU,74,"Asia/Krasnoyarsk" +RU,75,"Asia/Novosibirsk" +RU,76,"Europe/Moscow" +RU,77,"Europe/Moscow" +RU,78,"Asia/Yekaterinburg" +RU,79,"Asia/Irkutsk" +RU,80,"Asia/Yekaterinburg" +RU,81,"Europe/Samara" +RU,82,"Asia/Irkutsk" +RU,83,"Europe/Moscow" +RU,84,"Europe/Volgograd" +RU,85,"Europe/Moscow" +RU,86,"Europe/Moscow" +RU,87,"Asia/Novosibirsk" +RU,88,"Europe/Moscow" +RU,89,"Asia/Vladivostok" +RU,90,"Asia/Yekaterinburg" +RU,91,"Asia/Krasnoyarsk" +RU,92,"Asia/Anadyr" +RU,93,"Asia/Irkutsk" +RW,,"Africa/Kigali" +SA,,"Asia/Riyadh" +SB,,"Pacific/Guadalcanal" +SC,,"Indian/Mahe" +SD,,"Africa/Khartoum" +SE,,"Europe/Stockholm" +SG,,"Asia/Singapore" +SH,,"Atlantic/St_Helena" +SI,,"Europe/Ljubljana" +SJ,,"Arctic/Longyearbyen" +SK,,"Europe/Bratislava" +SL,,"Africa/Freetown" +SM,,"Europe/San_Marino" +SN,,"Africa/Dakar" +SO,,"Africa/Mogadishu" +SR,,"America/Paramaribo" +SS,,"Africa/Juba" +ST,,"Africa/Sao_Tome" +SV,,"America/El_Salvador" +SX,,"America/Curacao" +SY,,"Asia/Damascus" +SZ,,"Africa/Mbabane" +TC,,"America/Grand_Turk" +TD,,"Africa/Ndjamena" +TF,,"Indian/Kerguelen" +TG,,"Africa/Lome" +TH,,"Asia/Bangkok" +TJ,,"Asia/Dushanbe" +TK,,"Pacific/Fakaofo" +TL,,"Asia/Dili" +TM,,"Asia/Ashgabat" +TN,,"Africa/Tunis" +TO,,"Pacific/Tongatapu" +TR,,"Asia/Istanbul" +TT,,"America/Port_of_Spain" +TV,,"Pacific/Funafuti" +TW,,"Asia/Taipei" +TZ,,"Africa/Dar_es_Salaam" +UA,01,"Europe/Kiev" +UA,02,"Europe/Kiev" +UA,03,"Europe/Uzhgorod" +UA,04,"Europe/Zaporozhye" +UA,05,"Europe/Zaporozhye" +UA,06,"Europe/Uzhgorod" +UA,07,"Europe/Zaporozhye" +UA,08,"Europe/Simferopol" +UA,09,"Europe/Kiev" +UA,10,"Europe/Zaporozhye" +UA,11,"Europe/Simferopol" +UA,12,"Europe/Kiev" +UA,13,"Europe/Kiev" +UA,14,"Europe/Zaporozhye" +UA,15,"Europe/Uzhgorod" +UA,16,"Europe/Zaporozhye" +UA,17,"Europe/Simferopol" +UA,18,"Europe/Zaporozhye" +UA,19,"Europe/Kiev" +UA,20,"Europe/Simferopol" +UA,21,"Europe/Kiev" +UA,22,"Europe/Uzhgorod" +UA,23,"Europe/Kiev" +UA,24,"Europe/Uzhgorod" +UA,25,"Europe/Uzhgorod" +UA,26,"Europe/Zaporozhye" +UA,27,"Europe/Kiev" +UG,,"Africa/Kampala" +UM,,"Pacific/Wake" +US,AK,"America/Anchorage" +US,AL,"America/Chicago" +US,AR,"America/Chicago" +US,AZ,"America/Phoenix" +US,CA,"America/Los_Angeles" +US,CO,"America/Denver" +US,CT,"America/New_York" +US,DC,"America/New_York" +US,DE,"America/New_York" +US,FL,"America/New_York" +US,GA,"America/New_York" +US,HI,"Pacific/Honolulu" +US,IA,"America/Chicago" +US,ID,"America/Denver" +US,IL,"America/Chicago" +US,IN,"America/Indiana/Indianapolis" +US,KS,"America/Chicago" +US,KY,"America/New_York" +US,LA,"America/Chicago" +US,MA,"America/New_York" +US,MD,"America/New_York" +US,ME,"America/New_York" +US,MI,"America/New_York" +US,MN,"America/Chicago" +US,MO,"America/Chicago" +US,MS,"America/Chicago" +US,MT,"America/Denver" +US,NC,"America/New_York" +US,ND,"America/Chicago" +US,NE,"America/Chicago" +US,NH,"America/New_York" +US,NJ,"America/New_York" +US,NM,"America/Denver" +US,NV,"America/Los_Angeles" +US,NY,"America/New_York" +US,OH,"America/New_York" +US,OK,"America/Chicago" +US,OR,"America/Los_Angeles" +US,PA,"America/New_York" +US,RI,"America/New_York" +US,SC,"America/New_York" +US,SD,"America/Chicago" +US,TN,"America/Chicago" +US,TX,"America/Chicago" +US,UT,"America/Denver" +US,VA,"America/New_York" +US,VT,"America/New_York" +US,WA,"America/Los_Angeles" +US,WI,"America/Chicago" +US,WV,"America/New_York" +US,WY,"America/Denver" +UY,,"America/Montevideo" +UZ,01,"Asia/Tashkent" +UZ,02,"Asia/Samarkand" +UZ,03,"Asia/Tashkent" +UZ,05,"Asia/Samarkand" +UZ,06,"Asia/Tashkent" +UZ,07,"Asia/Samarkand" +UZ,08,"Asia/Samarkand" +UZ,09,"Asia/Samarkand" +UZ,10,"Asia/Samarkand" +UZ,12,"Asia/Samarkand" +UZ,13,"Asia/Tashkent" +UZ,14,"Asia/Tashkent" +VA,,"Europe/Vatican" +VC,,"America/St_Vincent" +VE,,"America/Caracas" +VG,,"America/Tortola" +VI,,"America/St_Thomas" +VN,,"Asia/Phnom_Penh" +VU,,"Pacific/Efate" +WF,,"Pacific/Wallis" +WS,,"Pacific/Pago_Pago" +YE,,"Asia/Aden" +YT,,"Indian/Mayotte" +YU,,"Europe/Belgrade" +ZA,,"Africa/Johannesburg" +ZM,,"Africa/Lusaka" +ZW,,"Africa/Harare" |