12

Possible Duplicate:
How can I check if an ip is in a network in python

What is the easy way to match subnet to an ip address in python, so that if the ip address is in the subnet I can choose it?

Thanks in advance.

Community
  • 1
  • 1
0xmtn
  • 2,625
  • 5
  • 27
  • 53
  • 1
    It's really not clear what you're asking. What are you choosing, the IP or the subnet? Is the question "how can I tell if an IP address is in a particular subnet?" Or what? – David Schwartz Mar 15 '12 at 09:41

2 Answers2

25

In Python 3.3+, you can use ipaddress module:

>>> import ipaddress
>>> ipaddress.ip_address('192.0.43.10') in ipaddress.ip_network('192.0.0.0/16')
True

If your Python installation is older than 3.3, you can use this backport.


If you want to evaluate a lot of IP addresses this way, you'll probably want to calculate the netmask upfront, like

n = ipaddress.ip_network('192.0.0.0/16')
netw = int(n.network_address)
mask = int(n.netmask)

Then, for each address, calculate the binary representation with one of

a = int(ipaddress.ip_address('192.0.43.10'))
a = struct.unpack('!I', socket.inet_pton(socket.AF_INET, '192.0.43.10'))[0]
a = struct.unpack('!I', socket.inet_aton('192.0.43.10'))[0]  # IPv4 only

Finally, you can simply check:

in_network = (a & mask) == netw
phihag
  • 278,196
  • 72
  • 453
  • 469
  • anyway to do this more efficiently for a giant set of tables? ex. I have a table of some 100,000 of these :) – Eiyrioü von Kauyf Nov 30 '12 at 18:20
  • @EiyrioüvonKauyf Updated the answer for that case as well. – phihag Nov 30 '12 at 18:43
  • The second approach, which calculates the netmask upfront, does not seem to work. I followed the exact step, and in the end, `in_network` is `False`. I am using the port of the module to 2.6 and 2.7. Using `ipaddr` (https://code.google.com/p/ipaddr-py/) is the same: yielding a False for the above example. Note that I imported the `py` module files directly without run the `setup.py`, which I don't think is an issue. – Causality Oct 15 '14 at 07:29
  • @Causality Great catch! Fixed by switching to ints. – phihag Oct 15 '14 at 14:12
  • Has since been [imported to older python versions](https://pypi.python.org/pypi/ipaddress). – Belmin Fernandez Dec 30 '14 at 16:33
  • 1
    @BelminFernandez Thanks, I've added the backport (by yours truly ;) ) to the answer. – phihag Dec 30 '14 at 22:35
2

If for a given IP you want to find a prefix from a long list of prefixes, then you can implement longest prefix match. You first build a prefix tree from your list of prefixes, and later, you traverse the tree looking for the furthest leaf that matches your prefix.

It sounds scary, but it is not that bad :)

Jakub M.
  • 32,471
  • 48
  • 110
  • 179