How can I get both IPv4 and IPv6 address using PHP code?
Asked Answered
B

4

7

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

$ip = $_SERVER["REMOTE_ADDR"];

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

Bedspread answered 9/7, 2018 at 11:58 Comment(8)
Why don't you add validation for both IPv4 & IPv6?Peterec
yes i can validate but i need thisBedspread
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?Mountaineer
A client only connects on IPv4 or IPv6, not both. So the webserver will only see one or the other.Rushton
ok but can i get all time ipv4?Bedspread
If you only have an ipv4 ip address for your server, then you will only get connected over IPV4Mountaineer
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.Comportment
Possible duplicate of PHP function to show both ipv4 ipv6Mutilate
B
13

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.

Basile answered 9/7, 2018 at 12:3 Comment(3)
IF you can't, then how IS it being done here? whatismyipaddress.comScarlet
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.Reflexion
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.Djakarta
C
19

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.

Comportment answered 9/7, 2018 at 12:5 Comment(6)
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)Keyboard
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.Ojibwa
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.Ojibwa
@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.Comportment
@decze 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.Ojibwa
@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).Comportment
B
13

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.

Basile answered 9/7, 2018 at 12:3 Comment(3)
IF you can't, then how IS it being done here? whatismyipaddress.comScarlet
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.Reflexion
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.Djakarta
E
1

Only for sake of experiment you could do something like this:

<?php

$ipv4 = $_GET['ipv4'] ?? "";
$ipv6 = $_GET['ipv6'] ?? "";

$ip = $_SERVER['REMOTE_ADDR'];
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
    $ipv4 = $ip;
} elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
    $ipv6 = $ip;
}

echo "Your IPv4 is: $ipv4 <br>";
echo "Your IPv6 is: $ipv6 <br>";

// Redirect user to this page with the other IP version if one is missing

if($ipv4 == ""){
    header("Location: http://127.0.0.1/ip.php?ipv6=$ipv6");
}

if($ipv6 == ""){
    header("Location: http://[::1]/ip.php?ipv4=$ipv4");
}

?>

But this code hardy has any practical application and you should use it with caution, as it does not provide validation of IP addresses, does not handle redirection loops, and does not account for cases where the user does not have access via IPv6 or IPv4(you could use javascript to detect that on client side).

You will also need to configure your web server to use this.

Egoism answered 7/10, 2023 at 11:26 Comment(6)
I don't get how this code makes any senseKos
@YourCommonSense The script is redirecting the client to itself using either the IPv4 or IPv6 address (or it could be DNS records pointing to these addresses) of the server.Egoism
And what's the point of such redirect? And, for that matter, how does it answer the question asked above?Kos
@YourCommonSense It answers the OP's question, as this code returns both IP addresses. The point of such a redirect is to obtain the missing IP of the client. If REMOTE_ADDR is IPv4, then the script will redirect to itself using an IPv6 address of server(or it could be an IPv6-only hostname of this same server), so after the redirect, REMOTE_ADDR is going to be IPv6.Egoism
@drushadrusha: This will probably only work if the web browser and the web server are running on the same computer. That can happen during development, but after that it is extremely rare.Creedon
@KIKOSoftware No, you just need to change 127.0.0.1 and [::1] to whatever your server is using.Egoism
L
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

Lais answered 7/1, 2023 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.