简体   繁体   中英

Get subnet from IP address

I am trying to get subnet for IP address I have.

Eg :

1

Subnet mask : 255.255.255.0

Input : 192.178.2.55

Output : 192.178.2.0

2

Subnet mask : 255.255.0.0

Input : 192.178.2.55

Output : 192.178.0.0

Currently, the way I do it (for subnet 255.255.255.0)

ip =  '192.178.2.55'
subnet = '.'.join(ip.split('.')[:2]) + '.0.0'
subnet
'192.178.0.0'

I see python has ipaddress library. However I could not find a method that could do the above task.

Bonus : Since ipaddress supports IPv4 and IPv6, if the same function could be used for both.

The ipaddress.ip_network function can take any of the string formats that IPv4Network and IPv6Network can take, including the address/mask format.

Since you're not actually passing the network address, but an address within that network with host bits set, you need to use strict=False .

So:

>>> net = ipaddress.ip_network('192.178.2.55/255.255.255.0', strict=False)
>>> net
IPv4Network('192.178.2.0/24')
>>> net.network_address
IPv4Address('192.178.2.0')
>>> net.netmask
IPv4Address('255.255.255.0')

Alternatively, you can use ip_interface and extract the network from there:

>>> iface = ipaddress.ip_interface('192.178.2.55/255.255.255.0')
>>> iface
IPv4Interface('192.178.2.55/24')
>>> iface.network
IPv4Network('192.178.2.0/24')
>>> iface.netmask
IPv4Address('255.255.255.0')
>>> iface.ip
IPv4Address('192.178.2.55')
>>> iface.network.network_address
IPv4Address('192.178.2.0')

Which of the two you want depends on what exactly you're trying to represent. Notice that the Interface types are subclasses of the Address types, and of course they remember the original address that was used to construct them, while the Network classes remember the network address; one of those two is usually the deciding factor.

Both of them will, of course, work just as well with IPv6:

>>> ipaddress.ip_interface('2001:db8::1000/32')
IPv6Interface('2001:db8::1000/32')
>>> ipaddress.ip_interface('2001:db8::1000/32').network.network_address
IPv6Address('2001:db8::')

subnet is simply a binary mask that must be and 'ed bitwise with the IP address. You can apply the mask yourself:

".".join(map(str, [i & m # Apply the mask
          for i,m in zip(map(int, ip.split(".")),
                         map(int, subnet.split(".")))]))
#'192.178.2.0'

This solution works only for IPv4 addresses.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM