5

I need to convert IPv6 addresses to IPv4 addresses. To do this, I used code from pedmillon's answer to a related question:

$ipv6 = $_SERVER['REMOTE_ADDR'];
$ipv4 = hexdec(substr($ipv6, 0, 2)). "." . hexdec(substr($ipv6, 2, 2)). "." . hexdec(substr($ipv6, 5, 2)). "." . hexdec(substr($ipv6, 7, 2));

I tried it in my localhost and ::1 gets converted to 0.1.0.0. Is this code correctly working?

I believe it should be showing 127.0.0.1 instead of 0.1.0.0.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 7
    IPv6 addresses cannot be converted to IPv4 addresses. That's like wanting to convert apples into bananas. For starters, there are **340,282,366,920,938,463,463,374,607,431,768,211,456** possible IPv6 addresses, while only **4,294,967,296** possible IPv4 addresses. So let me refine: that's like wanting to convert several galaxies worth of apples into one banana. – spectras Aug 15 '17 at 22:58
  • hmm.. then would it be the best solution if I force my Apache to use IPv4 address instead? –  Aug 15 '17 at 23:02
  • 2
    The future-proof solution would be to support ipv6. To ease transition, if you don't want to handle both systems, you can tell your server you want ipv4 addresses mapped into the ipv6 address space, and from there you just work with ipv6. – spectras Aug 15 '17 at 23:05
  • If that would be the future proof solution then can you explain how can I use IPv6 address to block countries on this link https://stackoverflow.com/questions/45702122/country-blocking-by-ip-address-returning-error?noredirect=1#comment78362861_45702122. I have asked this question and I will be pleased if you can answer how I can make my code work with IPv6 also to be future proof. Please have a look. –  Aug 15 '17 at 23:08
  • 2
    The script you found simply does not support IPv6. It's outdated. And guessing country from IPv6 is very hard, and impossible in many cases. IPv6 allocation does not work the same way IPv4 worked. It also covers new needs, for instance mobile devices which keep same address while moving around. – spectras Aug 15 '17 at 23:29
  • You can still use distances like MaxMind's to get a rough idea where an address is from. Their APIs and databases support IPv6. As long as you remember that geolocation is always a guess, nothing more. Also with IPv4... – Sander Steffann Aug 16 '17 at 07:20

2 Answers2

9

IPv4 and IPv6 are two entirely different mutually incompatible network addressing schemes. There is no way to "translate" from one into the other. An IPv4 address does not correspond to a particular IPv6 address or vice versa. The large majority of nodes on the internet still use IPv4 addresses exclusively at this point, some small percentage run a dual-stack of IPv4 and IPv6 simultaneously, and a vanishingly small number may be IPv6 exclusively. IPv4 and IPv6 nodes cannot talk to one another directly. In the long run everyone should be moving to IPv6 exclusively, but that's a long way off.

can you explain how can I use IPv6 address to block countries

The same way you block specific regions using IPv4: get a database that maps IPs to geographic locations. The only difference is that you need to find a database or service which does that for IPv6 addresses.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • IP block attribution schemes make it much more difficult to build such a database though (not to mention it will be much larger). As a matter of fact, I just checked three geolocation services supporting ipv6, and all three of them have my country wrong. Ditto for my hosted server. While with the ipv4 addresses they pinpoint my location pretty accurately (correct neighborhood). – spectras Aug 16 '17 at 13:07
  • 1
    I didn't claim it would be easy or realistic… ;-) – deceze Aug 16 '17 at 13:08
  • `In the long run everyone should be moving to IPv6 exclusively, but that's a long way off.` How many years am I safe with that? ;) –  Aug 17 '17 at 19:36
  • @Shubham You should start supporting IPv6 in every new project if possible, but the world will be dual-stack for quite a while to come. – deceze Aug 17 '17 at 19:49
  • just not getting the IPv6 databases :( can u help me if you know where I can find a similar one? –  Aug 17 '17 at 20:33
  • https://stackoverflow.com/questions/12435582/php-serverremote-addr-shows-ipv6 – s1w_ Jul 01 '21 at 17:14
0

As mentioned above - IPV6 and IPv4 are completely different addressing systems, one does not convert from one to another. However if you look at the issue another way you should be able to get the IPV4 address that may be used by the client. I used PHP and JavaScript to achieve this. Here is my sample code - it works for me. Your output will look something like this:

IP Address: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx IPv4:

xx.xx.xxx.xxx

<? // Grab the IP address of the user
$ipaddress = getenv("REMOTE_ADDR") ; echo 'IP Address: '.$ipaddress;

// Check if we need to try and get the IPv4 address
if(filter_var($ipaddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
?>
<script src=
"https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
    </script>

      <script>

    /* Add "https://api.ipify.org?format=json" statement
               this will communicate with the ipify servers in
               order to retrieve the IP address $.getJSON will
               load JSON-encoded data from the server using a
               GET HTTP request */

    $.getJSON("https://api.ipify.org?format=json", function(data) {

        // Setting text of element P with id gfg
        $("#gfg").html(data.ip);
    })
    </script>

       <p id="gfg"></p>
<?
}
else {
}

?>