3

I have geoip setup by following these identical steps (http://php.net/manual/en/geoip.setup.php):

wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoLiteCity.dat.gz
sudo mkdir -v /usr/share/GeoIP
sudo mv -v GeoLiteCity.dat /usr/share/GeoIP/GeoIPCity.dat

sudo apt-get install php5-geoip

This works brilliantly and has for several years now with IPv4 addresses. I did not, however realize how broken it was with incoming IPv6 devices. For example, it returns Notice: geoip_country_code_by_name(): Host 26xx:8:xx00:cf20:caxx:ff:fexx:35b5 not found

I have been through quite a few things attempting to fudge it into working, including:

  • testing for v6 address and using geoip_open("/usr/share/GeoIP/GeoIPv6.dat", GEOIP_STANDARD);

Apparently geoip_open is not an available function ala php5-geoip

  • I have tried using geoip_country_code_by_name_v6($ip)

This is another function that is not available even though geoip_country_code_by_name($ip) works great.

No avail so far.

Is there any way I can easily, within my PHP code select which database I want to use so that I can simply test whether it is an IPv4 or IPv6 address and load the appropriate database?

  • Make sure you're using `GeoLite2`. IPv6 is not supported by the legacy products. – Barmar May 07 '15 at 23:21
  • https://www.maxmind.com/en/ipv6-information-and-faq – Barmar May 07 '15 at 23:21
  • @Barmar if I understand correctly, the Geolite2 binaries are not .dat files and thus could not be used with my current integration with PHP. I do have the legacy IPv6 dat file but I am unable to indicate which .dat file to lookup in via my PHP code as far as I know. –  May 08 '15 at 00:28
  • Sorry, I don't know the integration process. – Barmar May 08 '15 at 00:33

2 Answers2

4

In order to support IPv6->Country code easily and without unnecessary files based on the integration above:

Grab a copy of the latest legacy IPv6 data (I'm assuming you already have IPv4 binary):

wget http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz

Decompress and move it to a dir accessible to your web server:

gunzip GeoIPv6.dat
mv GeoIPv6.dat /etc/usr/share/GeoIP/GeoIPv6.dat

Grab a copy of geoip.inc from the Maxmind git dir (https://github.com/maxmind/geoip-api-php/blob/master/src/geoip.inc) and save it somewhere you can access wherever you'll need to run geoip.

If you have php5-geoip installed as I did, remove it with sudo apt-get remove php5-geoip; purge as necessary.

With the above done you can now test incoming IP address for v4 or v6 and get appropriate results.

Example:

<?php
include_once('geoip.inc');

//set an IPv6 address for testing
$ip='2601:8:be00:cf20:ca60:ff:fe09:35b5';

/*
test if $ip is v4 or v6 and assign appropriate .dat file in $gi
run appropriate function geoip_country_code_by_addr() vs geoip_country_code_by_addr_v6()   
*/
if((strpos($ip, ":") === false)) {
    //ipv4
    $gi = geoip_open("/usr/share/GeoIP/GeoIP1.dat",GEOIP_STANDARD);
    $country = geoip_country_code_by_addr($gi, $ip);
}
else {
    //ipv6
    $gi = geoip_open("/usr/share/GeoIP/GeoIPv6.dat",GEOIP_STANDARD);
    $country = geoip_country_code_by_addr_v6($gi, $ip);
}
echo $ip . "<br>" . $country;

This is specifically for Country, but can easily be replicated for City data.

0

It is not needed something external for just country info for IPv6. PHP pecl geoip since v1.1.1 from 2016 https://pecl.php.net/package-changelog.php?package=geoip&release=1.1.1 supports 3 new functions geoip_country_code_by_name_v6(), geoip_country_code3_by_name_v6() and geoip_country_name_by_name_v6() which unfortunately are not mentioned in official PHP doc: https://www.php.net/manual/en/ref.geoip.php Functions require file GeoIPv6.dat. Note that city info for IPv6 is not supported.

$countryCode = (strpos($ip, ":") === false) ? geoip_country_code_by_name($ip) : geoip_country_code_by_name_v6($ip);

mikep
  • 5,880
  • 2
  • 30
  • 37