I have a table A with IP addresses (ipNumeric) stored as unsigned ints and a table B with subnets (subnetNumeric):
INET_NTOA(ipNumeric) = 192.168.0.1
INET_NTOA(subnetNumeric) = 192.168.0.0
I'd like to check if this IP is a member of a subnet.
The subnets are Class A, B and C.
Is this possible to do in reasonable time in MySQL on the fly or should the subnet ranges be precomputed?
You can determine the number and type of IP addresses any given local network requires based on its default subnet mask. An example of Class A IP address and subnet mask would be the Class A default submask of 255.0. 0.0 and an IP address of 10.20. 12.2.
IP Address In CIDR Range Check Please enter a valid IP Address in IPv4 format and CIDR notation range to check if it belongs to it. For example: enter IP address 192.168. 0.1 and for CIDR range 192.168. 0.0/24 to test it.
How to identify a company's public network address range. One of the most traditional ways to get the IP address of a company is to use the ping command, which allows you to get the main IP address of the webserver behind the webpage.
Sure, it's doable. The idea is that we calculate the subnet mask by setting the most significant bits to 1, as many as dictated by the subnet class. For a class C, that would be
SELECT -1 << 8;
Then, AND the subnet mask with the IP address you have; if the IP is inside the subnet, the result should be equal to the subnet address -- standard networking stuff. So we end up with:
SELECT (-1 << 8) & INET_ATON("192.168.0.1") = INET_ATON("192.168.0.0");
Update: Yes, it is necessary to know the network class or the subnet mask (which is equivalent information). Consider how could you handle the case where the subnet is X.Y.0.0
if you did not have this information. Is this X.Y.0.0/16
or X.Y.0.0/8
where the third octet just happens to be 0? No way to know.
If you do know the subnet mask, then the query can be written as
SELECT (-1 << (33 - INSTR(BIN(INET_ATON("255.255.255.0")), "0"))) &
INET_ATON("192.168.0.1") = INET_ATON("192.168.0.0");
This is the MySQL function we use.
DELIMITER $$
DROP FUNCTION IF EXISTS `ip_in_subnet_mask`$$
CREATE DEFINER=`root`@`%` FUNCTION `ip_in_subnet_mask`(ip VARCHAR(20), subnet VARCHAR(20), netmask VARCHAR(20)) RETURNS TINYINT(1)
DETERMINISTIC
BEGIN
RETURN (INET_ATON(ip) & INET_ATON(netmask)) = INET_ATON(subnet);
END$$
DELIMITER ;
e.g. Find all the rows where t.ip is in the range 192.168.0.x where 0<=x<=255
SELECT *
FROM t
WHERE
ip_in_subnet_mask(t.ip, "192.168.0.0", "255.255.255.0")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With