I'd like to find a way to do a SQL query that will calculate the cidr (bit representation) of a subnet mask stored in the database. So for example, I've got either 255.255.255.0 or its decimal value (4294967040) stored in the database. I'd like to do a select and get back /24 representation via the query.
I've done things like the following to determine the last IP of a subnet so I'm hoping to do something similar to determine the cidr representation of a mask.
select concat(inet_ntoa(ip_addr),'-',
inet_ntoa(ip_addr+(POWER(2,32)-ip_mask-1))) range
from subnets
order by ip_addr
Preferably this would be a SQL statement that would work under mysql, postgres, oracle etc.
The CIDR number comes from the number of ones in the subnet mask when converted to binary. The subnet mask 255.255. 255.0 is 11111111.11111111. 11111111.00000000 in binary.
The CIDR number is typically preceded by a slash “/” and follows the IP address. For example, an IP address of 131.10. 55.70 with a subnet mask of 255.0. 0.0 (which has 8 network bits) would be represented as 131.10.
How many addresses does a CIDR block represent? You calculate 2 32-prefix , where prefix is the number after the slash. For example, /29 contains 232-29=23=8 addresses. Here's a quick table that you can reference for the most CIDR blocks.
CIDR notation is really just shorthand for the subnet mask, and represents the number of bits available to the IP address. For instance, the /24 in 192.168.0.101/24 is equivalent to the IP address 192.168.0.101 and the subnet mask 255.255.255.0 .
e.g. you need to convert 255.255.255.252
netmask into bit mask.
I always use this simple query (PostgreSQL) :
SELECT 32-length(trim(((split_part('255.255.255.252','.',1)::bigint*(256^3)::bigint +
split_part('255.255.255.252','.',2)::bigint*(256^2)::bigint +
split_part('255.255.255.252','.',3)::bigint*256 +
split_part('255.255.255.252','.',4)::bigint)::bit(32))::text,'1'));
not as nice as could be, but it's short and working like a charm..
I think I have found the solution to my issue. Here is what I have done:
select CONCAT(INET_NTOA(ip_addr),'/',32-log2((4294967296-ip_mask))) net
from subnets
order by ip_addr
Basically I take my decmial mask and subtract it from the maximum decimal value. I then to a log2 on that value to get the logarithm value. Then simply subtract that from 32 (the maximum bit available).
Hope that helps others.
Thanks
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