Match IPv4 address given IP range/mask?

ip-address, php, regex

Solution

Use this library: https://github.com/S1lentium/IPTools

//Check if IP is within Range:

echo Range::parse('192.168.1.1-192.168.1.254')->contains(new IP('192.168.1.5')); // true
echo Range::parse('::1-::ffff')->contains(new IP('::1234')); // true

Problem

Either with PHP or a RegExp (or both), how do I match a range of IP addresses? Sample Incoming IPs ``` 10.210.12.12 10.253.12.12 10.210.12.254 10.210.12.95 10.210.12.60 ``` Sample Ranges ``` 10.210.12.0/24 10.210.12.0/16 10.210.*.* 10.*.*.* ``` I know that I can do this: ``` ?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) ``` ...but it doesn't take ranges into account. It merely lets you match an incoming number to see if it's an IP address where each octet is 0-255. EDIT: There's also this function that I found in a comment at php.net on the ip2long function. ``` function ip_in_network($ip, $net_addr, $net_mask){ if($net_mask <= 0){ return false; } $ip_binary_string = sprintf("%032b",ip2long($ip)); $net_binary_string = sprintf("%032b",ip2long($net_addr)); return (substr_compare($ip_binary_string,$net_binary_string,0,$net_mask) === 0); } ip_in_network("192.168.2.1","192.168.2.0",24); //true ip_in_network("192.168.6.93","192.168.0.0",16); //true ip_in_network("1.6.6.6","128.168.2.0",1); //false ``` It's short and sweet, but doesn't match the asterisk situation. I also don't know if it's entirely accurate because it returns a true result on this when I thought it would be a false: ``` echo ip_in_network("192.168.2.1","192.167.0.0",1); ``` ...but perhaps I misunderstand what the /1 would be. Perhaps I needed to use /24.

Original source