I want to check via php if someone connects to my site via IPv4 or IPv6.
The client address can be found in $_SERVER["REMOTE_ADDR"] but how to check if it's IPv4 or IPv6 ?
Check for IPv4
$ip = "255.255.255.255"; if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { echo "Valid IPv4"; } else { echo "Invalid IPv4"; } Check for IPv6
$ip = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329"; if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { echo "Valid IPv6"; } else { echo "Invalid IPv6"; } For more, check PHP function filter_vars and list of filters for validation.
You can use this:
function ipVersion($txt) { return strpos($txt, ":") === false ? 4 : 6; } 6 because of IPv4-mapped IPv6 addresses. To fix this, also check that the string doesn't begin with ::ffff: (and you probably want to strip that, too).2001:db8::10.0.0.1 is a perfectly valid IPv6 address.::ffff:10.20.30.40! It does on my server. It's better to check for the dot . character; it only appears in IPv4. By the way, while kasperd's address is sometimes valid, it is never returned by the server. The dot is really the proof of IPv4 here.What about counting the number of '.' and/or ':' in $_SERVER["REMOTE_ADDR"] ?
If there is more than 0 ':', and no '.' symbol in $_SERVER["REMOTE_ADDR"], I suppose you can consider you user is connected via IPv6.
Another solution might be to use the filter extension : there are constants (see the end of the page) that seem to be related to IPv4 and IPv6 :
FILTER_FLAG_IPV4(integer)
Allow only IPv4 address in "validate_ip" filter.
FILTER_FLAG_IPV6(integer)
Allow only IPv6 address in "validate_ip" filter.
Since the highest voted answer has a rather significant problem, I'm going to share my own.
This returns true if an address which appears to be IPv6 is passed in, and false if an address which appears to be IPv4 (or IPv4-mapped IPv6) is passed in. The actual addresses are not further validated; use filter_var() if you need to validate them.
function is_ipv6($address) { $ipv4_mapped_ipv6 = strpos($address, "::ffff:"); return (strpos($address, ":") !== FALSE) && ($ipv4_mapped_ipv6 === FALSE || $ipv4_mapped_ipv6 != 0); } You can use AF_INET6 to detect if PHP is compiled with IPv6 support:
<?php if ( defined('AF_INET6') ) { echo 'Yes'; } else { echo 'No'; } ?>