frik Posted March 15, 2015 Share Posted March 15, 2015 Hello, In my personal PHP application, I like to identify visitors to my website by checking the IP range that their IP address falls into. This is easy enough for IPv4 when I have the CIDR. For IPv6 however it is another matter entirely, because at present I don't know how to match an IPv6 address. As a result I am using the cumbersome substr matching approach, which does not work for many addresses. For example, consider 2620:149:f01:2b0:99ad:f010:61c1:63c5. The CIDR is 2620:149::/36. The 0 nybble in the 3rd 32-bit word is implied most of the time and this breaks the substr approach. Surely there is by now a simple way to do this. Can someone tell me the best solution that exists at present? Thanks. Quote Link to comment Share on other sites More sharing options...
kicken Posted March 15, 2015 Share Posted March 15, 2015 You'll need to use GMP to store the addresses and compare against a given prefix. If your PHP build supports IPv6, you can use inet_pton to convert the human-readable address into a binary number. If you do not have IPv6 support, you will have to find or create your own parser for IPv6 addresses. For example: $address = '2620:149:f01:2b0:99ad:f010:61c1:63c5'; $network = '2620:149::/36'; $address = inet_pton($address); $address = gmp_init(bin2hex($address), 16); if (false !== $pos=strpos($network, '/')){ $prefix = substr($network, 0, $pos); $bitlength = substr($network, $pos+1); $network = inet_pton($prefix); $network = gmp_init(bin2hex($network), 16); $mask = str_repeat('1', $bitlength).str_repeat('0', 128-$bitlength); $mask = gmp_init($mask, 2); } else { $network = inet_pton($prefix); $network = gmp_init(bin2hex($network), 16); $mask = str_repeat('1', 128); $mask = gmp_init($mask, 2); } $masked_address = gmp_and($address, $mask); $masked_network = gmp_and($network, $mask); if (gmp_cmp($masked_address, $masked_network) === 0){ echo 'address is within the network.'.PHP_EOL; } else { echo 'address is not within the network.'.PHP_EOL; } Quote Link to comment Share on other sites More sharing options...
frik Posted March 15, 2015 Author Share Posted March 15, 2015 You'll need to use GMP to store the addresses and compare against a given prefix. If your PHP build supports IPv6, you can use inet_pton to convert the human-readable address into a binary number. If you do not have IPv6 support, you will have to find or create your own parser for IPv6 addresses. OK, that helps. Thanks. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.