6

I have a script which sends a request to another server but problem is that IPv6 does not supported so if I send IPv6 then give error so i need this one of two:

  1. Get IPv4 address all time or
  2. Get both IPv4 and IPv6 addresses

I use this code to get the IP address

function getRealIP()
    {
        if (isset($_SERVER["HTTP_CLIENT_IP"])) {
            $ip = $_SERVER["HTTP_CLIENT_IP"];
        } elseif (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
            $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
        } elseif (isset($_SERVER["HTTP_X_FORWARDED"])) {
            $ip = $_SERVER["HTTP_X_FORWARDED"];
        } elseif (isset($_SERVER["HTTP_FORWARDED_FOR"])) {
            $ip = $_SERVER["HTTP_FORWARDED_FOR"];
        } elseif (isset($_SERVER["HTTP_FORWARDED"])) {
            $ip = $_SERVER["HTTP_FORWARDED"];
        } else {
            $ip = $_SERVER["REMOTE_ADDR"];
        }

        // Strip any secondary IP etc from the IP address
        if (strpos($ip, ',') > 0) {
            $ip = substr($ip, 0, strpos($ip, ','));
        }
        return $ip;
    }

But this function only returns one IPv address. How can I get all time IPv4 or get both addresses?

squancy
  • 565
  • 1
  • 7
  • 25
Shafiqul Islam
  • 5,570
  • 2
  • 34
  • 43
  • Why don't you add validation for both IPv4 & IPv6? – Lovepreet Singh Jul 09 '18 at 12:03
  • yes i can validate but i need this – Shafiqul Islam Jul 09 '18 at 12:04
  • You can only get the ip address used to connect. If that was IPV4 (still most likely) then thats it. If user is connecting over IPV6 then you will get the IPV6 address. Do you have an IPV6 network/router? – RiggsFolly Jul 09 '18 at 12:04
  • A client only connects on IPv4 *or* IPv6, not both. So the webserver will only see one or the other. – Jonathon Reinhart Jul 09 '18 at 12:04
  • ok but can i get all time ipv4? – Shafiqul Islam Jul 09 '18 at 12:05
  • If you only have an ipv4 ip address for your server, then you will only get connected over IPV4 – RiggsFolly Jul 09 '18 at 12:05
  • And never use anything but `REMOTE_ADDR` **unless and until** you know you're behind a proxy that you control that masks the real remote IP and forwards it in an HTTP header instead. That'd be a typical situation if you're using a load balancer or CDN. If you're not using any of those, ignore all `HTTP_` headers for IP addresses. – deceze Jul 09 '18 at 12:08
  • Possible duplicate of [PHP function to show both ipv4 ipv6](https://stackoverflow.com/questions/33214331/php-function-to-show-both-ipv4-ipv6) – Michael Hampton Jun 29 '19 at 21:30

3 Answers3

16

A client will send a request to your server using only one protocol. It doesn't send the request using both IPv4 and IPv6 at the same time, and there's no way to interleave both protocols, and IPv4 addresses also don't translate into equivalent IPv6 addresses. If the client sent the request using IPv4, then you'll get the IPv4 address. If they sent the request using IPv6, you'll get the IPv6 address. Period. End of story.

If you require an IPv4 address, then you have to disable IPv6 support on your server/DNS entry, so all clients are forced to use IPv4 as the only available protocol. But that would also be a terrible step backwards in this day and age.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 1
    So then, if you are trying to test if someone has a certain IP, you would need to be prepared for both IP addresses to be incoming? (I know spoofing exists still) – Elijah Mock Mar 14 '20 at 15:28
  • These accepted answers need updating because, as pointed out by @Jeffrey Kastner back in 2018 and still happens today (July 2021), some services display a visitor's IPV 4 and IPV6 ip addresses. – Mark Lee Jul 30 '21 at 04:24
  • What I discovered is that my router operates in dual mode so that whoever checks can identify both. I disabled IPV6 for my purposes since it seems difficult to connect remotely using IPV6. – Mark Lee Jul 30 '21 at 04:39
  • @Mark One request can only be sent using one IP address and protocol. If your router is supporting both, then a website can be rigged to include some IPv6-only and IPv4-only resources, and through cookies or other ids you can consolidate those separate requests with their separate IPs to one user. It’s not impossible to find multiple IPs per user. That doesn’t usually help you much though. – deceze Jul 30 '21 at 05:03
  • @decze https://whatismyipaddress.com/ goes to great lengths to make both available it would seem. I rigged my own dynamic ip on a website for some audio streaming but it now arbitrarily skips between the two versions. – Mark Lee Jul 30 '21 at 11:57
  • 2
    @Mark Yes, they appear to have the explicit subdomain `ds4.whatismyipaddress.com`, which is only served over IPv4, and the page makes an explicit request to that with a unique token, so it can be linked back to the original IPv6 request (or vice versa). – deceze Jul 30 '21 at 12:02
12

You can't.

Only the IP address the request came from is available.

There's no reliable way to identify other IP addresses (my laptop currently has 12 IP addresses) that route to the same computer.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 8
    IF you can't, then how IS it being done here? https://whatismyipaddress.com – Jeffrey Kastner Sep 30 '18 at 14:38
  • 5
    This is most likely done with a redirect (using Javascript?) or a request to IPv6 or a IPv4 only address respectively and using that to return a response with the missing address. For example: Connect through IPv4, that IP is now found. Use a Javascript to request to ipv6test.service.tld to get missing address. – Sampsa Suoninen Apr 05 '19 at 11:36
  • 1
    Most likely by embedding resources in the page like images, scripts etc that resolve to IPv4 or IPv6 addresses, as a result forcing your browser to make HTTP connections over both protocols. – Andrew Rout Mar 20 '22 at 02:06
0

This is just a thought but maybe the trick is how said client queries the server.

Its what I use to gain my Public WAN_IPv4 & Public WAN_IPv6 with a simple Cron job to fire every xx mins and update one of my DNS records

Why not go up a layer and query the hostname NS A and AAAA records itself?

$ dig dom.domain -A | grep "ip ..." [with some some regex to extract specific pattern.]

Or a combination of approaches, maybe even employ curl to grab the -ipv4 address and then use a direct call to "ping" the myip6.php script for IPv6 return.?

Or keep it simple via dns resolving on interface with cURL

$ curl --help all
...
--dns-interface <interface> Interface to use for DNS requests
--dns-ipv4-addr <address> IPv4 address to use for DNS requests
--dns-ipv6-addr <address> IPv6 address to use for DNS requests
--dns-servers <addresses> DNS server addrs to use
...
--interface <name>   Use network INTERFACE (or address)
-4, --ipv4               Resolve names to IPv`enter code here`4 addresses
-6, --ipv6               Resolve names to IPv6 addresses
...

if using curl you can specify option -4 and -6 to indicate which IP stack to return its result

$ curl -4 dom.domain
OUTPUT:
> 255.255.255.255

The same can be done for IPv6 by using -6

$ curl -6 dom.domin 
OUTPUT:
> 20a1:efef:ffff::0

Above can then of course can be piped out to either console or stored inside a _VAR for later use.

I mean this is not a direct method to answer your specific question BUT it does give you options when managing dual-ipstack machines and its what I do.

There is also a very good example on how you could use curl for this exact job [name-resolve-tricks-with-c-ares][1] [1]: https://everything.curl.dev/usingcurl/connections/name#name-resolve-tricks-with-c-ares

Majika
  • 13
  • 4