8

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?

8
  • Why don't you add validation for both IPv4 & IPv6? Commented Jul 9, 2018 at 12:03
  • yes i can validate but i need this Commented Jul 9, 2018 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? Commented Jul 9, 2018 at 12:04
  • A client only connects on IPv4 or IPv6, not both. So the webserver will only see one or the other. Commented Jul 9, 2018 at 12:04
  • ok but can i get all time ipv4? Commented Jul 9, 2018 at 12:05

4 Answers 4

22

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.

Sign up to request clarification or add additional context in comments.

6 Comments

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)
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.
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 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.
@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).
|
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.

3 Comments

IF you can't, then how IS it being done here? whatismyipaddress.com
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.
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.
1

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 you should use this code 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.

6 Comments

I don't get how this code makes any sense
@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.
And what's the point of such redirect? And, for that matter, how does it answer the question asked above?
@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.
@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.
|
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.