Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

imported 1.2.5

  • Loading branch information...
commit a61dc5cee6f0be48294541f3a886de91f1b06671 0 parents
@kohsuke authored
21 ASNumLookupTest.java
@@ -0,0 +1,21 @@
+/* OrgLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+/* sample of how to use the GeoIP Java API with GeoIP Organization and ISP databases */
+/* This example can also be used with the GeoIP Domain and ASNum databases */
+/* Usage: java OrgLookupTest 64.4.4.4 */
+
+class ASNumLookupTest {
+ public static void main(String[] args) {
+ try {
+ LookupService asnl = new LookupService("/usr/local/share/GeoIP/GeoIPASNum.dat");
+ System.out.println("ASNum: " + asnl.getOrg(args[0]));
+ asnl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
21 ASNumLookupTestV6.java
@@ -0,0 +1,21 @@
+/* OrgLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+/* sample of how to use the GeoIP Java API with GeoIP Organization and ISP databases */
+/* This example can also be used with the GeoIP Domain and ASNum databases */
+/* Usage: java OrgLookupTest 64.4.4.4 */
+
+class ASNumLookupTestV6 {
+ public static void main(String[] args) {
+ try {
+ LookupService asnl = new LookupService("/usr/local/share/GeoIP/GeoIPASNumv6.dat");
+ System.out.println("ASNum V6: " + asnl.getOrgV6(args[0]));
+ asnl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
79 BenchmarkGeoIP.java
@@ -0,0 +1,79 @@
+import java.io.*;
+import com.maxmind.geoip.*;
+
+class BenchmarkGeoIP {
+
+static void testGeoipCountry(int flags,String msg,int numlookups){
+ try {
+ LookupService cl = new LookupService("/usr/local/share/GeoIP/GeoIP.dat",flags);
+ int i4 = 0;
+ long t1 = System.currentTimeMillis();
+ for (int i2 = 0;i2 < numlookups;i2++){
+ cl.getCountry(ipstring[i4]);
+ i4 = (i4 + 1) % ipstring.length;
+ }
+ long t2 = System.currentTimeMillis();
+ double t3 = ((double) (t2-t1)) / 1000.0;
+ System.out.println(msg);
+ System.out.println(numlookups + " lookups made in " + t3 + " seconds ");
+ } catch (java.io.IOException e) {
+ System.out.println("error");
+ }
+}
+
+static void testGeoipRegion(int flags,String msg,int numlookups){
+ try {
+ LookupService cl = new LookupService("/usr/local/share/GeoIP/GeoIPRegion.dat",flags);
+ int i4 = 0;
+ long t1 = System.currentTimeMillis();
+ for (int i2 = 0;i2 < numlookups;i2++){
+ cl.getRegion(ipstring[i4]);
+ i4 = (i4 + 1) % ipstring.length;
+ }
+ long t2 = System.currentTimeMillis();
+ double t3 = ((double) (t2-t1)) / 1000.0;
+ System.out.println(msg);
+ System.out.println(numlookups + " lookups made in " + t3 + " seconds ");
+ } catch (java.io.IOException e) {
+ System.out.println("error");
+ }
+}
+
+static void testGeoipCity(int flags,String msg,int numlookups){
+ try {
+ LookupService cl = new LookupService("/usr/local/share/GeoIP/GeoIPCity.dat",flags);
+ int i4 = 0;
+ long t1 = System.currentTimeMillis();
+ for (int i2 = 0;i2 < numlookups;i2++){
+ cl.getLocation(ipstring[i4]);
+ i4 = (i4 + 1) % ipstring.length;
+ }
+ long t2 = System.currentTimeMillis();
+ double t3 = ((double) (t2-t1)) / 1000.0;
+ System.out.println(msg);
+ System.out.println(numlookups + " lookups made in " + t3 + " seconds ");
+ } catch (java.io.IOException e) {
+ System.out.println("error");
+ }
+}
+
+ static String ipstring[] = {"24.24.24.24","80.24.24.80","200.24.24.40","68.24.24.46"};
+ public static void main(String args[]){
+ // GEOIP_CHECK_CACHE is not yet supported, so that is why the lines below are commented out!
+
+ testGeoipCountry(LookupService.GEOIP_STANDARD,"GeoIP Country",3000);
+ //testGeoipCountry(LookupService.GEOIP_CHECK_CACHE,"GeoIP Country with GEOIP_CHECK_CACHE",1000);
+ testGeoipCountry(LookupService.GEOIP_MEMORY_CACHE,"GeoIP Country with GEOIP_MEMORY_CACHE",30000);
+ //testGeoipCountry(LookupService.GEOIP_MEMORY_CACHE | LookupService.GEOIP_CHECK_CACHE,"GeoIP Country with GEOIP_MEMORY_CACHE",10000);
+
+ testGeoipRegion(LookupService.GEOIP_STANDARD,"GeoIP Region",3000);
+ //testGeoipRegion(LookupService.GEOIP_CHECK_CACHE,"GeoIP Region with GEOIP_CHECK_CACHE",1000);
+ testGeoipRegion(LookupService.GEOIP_MEMORY_CACHE,"GeoIP Region with GEOIP_MEMORY_CACHE",30000);
+ //testGeoipRegion(LookupService.GEOIP_MEMORY_CACHE | LookupService.GEOIP_CHECK_CACHE,"GeoIP Region with GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE",10000);
+
+ testGeoipCity(LookupService.GEOIP_STANDARD,"GeoIP City",1500);
+ //testGeoipCity(LookupService.GEOIP_INDEX_CACHE,"GeoIP City with GEOIP_INDEX_CACHE",2000);
+ //testGeoipCity(LookupService.GEOIP_INDEX_CACHE | LookupService.GEOIP_CHECK_CACHE,"GeoIP City with GEOIP_INDEX_CACHE and GEOIP_CHECK_CACHE",2000);
+ testGeoipCity(LookupService.GEOIP_MEMORY_CACHE,"GeoIP City with GEOIP_MEMORY_CACHE",15000);
+ }
+}
112 Changes
@@ -0,0 +1,112 @@
+1.2.5 Aug 23th 2011
+ - Fix small buffer issue when java tries to read over the EOF ( Boris Zentner )
+ - Add support for new database types NETSPEED_EDITION_REV1_V6,
+ NETSPEED_EDITION_REV1, ASNUM_EDITION_V6, CITY_EDITION_REV1_V6,
+ ISP_EDITION_V6, ORG_EDITION_V6, DOMAIN_EDITION, DOMAIN_EDITION_V6 ( Boris Zentner )
+ - Add new examples CityLookupTestV6 and ASNumLookupTestV6 ( Boris Zentner )
+1.2.4 Aug 13th 2010
+ - Update FIPS codes 20100810 ( Boris Zentner )
+ - Simplify init code in class LookupServices ( Boris Zentner )
+ - Big timezone update ( Boris Zentner )
+ - Update FIPS codes 20100530 ( Boris Zentner )
+ - Update FIPS codes 20100510 ( Boris Zentner )
+ - Add IPv6 support via getCountryV6 ( Boris Zentner )
+ - Add exmaple for IPv6 lookups: CountryLookupTestV6 ( Boris Zentner )
+ - Fix DatabaseInfo string ( Boris Zentner )
+ - Add netmask and last_netmask methods ( Boris Zentner )
+ - Remove static keyword from objects that are reinitialized in the init() method. ( Tony Jacobs )
+ - Replace nearly all calls to file.read() with file.readFully() ( Tony Jacobs )
+ - Synchronized 100% of the calls to file ( Tony Jacobs )
+ - Use Integer.valueOf() instead of new Integer() to reduce memory consumption. ( Tony Jacobs )
+ - Use explicit imports instead of import java.io.*; and the like. ( Tony Jacobs )
+ - Fix array length in distributed service setup ( quarz12h )
+ - Sync with recent FIPS codes 20090723 ( Boris Zentner )
+1.2.3 May 11th 2009
+ - Sync with recent FIPS codes 20090511 ( Boris Zentner )
+ - Fixed spelling of Kazakhstan, was Kazakstan ( Boris Zentner )
+ - Fix rare out of range error, when the last entry of the Org/ISP/Domain database is copied ( MEMORY_CACHE only ). ( Boris Zentner )
+ - Update timezones for Australia
+ - Remore "\n" from RegionLookupTest.java. println add already a newline ( Boris Zentner )
+ - Change regionName.java and generate_regionName.pl to support FIPS codes with letters ( Boris Zentner ).
+ - Sync with recent FIPS codes Jan 14th, 2009 ( Boris Zentner )
+ - remove dma_code from city records. use metro_code instead. ( Boris Zentner )
+1.2.2 March 22nd 2008
+ - Added BL/Saint Barthelemy, MF/Saint Martin (ISO-3166-1 additions)
+ - Updated timeZone.java ( Boris Zentner )
+ - Add missing \n to admin/generate_timeZone.pl ( Boris Zentner )
+ - Fix refresh databaseInfo in combination with GEOIP_CHECK_CACHE ( Boris Zentner, Glenn Pedersen )
+ - Changed license from GPL to LGPL, to allow commercial programs to include GeoIP API
+
+1.2.1 June 19th 2007
+ - Made GeoIP ASNum database work with Java API
+ - Added timeZone and regionName classes to lookup timezone and region name
+ from country code and region code (Frank Mather)
+
+1.2.0 January 10th 2007
+ - Added support for GEOIP_CHECK_CACHE (Frank Mather)
+ - Allow database to be closed in memory cache mode
+ - 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 support for GEOIP_INDEX_CACHE (Frank Mather)
+ - close filehandle after data is read into memory for MemoryCache mode
+ - Added BenchmarkGeoIP.java (Frank Mather)
+
+1.1.8 August 18th 2006
+ - Increased FULL_RECORD_LENGTH from 50 to 60, fixes Array out ArrayOutOfBounds=50
+ for long city names in GeoIP City databases before July 2006
+ - TP/East Timor changed to TL/Timor-Leste, reflecting changes in ISO-3166
+ - Removed hashmap initialization for local database
+ - Replaced Yugoslavia with Serbia and Montenegro
+
+1.1.7 October 6th 2004
+ - Specified ISO-8859-1 encoding for City, ISP and Organization field string
+ (Yan Zhang Chen)
+
+1.1.6 September 9th 2004
+ - Fixed problem with postalCode, city and region fields
+ returning null char (Frank Mather)
+ - Added support for GeoIP Netspeed Database (Frank Mather)
+ - Added support for GEOIP_MEMORY_CACHE (Frank Mather)
+
+1.1.5 June 3rd 2004
+ - Added support for Maxmind GeoIP Region (Frank Mather)
+ - Windows compatibility fix for CountryLookupTest.java (Hanan Al-Shargi)
+ - Country name fixes
+
+1.1.4 October 21st 2003
+ - Added support for distributed queries (Frank Mather)
+ - Massive code cleanup (Matt Tucker)
+ - Added support for DMA code and Area codes (Frank Mather)
+
+1.1.3 June 9th 2003
+ - Added support for GeoIP Organization and ISP databases
+ - Changed Taiwan, Province of China to Taiwan
+
+1.1.2 December 16th 2002
+ - Added support for postal codes in GeoIP City (beta)
+
+1.1.1 Oct 31st 2002
+ - Added support for GeoIP Full Edition, remaned CountryLookup class
+ to Lookup
+
+1.1.0 Oct 28th 2002
+ - API Change!!! Return null instead of '--' if country can not be found
+ - rewrote seekCountry to use loop instead of recursion for faster performance
+ - Fixed error when looking Anonymous Proxies
+
+1.0.4 Sep 11th 2002
+ - Added close method to clean up filehandles
+ (Jeroen Nijenhuis)
+
+0.3.0 Aug 4th 2002
+ - Added support for satellite providers
+
+0.2.1 July 3rd 2002
+ - Added support for anonymous proxies
+
+0.1.2 Apr 14th 2002
+ - Added public to CountryLookup class (Noel Bergman), should
+ now be accessible outside of GeoIP package.
+
+0.1.1 Apr 9th 2002
+ - Initial Release
36 CityLookupTest.java
@@ -0,0 +1,36 @@
+/* CityLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+/* sample of how to use the GeoIP Java API with GeoIP City database */
+/* Usage: java CityLookupTest 64.4.4.4 */
+
+class CityLookupTest {
+ public static void main(String[] args) {
+ try {
+ LookupService cl = new LookupService("/usr/local/share/GeoIP/GeoIPCity.dat",
+ LookupService.GEOIP_MEMORY_CACHE );
+ Location l1 = cl.getLocation("213.52.50.8");
+ Location l2 = cl.getLocation(args[0]);
+ System.out.println("countryCode: " + l2.countryCode +
+ "\n countryName: " + l2.countryName +
+ "\n region: " + l2.region +
+ "\n regionName: " + regionName.regionNameByCode(l2.countryCode, l2.region) +
+ "\n city: " + l2.city +
+ "\n postalCode: " + l2.postalCode +
+ "\n latitude: " + l2.latitude +
+ "\n longitude: " + l2.longitude +
+ "\n distance: " + l2.distance(l1) +
+ "\n distance: " + l1.distance(l2) +
+ "\n metro code: " + l2.metro_code +
+ "\n area code: " + l2.area_code +
+ "\n timezone: " + timeZone.timeZoneByCountryAndRegion(l2.countryCode, l2.region));
+
+ cl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
36 CityLookupTestV6.java
@@ -0,0 +1,36 @@
+/* CityLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+/* sample of how to use the GeoIP Java API with GeoIP City database */
+/* Usage: java CityLookupTest 64.4.4.4 */
+
+class CityLookupTestV6 {
+ public static void main(String[] args) {
+ try {
+ LookupService cl = new LookupService("/usr/local/share/GeoIP/GeoLiteCityv6.dat",
+ LookupService.GEOIP_MEMORY_CACHE );
+ Location l1 = cl.getLocationV6("::213.52.50.8");
+ Location l2 = cl.getLocationV6(args[0]);
+ System.out.println("countryCode: " + l2.countryCode +
+ "\n countryName: " + l2.countryName +
+ "\n region: " + l2.region +
+ "\n regionName: " + regionName.regionNameByCode(l2.countryCode, l2.region) +
+ "\n city: " + l2.city +
+ "\n postalCode: " + l2.postalCode +
+ "\n latitude: " + l2.latitude +
+ "\n longitude: " + l2.longitude +
+ "\n distance: " + l2.distance(l1) +
+ "\n distance: " + l1.distance(l2) +
+ "\n metro code: " + l2.metro_code +
+ "\n area code: " + l2.area_code +
+ "\n timezone: " + timeZone.timeZoneByCountryAndRegion(l2.countryCode, l2.region));
+
+ cl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
39 CountryLookupTest.java
@@ -0,0 +1,39 @@
+/* CountryLookupTest.java */
+
+/* Only works with GeoIP Country Edition */
+/* For Geoip City Edition, use CityLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+class CountryLookupTest {
+ public static void main(String[] args) {
+ try {
+ String sep = System.getProperty("file.separator");
+
+ // Uncomment for windows
+ // String dir = System.getProperty("user.dir");
+
+ // Uncomment for Linux
+ String dir = "/usr/local/share/GeoIP";
+
+ String dbfile = dir + sep + "GeoIP.dat";
+ // You should only call LookupService once, especially if you use
+ // GEOIP_MEMORY_CACHE mode, since the LookupService constructor takes up
+ // resources to load the GeoIP.dat file into memory
+ //LookupService cl = new LookupService(dbfile,LookupService.GEOIP_STANDARD);
+ LookupService cl = new LookupService(dbfile,LookupService.GEOIP_MEMORY_CACHE);
+
+ System.out.println(cl.getCountry("151.38.39.114").getCode());
+ System.out.println(cl.getCountry("151.38.39.114").getName());
+ System.out.println(cl.getCountry("12.25.205.51").getName());
+ System.out.println(cl.getCountry("64.81.104.131").getName());
+ System.out.println(cl.getCountry("200.21.225.82").getName());
+
+ cl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
38 CountryLookupTestV6.java
@@ -0,0 +1,38 @@
+/* CountryLookupTest.java */
+
+/* Only works with GeoIP Country Edition */
+/* For Geoip City Edition, use CityLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+class CountryLookupTestV6 {
+ public static void main(String[] args) {
+ try {
+ String sep = System.getProperty("file.separator");
+
+ // Uncomment for windows
+ // String dir = System.getProperty("user.dir");
+
+ // Uncomment for Linux
+ String dir = "/usr/local/share/GeoIP";
+
+ String dbfile = dir + sep + "GeoIPv6.dat";
+ // You should only call LookupService once, especially if you use
+ // GEOIP_MEMORY_CACHE mode, since the LookupService constructor takes up
+ // resources to load the GeoIP.dat file into memory
+ //LookupService cl = new LookupService(dbfile,LookupService.GEOIP_STANDARD);
+ LookupService cl = new LookupService(dbfile,LookupService.GEOIP_MEMORY_CACHE);
+
+ System.out.println(cl.getCountryV6("ipv6.google.com").getCode());
+ System.out.println(cl.getCountryV6("::127.0.0.1").getName());
+ System.out.println(cl.getCountryV6("::151.38.39.114").getName());
+ System.out.println(cl.getCountryV6("2001:4860:0:1001::68").getName());
+
+ cl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
27 DistributedServiceTest.java
@@ -0,0 +1,27 @@
+// Usage: CLASSPATH=".:source" java DistributedServiceTest LICENSE_KEY 24.24.24.24
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+class DistributedServiceTest {
+ public static void main(String[] args) {
+ try {
+ // /usr/local/share/GeoIP/GeoIPCity.dat is the location of a backup local copy of the database
+ LookupService cl = new LookupService(0,args[0]);
+ Location l = cl.getLocation(args[1]);
+ System.out.println("countryCode: " + l.countryCode +
+ " countryName: " + l.countryName +
+ " region: " + l.region +
+ " city: " + l.city +
+ " postalCode: " + l.postalCode +
+ " latitude: " + l.latitude +
+ " longitude: " + l.longitude);
+ cl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+
+ }
+}
+
504 LICENSE
@@ -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!
+
+
21 NetSpeedCellLookupTest.java
@@ -0,0 +1,21 @@
+/* OrgLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+/* sample of how to use the GeoIP Java API with GeoIP Organization and ISP databases */
+/* This example can also be used with the GeoIP Domain and ASNum databases */
+/* Usage: java OrgLookupTest 64.4.4.4 */
+
+class NetSpeedCellLookupTest {
+ public static void main(String[] args) {
+ try {
+ LookupService ns = new LookupService("/usr/local/share/GeoIP/GeoIPNetSpeedCell.dat");
+ System.out.println("XX: " + ns.getOrg(args[0]));
+ ns.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
32 NetspeedLookupTest.java
@@ -0,0 +1,32 @@
+/* NetspeedLookup.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+/* sample of how to use the GeoIP Java API with GeoIP Netspeed database */
+/* Usage: java NetspeedLookupTest 24.24.24.24 */
+
+class NetspeedLookupTest {
+ public static void main(String[] args) {
+ try {
+ LookupService cl = new LookupService("/usr/local/share/GeoIP/GeoIPNetspeed.dat");
+ if (args.length > 0) {
+ int speed = cl.getID(args[0]);
+ if (speed == cl.GEOIP_UNKNOWN_SPEED){
+ System.out.println("Unknown");
+ } else if (speed == cl.GEOIP_DIALUP_SPEED) {
+ System.out.println("Dialup");
+ } else if (speed == cl.GEOIP_CABLEDSL_SPEED) {
+ System.out.println("Cable/DSL");
+ } else if (speed == cl.GEOIP_CORPORATE_SPEED) {
+ System.out.println("Corporate");
+ }
+ } else {
+ System.out.println("input a ip address\n");
+ }
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
24 OrgLookupTest.java
@@ -0,0 +1,24 @@
+/* OrgLookupTest.java */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+/* sample of how to use the GeoIP Java API with GeoIP Organization and ISP databases */
+/* This example can also be used with the GeoIP Domain and ASNum databases */
+/* Usage: java OrgLookupTest 64.4.4.4 */
+
+class OrgLookupTest {
+ public static void main(String[] args) {
+ try {
+ LookupService orgl = new LookupService("/usr/local/share/GeoIP/GeoIPOrg.dat");
+ LookupService ispl = new LookupService("/usr/local/share/GeoIP/GeoIPISP.dat");
+ System.out.println("Organization: " + orgl.getOrg(args[0]) +
+ "\tISP: " + ispl.getOrg(args[0]));
+ orgl.close();
+ ispl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
77 README
@@ -0,0 +1,77 @@
+To get started, run
+
+cd source/com/maxmind/geoip/
+javac *.java
+cd -
+CLASSPATH=".:source" javac *.java
+CLASSPATH=".:source" java CountryLookupTest
+
+By default, CountryLookupTest expects to find the
+GeoIP Country database in /usr/local/share/GeoIP/GeoIP.dat
+
+IMPORTANT API Change for 1.1.x users - as of GeoIP 1.1.0 the
+lookupCountryXxxx methods return null if a country can not
+be found (it used to return '--' or 'N/A'. Be sure to check the
+return value for null !
+
+This is version 1.2.3 of the Java interface to GeoIP. For more information
+see http://www.maxmind.com/
+
+As of version 1.1.4 this API is fully thread safe.
+
+To get started for GeoIP Country, look at the code in CountryLookupTest.java.
+
+CityLookupTest.java contains an example for the MaxMind GeoIP City database.
+OrgLookupTest.java contains examples for the GeoIP Organization and ISP databases.
+RegionLookupTest.java contains an example for the MaxMind GeoIP Region database.
+NetspeedLookupTest.java contains an example for the MaxMind GeoIP Netspeed database.
+
+BenchmarkGeoIP.java contains benchmarks for various databases using various options.
+
+Note that CountryLookupTest assumes that you have the GeoIP Country database
+installed at /usr/local/share/GeoIP/GeoIP.dat
+
+A free GeoLite Country database is available from:
+http://www.maxmind.com/app/geoip_country
+
+A free GeoLite City database is available from:
+http://www.maxmind.com/app/geolitecity
+
+MaxMind GeoIP Country offers greater accuracy over the free database.
+MaxMind GeoIP Country, Region, City, ISP, and Organization are available
+for purchase from here:
+http://www.maxmind.com/app/products
+
+Please send any comments to support@maxmind.com
+
+To generate the JAR file, cd to the source directory and run
+
+jar cf maxmindgeoip.jar com/maxmind/geoip/Country.class com/maxmind/geoip/DatabaseInfo.class com/maxmind/geoip/Location.class com/maxmind/geoip/LookupService.class com/maxmind/geoip/Region.class com/maxmind/geoip/regionName.class com/maxmind/geoip/timeZone.class
+
+MEMORY CACHING AND OTHER OPTIONS
+================================
+The following options can be passed as the second parameter to the
+LookupService constructor:
+
+GEOIP_STANDARD - read database from filesystem, uses least memory.
+
+GEOIP_MEMORY_CACHE - load database into memory, faster performance
+ but uses more memory
+
+GEOIP_CHECK_CACHE - check for updated database. If database has been updated,
+ reload filehandle and/or memory cache.
+
+GEOIP_INDEX_CACHE - just cache
+ the most frequently accessed index portion of the database, resulting
+ in faster lookups than GEOIP_STANDARD, but less memory usage than
+ GEOIP_MEMORY_CACHE - useful for larger databases such as
+ GeoIP Organization and GeoIP City. Note, for GeoIP Country, Region
+ and Netspeed databases, GEOIP_INDEX_CACHE is equivalent to GEOIP_MEMORY_CACHE
+
+Note the options can be combined, for example:
+LookupService cl = new LookupService(dbfile, LookupService.GEOIP_MEMORY_CACHE | LookupService.GEOIP_CHECK_CACHE);
+
+Windows Notes
+========================
+If it doesn't work on Windows, try to remove or comment out all the "package com.maxmind.geoip" lines
+from all the files.
23 RegionLookupTest.java
@@ -0,0 +1,23 @@
+/* RegionLookupTest.java */
+
+/* Requires subscription to MaxMind GeoIP Region database */
+
+import com.maxmind.geoip.*;
+import java.io.IOException;
+
+class RegionLookupTest {
+ public static void main(String[] args) {
+ try {
+ LookupService cl = new LookupService("/usr/local/share/GeoIP/GeoIPRegion.dat");
+ Region l = cl.getRegion(args[0]);
+ System.out.println("Country Code: " + l.countryCode);
+ System.out.println("Country Name: " + l.countryName);
+ System.out.println("Region Code: " + l.region);
+ System.out.println("Region Name: " + regionName.regionNameByCode(l.countryCode,l.region));
+ cl.close();
+ }
+ catch (IOException e) {
+ System.out.println("IO Exception");
+ }
+ }
+}
113 admin/generate_regionName.pl
@@ -0,0 +1,113 @@
+#!/usr/bin/perl
+
+# Used to generate regionName.java
+# usage: ./generate_regionName.pl > ../source/com/maxmind/geoip/regionName.java
+
+use strict;
+use warnings;
+
+print <<__JAVA_CODE__;
+package com.maxmind.geoip;
+// generated automatically from admin/generate_regionName.pl
+public class regionName {
+static public String regionNameByCode(String country_code,String region_code) {
+ String name = null;
+ int region_code2 = -1;
+ if (region_code == null) { return null; }
+ if (region_code.equals("")) { return null; }
+
+ if ( ((region_code.charAt(0) >= 48 ) && ( region_code.charAt(0) < ( 48 + 10 )))
+ && ((region_code.charAt(1) >= 48 ) && ( region_code.charAt(1) < ( 48 + 10 )))
+ ){
+ // only numbers, that shorten the large switch statements
+ region_code2 = (region_code.charAt(0)- 48) * 10 + region_code.charAt(1) - 48;
+ }
+ else if ( ( ((region_code.charAt(0) >= 65) && (region_code.charAt(0) < (65 + 26)))
+ || ((region_code.charAt(0) >= 48) && (region_code.charAt(0) < (48 + 10))))
+ && ( ((region_code.charAt(1) >= 65) && (region_code.charAt(1) < (65 + 26)))
+ || ((region_code.charAt(1) >= 48) && (region_code.charAt(1) < (48 + 10))))
+ ) {
+
+ region_code2 = (region_code.charAt(0) - 48) * (65 + 26 - 48) + region_code.charAt(1) - 48 + 100;
+ }
+
+ if (region_code2 == -1) {return null;}
+__JAVA_CODE__
+
+# iso3166_2.txt extracted from http://www.maxmind.com/app/iso3166_2
+open( FILE, "iso3166_2.txt" ) or die $!;
+<FILE>;
+my $last_country_code = "";
+while ( my $str = <FILE> ) {
+ chomp($str);
+ my ( $country_code, $region_code, $name ) = split( ",", $str );
+ $region_code =~ /^[A-Z]{2}$/ or die "Wrong region code";
+ my $region_code2 =
+ ( ( ord( substr( $region_code, 0, 1 ) ) - 48 ) * ( 65 + 26 - 48 ) ) +
+ ord( substr( $region_code, 1, 1 ) ) - 48 + 100;
+ readcode( $last_country_code, $country_code, $region_code, $region_code2,
+ $name );
+ $last_country_code = $country_code;
+}
+close(FILE);
+print " }\n";
+print " }\n";
+
+# fips10_4.txt extracted from http://www.maxmind.com/app/fips10_4
+open( FILE, "fips10_4.txt" ) or die $!;
+<FILE>;
+$last_country_code = "";
+while ( my $str = <FILE> ) {
+ chomp($str);
+ my ( $country_code, $region_code, $name ) = split( ",", $str );
+ next if ( $country_code eq "US" );
+ next if ( $country_code eq "CA" );
+ my $region_code2;
+ 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";
+ }
+ readcode( $last_country_code, $country_code, $region_code, $region_code2,
+ $name );
+ $last_country_code = $country_code;
+}
+print " }\n";
+print " }\n";
+print " return name;\n";
+print " }\n";
+print "}\n";
+
+close(FILE);
+
+sub readcode {
+ my ( $last_country_code, $country_code, $region_code, $region_code2, $name ) =
+ @_;
+ if ( $country_code ne $last_country_code ) {
+ if ( $last_country_code ne "" ) {
+ print " }\n";
+ print " }\n";
+ }
+ print " if (country_code.equals(" . qq(")
+ . $country_code . qq(")
+ . ") == true) {\n";
+ print " switch (region_code2) {\n";
+ }
+
+ # $name =~ s!\s+!!g;
+ $name =~ s!\"!!g;
+ $name = qq(") . $name . qq(");
+ print " case " . $region_code2 . ":\n";
+ print " name = " . $name . ";\n";
+ print " break;\n";
+}
+
65 admin/generate_timeZone.pl
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+
+use strict;
+
+# Used to generate timeZone.java
+# usage: ./generate_timeZone.pl > ../source/com/maxmind/geoip/timeZone.java
+
+my $old_country;
+my $old_region;
+my $had_region;
+
+# Obtain timezone.txt from http://www.maxmind.com/timezone.txt
+open(FILE,"timezone.txt");
+my $str = <FILE>;
+
+print "package com.maxmind.geoip;\n";
+print "// generated automatically from admin/generate_timeZone.pl\n";
+print "public class timeZone {\n";
+print " static public String timeZoneByCountryAndRegion(String country,String region) {\n";
+print " String timezone = null;\n";
+print <<END;
+ if (country == null) {
+ return null;
+ }
+ if (region == null) {
+ region = "";
+ }
+END
+
+while ($str = <FILE>) {
+ $str =~ s!\s*$!!;
+ my ($country,$region,$timezone) = split("\t",$str);
+ if ($country ne $old_country) {
+ if ($had_region) {
+ print " }\n";
+ $had_region = "";
+ $old_region = "";
+ }
+ if ($old_country ne "") {
+ print " } else if (country.equals(" . qq(") . $country . qq(") . ") == true) {\n";
+ } else {
+ print " if (country.equals(" . qq(") . $country . qq(") . ") == true) {\n";
+ }
+ }
+ if ($region ne "") {
+ $had_region = 1;
+ if ($old_region ne "") {
+ print " } else if (region.equals(" . qq(") . $region . qq(") . ") == true) {\n ";
+ } else {
+ print " if (region.equals(" . qq(") . $region . qq(") . ") == true) {\n ";
+ }
+ } elsif ($old_region ne "") {
+ print " } else {\n ";
+ }
+ print qq( timezone = ") . $timezone . qq(") . ";\n";
+ $old_country = $country;
+ $old_region = $region;
+}
+print " }\n";
+print " return timezone;\n";
+print " }\n";
+print "}\n";
+
+close(FILE);
+
110 admin/new_generate_TimeZone.pl
@@ -0,0 +1,110 @@
+#!/usr/bin/perl
+use Data::Dumper;
+use strict;
+use warnings;
+
+# Used to generate timeZone.java
+# usage: ./generate_timeZone.pl > ../source/com/maxmind/geoip/timeZone.java
+
+my $old_country;
+my $old_region;
+my $had_region;
+
+# Obtain timezone.txt from http://www.maxmind.com/timezone.txt
+open(FILE,"timezone.txt") or die $!;
+my $str = <FILE>;
+my @time_zones = map { [ split /\t/, $_, 3 ] } <FILE>;
+#print Dumper(\@time_zones);
+#exit;
+my $cnt_time_zones = @time_zones;
+print <<__HEADER__;
+package com.maxmind.geoip;
+
+import java.util.HashMap;
+import java.util.TimeZone;
+
+// generated automatically from admin/generate_timeZone.pl
+public class GeoIPTimeZone {
+ private static final HashMap<String, TimeZone>TIME_ZONES = new HashMap<String, TimeZone>($cnt_time_zones);
+ static {
+__HEADER__
+
+for ( @time_zones ) {
+ my ( $c, $r, $tz ) = @$_;
+ chomp $tz;
+ my $k = $c . $r || '';
+ print qq[ TIME_ZONES.put("$k", TimeZone.getTimeZone("$tz"));\n];
+}
+print qq[ };\n];
+
+print <<__FOOTER__;
+ static public TimeZone getTimeZone(String country, String region) {
+
+ TimeZone tz;
+
+ if ( country.length() != 2 ) {
+ return null;
+ }
+
+ if ( region.length() == 2 ) {
+ tz = TIME_ZONES.get(country + region);
+ if ( tz != null ) {
+ return tz;
+ }
+ }
+ return TIME_ZONES.get(country) ;
+ }
+
+ static public String timeZoneByCountryAndRegion(String country,String region) {
+ return getTimeZone( country, region ).getID() ;
+ }
+};
+__FOOTER__
+
+__END__
+print " String timezone = null;\n";
+print <<END;
+ if (country == null) {
+ return null;
+ }
+ if (region == null) {
+ region = "";
+ }
+END
+
+while ($str = <FILE>) {
+ $str =~ s!\s*$!!;
+ my ($country,$region,$timezone) = split(/\t/,$str);
+ if ($country ne $old_country) {
+ if ($had_region) {
+ print " }\n";
+ $had_region = "";
+ $old_region = "";
+ }
+ if ($old_country ne "") {
+ print " } else if (country.equals(" . qq(") . $country . qq(") . ") == true) {\n";
+ } else {
+ print " if (country.equals(" . qq(") . $country . qq(") . ") == true) {\n";
+ }
+ }
+ if ($region ne "") {
+ $had_region = 1;
+ if ($old_region ne "") {
+ print " } else if (region.equals(" . qq(") . $region . qq(") . ") == true) {\n ";
+ } else {
+ print " if (region.equals(" . qq(") . $region . qq(") . ") == true) {\n ";
+ }
+ } elsif ($old_region ne "") {
+ print " } else {\n ";
+ }
+ print qq( timezone = ") . $timezone . qq(") . ";\n";
+ $old_country = $country;
+ $old_region = $region;
+}
+print " }\n";
+print " return timezone;\n";
+print " }\n";
+print "}\n";
+
+close(FILE);
+
61 source/com/maxmind/geoip/Country.java
@@ -0,0 +1,61 @@
+/**
+ * Country.java
+ *
+ * Copyright (C) 2003 MaxMind LLC. All Rights Reserved.
+ *
+ * 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 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.maxmind.geoip;
+
+/**
+ * Represents a country.
+ *
+ * @author Matt Tucker
+ */
+public class Country {
+
+ private String code;
+ private String name;
+
+ /**
+ * Creates a new Country.
+ *
+ * @param code the country code.
+ * @param name the country name.
+ */
+ public Country(String code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ /**
+ * Returns the ISO two-letter country code of this country.
+ *
+ * @return the country code.
+ */
+ public String getCode() {
+ return code;
+ }
+
+ /**
+ * Returns the name of this country.
+ *
+ * @return the country name.
+ */
+ public String getName() {
+ return name;
+ }
+}
127 source/com/maxmind/geoip/DatabaseInfo.java
@@ -0,0 +1,127 @@
+/**
+ * DatabaseInfo.java
+ *
+ * Copyright (C) 2003 MaxMind LLC. All Rights Reserved.
+ *
+ * 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 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.maxmind.geoip;
+
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+
+/**
+ * Encapsulates metadata about the GeoIP database. The database has a date, is a premium or
+ * standard version, and is one of the following types:
+ *
+ * <ul>
+ * <li>Country edition -- this is the most common version of the database. It includes
+ * the name of the country and it's ISO country code given an IP address.
+ * <li>Region edition -- includes the country information as well as
+ * what U.S. state or Canadian province the IP address is from if the IP address
+ * is from the U.S. or Canada.
+ * <li>City edition -- includes country, region, city, postal code, latitude, and
+ * longitude information.
+ * <li>Org edition -- includes netblock owner.
+ * <li>ISP edition -- ISP information.
+ * </ul>
+ *
+ * @see com.maxmind.geoip.LookupService#getDatabaseInfo()
+ * @author Matt Tucker
+ */
+public class DatabaseInfo {
+
+ public final static int COUNTRY_EDITION = 1;
+ public final static int REGION_EDITION_REV0 = 7;
+ public final static int REGION_EDITION_REV1 = 3;
+ public final static int CITY_EDITION_REV0 = 6;
+ public final static int CITY_EDITION_REV1 = 2;
+ public final static int ORG_EDITION = 5;
+ public final static int ISP_EDITION = 4;
+ public final static int PROXY_EDITION = 8;
+ public final static int ASNUM_EDITION = 9;
+ public final static int NETSPEED_EDITION = 10;
+ public final static int DOMAIN_EDITION = 11;
+ public final static int COUNTRY_EDITION_V6 = 12;
+ public final static int ASNUM_EDITION_V6 = 21;
+ public final static int ISP_EDITION_V6 = 22;
+ public final static int ORG_EDITION_V6 = 23;
+ public final static int DOMAIN_EDITION_V6 = 24;
+ public final static int CITY_EDITION_REV1_V6 = 30;
+ public final static int CITY_EDITION_REV0_V6 = 31;
+ public final static int NETSPEED_EDITION_REV1 = 32;
+ public final static int NETSPEED_EDITION_REV1_V6 = 33;
+
+
+private static SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
+
+ private String info;
+
+ /**
+ * Creates a new DatabaseInfo object given the database info String.
+ * @param info
+ */
+ public DatabaseInfo(String info) {
+ this.info = info;
+ }
+
+ public int getType() {
+ if (info == null || info.equals("")) {
+ return COUNTRY_EDITION;
+ }
+ else {
+ // Get the type code from the database info string and then
+ // subtract 105 from the value to preserve compatability with
+ // databases from April 2003 and earlier.
+ return Integer.parseInt(info.substring(4, 7)) - 105;
+ }
+ }
+
+ /**
+ * Returns true if the database is the premium version.
+ *
+ * @return true if the premium version of the database.
+ */
+ public boolean isPremium() {
+ return info.indexOf("FREE") < 0;
+ }
+
+ /**
+ * Returns the date of the database.
+ *
+ * @return the date of the database.
+ */
+ public Date getDate() {
+ for (int i=0; i<info.length()-9; i++) {
+ if (Character.isWhitespace(info.charAt(i))) {
+ String dateString = info.substring(i+1, i+9);
+ try {
+ synchronized (formatter) {
+ return formatter.parse(dateString);
+ }
+ }
+ catch (ParseException pe) { }
+ break;
+ }
+ }
+ return null;
+ }
+
+ public String toString() {
+ return info;
+ }
+}
60 source/com/maxmind/geoip/Location.java
@@ -0,0 +1,60 @@
+/**
+ * Location.java
+ *
+ * Copyright (C) 2004 MaxMind LLC. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.maxmind.geoip;
+
+public class Location {
+ public String countryCode;
+ public String countryName;
+ public String region;
+ public String city;
+ public String postalCode;
+ public float latitude;
+ public float longitude;
+ public int dma_code;
+ public int area_code;
+ public int metro_code;
+
+ private final static double EARTH_DIAMETER = 2 * 6378.2;
+ private final static double PI = 3.14159265;
+ private final static double RAD_CONVERT = PI / 180;
+
+ public double distance (Location loc) {
+ double delta_lat, delta_lon;
+ double temp;
+
+ float lat1 = latitude;
+ float lon1 = longitude;
+ float lat2 = loc.latitude;
+ float lon2 = loc.longitude;
+
+ // convert degrees to radians
+ lat1 *= RAD_CONVERT;
+ lat2 *= RAD_CONVERT;
+
+ // find the deltas
+ delta_lat = lat2 - lat1;
+ delta_lon = (lon2 - lon1) * RAD_CONVERT;
+
+ // Find the great circle distance
+ temp = Math.pow(Math.sin(delta_lat/2),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(delta_lon/2),2);
+ return EARTH_DIAMETER * Math.atan2(Math.sqrt(temp),Math.sqrt(1-temp));
+ }
+}
1,222 source/com/maxmind/geoip/LookupService.java
@@ -0,0 +1,1222 @@
+/**
+ * LookupService.java
+ *
+ * Copyright (C) 2003 MaxMind LLC. All Rights Reserved.
+ *
+ * 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 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.maxmind.geoip;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+
+/**
+ * Provides a lookup service for information based on an IP address. The location of
+ * a database file is supplied when creating a lookup service instance. The edition of
+ * the database determines what information is available about an IP address. See the
+ * DatabaseInfo class for further details.<p>
+ *
+ * The following code snippet demonstrates looking up the country that an IP
+ * address is from:
+ * <pre>
+ * // First, create a LookupService instance with the location of the database.
+ * LookupService lookupService = new LookupService("c:\\geoip.dat");
+ * // Assume we have a String ipAddress (in dot-decimal form).
+ * Country country = lookupService.getCountry(ipAddress);
+ * System.out.println("The country is: " + country.getName());
+ * System.out.println("The country code is: " + country.getCode());
+ * </pre>
+ *
+ * In general, a single LookupService instance should be created and then reused
+ * repeatedly.<p>
+ *
+ * <i>Tip:</i> Those deploying the GeoIP API as part of a web application may find it
+ * difficult to pass in a File to create the lookup service, as the location of the
+ * database may vary per deployment or may even be part of the web-application. In this
+ * case, the database should be added to the classpath of the web-app. For example, by
+ * putting it into the WEB-INF/classes directory of the web application. The following code
+ * snippet demonstrates how to create a LookupService using a database that can be found
+ * on the classpath:
+ *
+ * <pre>
+ * String fileName = getClass().getResource("/GeoIP.dat").toExternalForm().substring(6);
+ * LookupService lookupService = new LookupService(fileName);</pre>
+ *
+ * @author Matt Tucker (matt@jivesoftware.com)
+ */
+public class LookupService {
+
+ /**
+ * Database file.
+ */
+ private RandomAccessFile file = null;
+ private File databaseFile = null;
+
+ /**
+ * Information about the database.
+ */
+ private DatabaseInfo databaseInfo = null;
+
+ /**
+ * The database type. Default is the country edition.
+ */
+ byte databaseType = DatabaseInfo.COUNTRY_EDITION;
+
+ int databaseSegments[];
+ int recordLength;
+
+ String licenseKey;
+ int dnsService = 0;
+ int dboptions;
+ byte dbbuffer[];
+ byte index_cache[];
+ long mtime;
+ int last_netmask;
+ private final static int US_OFFSET = 1;
+ private final static int CANADA_OFFSET = 677;
+ private final static int WORLD_OFFSET = 1353;
+ private final static int FIPS_RANGE = 360;
+ private final static int COUNTRY_BEGIN = 16776960;
+ private final static int STATE_BEGIN_REV0 = 16700000;
+ private final static int STATE_BEGIN_REV1 = 16000000;
+ private final static int STRUCTURE_INFO_MAX_SIZE = 20;
+ private final static int DATABASE_INFO_MAX_SIZE = 100;
+ public final static int GEOIP_STANDARD = 0;
+ public final static int GEOIP_MEMORY_CACHE = 1;
+ public final static int GEOIP_CHECK_CACHE = 2;
+ public final static int GEOIP_INDEX_CACHE = 4;
+ public final static int GEOIP_UNKNOWN_SPEED = 0;
+ public final static int GEOIP_DIALUP_SPEED = 1;
+ public final static int GEOIP_CABLEDSL_SPEED = 2;
+ public final static int GEOIP_CORPORATE_SPEED = 3;
+
+
+ private final static int SEGMENT_RECORD_LENGTH = 3;
+ private final static int STANDARD_RECORD_LENGTH = 3;
+ private final static int ORG_RECORD_LENGTH = 4;
+ private final static int MAX_RECORD_LENGTH = 4;
+
+ private final static int MAX_ORG_RECORD_LENGTH = 300;
+ private final static int FULL_RECORD_LENGTH = 60;
+
+ private final Country UNKNOWN_COUNTRY = new Country("--", "N/A");
+
+ private static final HashMap hashmapcountryCodetoindex = new HashMap(512);
+ private static final HashMap hashmapcountryNametoindex = new HashMap(512);
+ private static final String[] countryCode = {
+ "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN","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","FX","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"};
+
+ private static final String[] countryName = {
+ "N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates",
+ "Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia",
+ "Netherlands Antilles","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","France, Metropolitan","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","Libyan Arab Jamahiriya","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"};
+
+
+ /* init the hashmap once at startup time */
+ static {
+ int i;
+ if(countryCode.length!=countryName.length)
+ throw new AssertionError("countryCode.length!=countryName.length");
+
+ // distributed service only
+ for (i = 0; i < countryCode.length ;i++){
+ hashmapcountryCodetoindex.put(countryCode[i],Integer.valueOf(i));
+ hashmapcountryNametoindex.put(countryName[i],Integer.valueOf(i));
+ }
+ };
+
+
+ /**
+ * Create a new distributed lookup service using the license key
+ *
+ * @param databaseFile String representation of the database file.
+ * @param licenseKey license key provided by Maxmind to access distributed service
+ */
+ public LookupService(String databaseFile,String licenseKey) throws IOException {
+ this(new File(databaseFile));
+ this.licenseKey = licenseKey;
+ dnsService = 1;
+ }
+ /**
+ * Create a new distributed lookup service using the license key
+ *
+ * @param databaseFile the database file.
+ * @param licenseKey license key provided by Maxmind to access distributed service
+ */
+ public LookupService(File databaseFile,String licenseKey) throws IOException {
+ this(databaseFile);
+ this.licenseKey = licenseKey;
+ dnsService = 1;
+ }
+ /**
+ * Create a new distributed lookup service using the license key
+ *
+ * @param options Resevered for future use
+ * @param licenseKey license key provided by Maxmind to access distributed service
+ */
+ public LookupService(int options,String licenseKey) throws IOException {
+ this.licenseKey = licenseKey;
+ dnsService = 1;
+ init();
+ }
+ /**
+ * Create a new lookup service using the specified database file.
+ *
+ * @param databaseFile String representation of the database file.
+ * @throws java.io.IOException if an error occured creating the lookup service
+ * from the database file.
+ */
+ public LookupService(String databaseFile) throws IOException {
+ this(new File(databaseFile));
+ }
+
+ /**
+ * Create a new lookup service using the specified database file.
+ *
+ * @param databaseFile the database file.
+ * @throws java.io.IOException if an error occured creating the lookup service
+ * from the database file.
+ */
+ public LookupService(File databaseFile) throws IOException {
+ this.databaseFile = databaseFile;
+ this.file = new RandomAccessFile(databaseFile, "r");
+ init();
+ }
+
+ /**
+ * Create a new lookup service using the specified database file.
+ *
+ * @param databaseFile String representation of the database file.
+ * @param options database flags to use when opening the database
+ * GEOIP_STANDARD read database from disk
+ * GEOIP_MEMORY_CACHE cache the database in RAM and read it from RAM
+ * @throws java.io.IOException if an error occured creating the lookup service
+ * from the database file.
+ */
+ public LookupService(String databaseFile, int options) throws IOException{
+ this(new File(databaseFile),options);
+ }
+
+ /**
+ * Create a new lookup service using the specified database file.
+ *
+ * @param databaseFile the database file.
+ * @param options database flags to use when opening the database
+ * GEOIP_STANDARD read database from disk
+ * GEOIP_MEMORY_CACHE cache the database in RAM and read it from RAM
+ * @throws java.io.IOException if an error occured creating the lookup service
+ * from the database file.
+ */
+ public LookupService(File databaseFile, int options) throws IOException{
+ this.databaseFile = databaseFile;
+ this.file = new RandomAccessFile(databaseFile, "r");
+ dboptions = options;
+ init();
+ }
+ /**
+ * Reads meta-data from the database file.
+ *
+ * @throws java.io.IOException if an error occurs reading from the database file.
+ */
+ private void init() throws IOException {
+ int i, j;
+ byte [] delim = new byte[3];
+ byte [] buf = new byte[SEGMENT_RECORD_LENGTH];
+
+ if (file == null) {
+ return;
+ }
+ if ((dboptions & GEOIP_CHECK_CACHE) != 0) {
+ mtime = databaseFile.lastModified();
+ }
+ file.seek(file.length() - 3);
+ for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
+ file.readFully(delim);
+ if (delim[0] == -1 && delim[1] == -1 && delim[2] == -1) {
+ databaseType = file.readByte();
+ if (databaseType >= 106) {
+ // Backward compatibility with databases from April 2003 and earlier
+ databaseType -= 105;
+ }
+ // Determine the database type.
+ if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
+ databaseSegments = new int[1];
+ databaseSegments[0] = STATE_BEGIN_REV0;
+ recordLength = STANDARD_RECORD_LENGTH;
+ }else if (databaseType == DatabaseInfo.REGION_EDITION_REV1){
+ databaseSegments = new int[1];
+ databaseSegments[0] = STATE_BEGIN_REV1;
+ recordLength = STANDARD_RECORD_LENGTH;
+ }
+ else if (databaseType == DatabaseInfo.CITY_EDITION_REV0 ||
+ databaseType == DatabaseInfo.CITY_EDITION_REV1 ||
+ databaseType == DatabaseInfo.ORG_EDITION ||
+ databaseType == DatabaseInfo.ORG_EDITION_V6 ||
+ databaseType == DatabaseInfo.ISP_EDITION ||
+ databaseType == DatabaseInfo.ISP_EDITION_V6 ||
+ databaseType == DatabaseInfo.DOMAIN_EDITION ||
+ databaseType == DatabaseInfo.DOMAIN_EDITION_V6 ||
+ databaseType == DatabaseInfo.ASNUM_EDITION ||
+ databaseType == DatabaseInfo.ASNUM_EDITION_V6 ||
+ databaseType == DatabaseInfo.NETSPEED_EDITION_REV1 ||
+ databaseType == DatabaseInfo.NETSPEED_EDITION_REV1_V6 ||
+ databaseType == DatabaseInfo.CITY_EDITION_REV0_V6 ||
+ databaseType == DatabaseInfo.CITY_EDITION_REV1_V6
+ ) {
+ databaseSegments = new int[1];
+ databaseSegments[0] = 0;
+ if (databaseType == DatabaseInfo.CITY_EDITION_REV0 ||
+ databaseType == DatabaseInfo.CITY_EDITION_REV1 ||
+ databaseType == DatabaseInfo.ASNUM_EDITION_V6 ||
+ databaseType == DatabaseInfo.NETSPEED_EDITION_REV1 ||
+ databaseType == DatabaseInfo.NETSPEED_EDITION_REV1_V6 ||
+ databaseType == DatabaseInfo.CITY_EDITION_REV0_V6 ||
+ databaseType == DatabaseInfo.CITY_EDITION_REV1_V6 ||
+ databaseType == DatabaseInfo.ASNUM_EDITION) {
+ recordLength = STANDARD_RECORD_LENGTH;
+ }
+ else {
+ recordLength = ORG_RECORD_LENGTH;
+ }
+ file.readFully(buf);
+ for (j = 0; j < SEGMENT_RECORD_LENGTH; j++) {
+ databaseSegments[0] += (unsignedByteToInt(buf[j]) << (j * 8));
+ }
+ }
+ break;
+ }
+ else {
+ file.seek(file.getFilePointer() - 4);
+ }
+ }
+ if ((databaseType == DatabaseInfo.COUNTRY_EDITION) ||
+ (databaseType == DatabaseInfo.COUNTRY_EDITION_V6) ||
+ (databaseType == DatabaseInfo.PROXY_EDITION) ||
+ (databaseType == DatabaseInfo.NETSPEED_EDITION)) {
+ databaseSegments = new int[1];
+ databaseSegments[0] = COUNTRY_BEGIN;
+ recordLength = STANDARD_RECORD_LENGTH;
+ }
+ if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
+ int l = (int) file.length();
+ dbbuffer = new byte[l];
+ file.seek(0);
+ file.readFully(dbbuffer,0,l);
+ databaseInfo = this.getDatabaseInfo();
+ file.close();
+ }
+ if ((dboptions & GEOIP_INDEX_CACHE) != 0) {
+ int l = databaseSegments[0] * recordLength * 2;
+ index_cache = new byte[l];
+ if (index_cache != null){
+ file.seek(0);
+ file.readFully(index_cache,0,l);
+ }
+ } else {
+ index_cache = null;
+ }
+
+ }
+
+ /**
+ * Closes the lookup service.
+ */
+ public void close() {
+ try {
+ if (file != null){
+ file.close();
+ }
+ file = null;
+ }
+ catch (Exception e) { }
+ }
+
+ /**
+ * Returns the country the IP address is in.
+ *
+ * @param ipAddress String version of an IPv6 address, i.e. "::127.0.0.1"
+ * @return the country the IP address is from.
+ */
+ public Country getCountryV6(String ipAddress) {
+ InetAddress addr;
+ try {
+ addr = Inet6Address.getByName(ipAddress);
+ }
+ catch (UnknownHostException e) {
+ return UNKNOWN_COUNTRY;
+ }
+ return getCountryV6(addr);
+ }
+
+ /**
+ * Returns the country the IP address is in.
+ *
+ * @param ipAddress String version of an IP address, i.e. "127.0.0.1"
+ * @return the country the IP address is from.
+ */
+ public Country getCountry(String ipAddress) {
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(ipAddress);
+ }
+ catch (UnknownHostException e) {
+ return UNKNOWN_COUNTRY;
+ }
+ return getCountry(bytesToLong(addr.getAddress()));
+ }
+
+ /**
+ * Returns the country the IP address is in.
+ *
+ * @param ipAddress the IP address.
+ * @return the country the IP address is from.
+ */
+ public synchronized Country getCountry(InetAddress ipAddress) {
+ return getCountry(bytesToLong(ipAddress.getAddress()));
+ }
+
+ /**
+ * Returns the country the IP address is in.
+ *
+ * @param addr the IP address as Inet6Address.
+ * @return the country the IP address is from.
+ */
+ public Country getCountryV6(InetAddress addr) {
+ if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
+ throw new IllegalStateException("Database has been closed.");
+ }
+ int ret = seekCountryV6(addr) - COUNTRY_BEGIN;
+ if (ret == 0) {
+ return UNKNOWN_COUNTRY;
+ }
+ else {
+ return new Country(countryCode[ret], countryName[ret]);
+ }
+ }
+
+ /**
+ * Returns the country the IP address is in.
+ *
+ * @param ipAddress the IP address in long format.
+ * @return the country the IP address is from.
+ */
+ public Country getCountry(long ipAddress) {
+ if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
+ throw new IllegalStateException("Database has been closed.");
+ }
+ int ret = seekCountry(ipAddress) - COUNTRY_BEGIN;
+ if (ret == 0) {
+ return UNKNOWN_COUNTRY;
+ }
+ else {
+ return new Country(countryCode[ret], countryName[ret]);
+ }
+ }
+
+ public int getID(String ipAddress) {
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(ipAddress);
+ }
+ catch (UnknownHostException e) {
+ return 0;
+ }
+ return getID(bytesToLong(addr.getAddress()));
+ }
+
+ public int getID(InetAddress ipAddress) {
+ return getID(bytesToLong(ipAddress.getAddress()));
+ }
+
+ public synchronized int getID(long ipAddress) {
+ if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
+ throw new IllegalStateException("Database has been closed.");
+ }
+ int ret = seekCountry(ipAddress) - databaseSegments[0];
+ return ret;
+ }
+
+ public int last_netmask() {
+ return this.last_netmask;
+ }
+
+ public void netmask(int nm){
+ this.last_netmask = nm;
+ }
+
+ /**
+ * Returns information about the database.
+ *
+ * @return database info.
+ */
+ public synchronized DatabaseInfo getDatabaseInfo() {
+ if (databaseInfo != null) {
+ return databaseInfo;
+ }
+ try {
+ _check_mtime();
+ boolean hasStructureInfo = false;
+ byte [] delim = new byte[3];
+ // Advance to part of file where database info is stored.
+ file.seek(file.length() - 3);
+ for (int i=0; i<STRUCTURE_INFO_MAX_SIZE; i++) {
+ int read = file.read( delim );
+ if( read==3 && (delim[0]&0xFF)==255 && (delim[1]&0xFF) == 255 && (delim[2]&0xFF)==255 ){
+ hasStructureInfo = true;
+ break;
+ }
+ file.seek(file.getFilePointer() - 4);
+
+ }
+ if (hasStructureInfo) {
+ file.seek(file.getFilePointer() - 6);
+ }
+ else {
+ // No structure info, must be pre Sep 2002 database, go back to end.
+ file.seek(file.length() - 3);
+ }
+ // Find the database info string.
+ for (int i=0; i<DATABASE_INFO_MAX_SIZE; i++) {
+ file.readFully(delim);
+ if (delim[0]==0 && delim[1]==0 && delim[2]==0) {
+ byte[] dbInfo = new byte[i];
+ file.readFully(dbInfo);
+ // Create the database info object using the string.
+ this.databaseInfo = new DatabaseInfo(new String(dbInfo));
+ return databaseInfo;
+ }
+ file.seek(file.getFilePointer() -4);
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return new DatabaseInfo("");
+ }
+
+ synchronized void _check_mtime(){
+ try {
+ if ((dboptions & GEOIP_CHECK_CACHE) != 0){
+ long t = databaseFile.lastModified();
+ if (t != mtime){
+ /* GeoIP Database file updated */
+ /* refresh filehandle */
+ file.close();
+ file = new RandomAccessFile(databaseFile,"r");
+ databaseInfo = null;
+ init();
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("file not found");
+ }
+ }
+
+ // for GeoIP City only
+ public Location getLocationV6(String str) {
+ if (dnsService == 0) {
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(str);
+ }
+ catch (UnknownHostException e) {
+ return null;
+ }
+
+ return getLocationV6(addr);
+ } else {
+ String str2 = getDnsAttributes(str);
+ return getLocationwithdnsservice(str2);
+ // TODO if DNS is not available, go to local file as backup
+ }
+ }
+
+ // for GeoIP City only
+ public Location getLocation(InetAddress addr) {
+ return getLocation(bytesToLong(addr.getAddress()));
+ }
+
+ // for GeoIP City only
+ public Location getLocation(String str) {
+ if (dnsService == 0) {
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(str);
+ }
+ catch (UnknownHostException e) {
+ return null;
+ }
+
+ return getLocation(addr);
+ } else {
+ String str2 = getDnsAttributes(str);
+ return getLocationwithdnsservice(str2);
+ // TODO if DNS is not available, go to local file as backup
+ }
+ }
+
+ String getDnsAttributes(String ip) {
+ try {
+ Hashtable env = new Hashtable();
+ env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
+ // TODO don't specify ws1, instead use ns servers for s.maxmind.com
+ env.put("java.naming.provider.url","dns://ws1.maxmind.com/");
+
+ DirContext ictx = new InitialDirContext(env);
+ Attributes attrs = ictx.getAttributes(licenseKey + "." + ip + ".s.maxmind.com", new String[] {"txt"});
+ //System.out.println(attrs.get("txt").get());
+ String str = attrs.get("txt").get().toString();
+ return str;
+ }
+ catch(NamingException e) {
+ // TODO fix this to handle exceptions
+ System.out.println("DNS error");
+ return null;
+ }
+
+ }
+
+ public Location getLocationwithdnsservice(String str) {
+ Location record = new Location();
+ String key;
+ String value;
+ StringTokenizer st = new StringTokenizer(str,";=\"");
+ while (st.hasMoreTokens()) {
+ key = st.nextToken();
+ if (st.hasMoreTokens()) {
+ value = st.nextToken();
+ } else {
+ value = "";}
+ if (key.equals("co")) {
+ Integer i = (Integer)hashmapcountryCodetoindex.get(value);
+ record.countryCode = value;
+ record.countryName = countryName[i.intValue()];
+ }
+ if (key.equals("ci")) {
+ record.city = value;
+ }
+ if (key.equals("re")) {
+ record.region = value;
+ }
+ if (key.equals("zi")) {
+ record.postalCode = value;
+ }
+ // TODO, ISP and Organization
+ //if (key.equals("or")) {
+ //record.org = value;
+ //}
+ //if (key.equals("is")) {
+ //record.isp = value;
+ //}
+ if (key.equals("la")) {
+ try{
+ record.latitude = Float.parseFloat(value);
+ } catch(NumberFormatException e) {
+ record.latitude = 0;
+ }
+ }
+ if (key.equals("lo")) {
+ try{
+ record.longitude = Float.parseFloat(value);
+ } catch(NumberFormatException e) {
+ record.latitude = 0;
+ }
+ }
+ // dm depreciated use me ( metro_code ) instead
+ if (key.equals("dm") || key.equals("me")) {
+ try{
+ record.metro_code = record.dma_code = Integer.parseInt(value);
+ } catch(NumberFormatException e) {
+ record.metro_code = record.dma_code = 0;
+ }
+ }
+ if (key.equals("ac")) {
+ try{
+ record.area_code = Integer.parseInt(value);
+ } catch(NumberFormatException e) {
+ record.area_code = 0;
+ }
+ }
+ }
+ return record;
+ }
+
+ public synchronized Region getRegion(String str) {
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(str);
+ }
+ catch (UnknownHostException e) {
+ return null;
+ }
+
+ return getRegion(bytesToLong(addr.getAddress()));
+ }
+
+ public synchronized Region getRegion(long ipnum) {
+ Region record = new Region();
+ int seek_region = 0;
+ if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
+ seek_region = seekCountry(ipnum) - STATE_BEGIN_REV0;
+ char ch[] = new char[2];
+ if (seek_region >= 1000) {
+ record.countryCode = "US";
+ record.countryName = "United States";
+ ch[0] = (char)(((seek_region - 1000)/26) + 65);
+ ch[1] = (char)(((seek_region - 1000)%26) + 65);
+ record.region = new String(ch);
+ } else {
+ record.countryCode = countryCode[seek_region];
+ record.countryName = countryName[seek_region];
+ record.region = "";
+ }
+ } else if (databaseType == DatabaseInfo.REGION_EDITION_REV1) {
+ seek_region = seekCountry(ipnum) - STATE_BEGIN_REV1;
+ char ch[] = new char[2];
+ if (seek_region < US_OFFSET) {
+ record.countryCode = "";
+ record.countryName = "";
+ record.region = "";
+ } else if (seek_region < CANADA_OFFSET) {
+ record.countryCode = "US";
+ record.countryName = "United States";
+ ch[0] = (char)(((seek_region - US_OFFSET)/26) + 65);
+ ch[1] = (char)(((seek_region - US_OFFSET)%26) + 65);
+ record.region = new String(ch);
+ } else if (seek_region < WORLD_OFFSET) {
+ record.countryCode = "CA";
+ record.countryName = "Canada";
+ ch[0] = (char)(((seek_region - CANADA_OFFSET)/26) + 65);
+ ch[1] = (char)(((seek_region - CANADA_OFFSET)%26) + 65);
+ record.region = new String(ch);
+ } else {
+ record.coun