Reputation: 453
I am trying to run a routine on two lists, sourced from MySQL queries - one contains CIDR networks and the other contains IP addresses. I am trying to compare entries in the IP list to see whether they are in the networks described by the CIDR list, and act on those that are not.
I am trying to use the netaddr
module but this doesn't appear to be implemented on Python3 yet?
I have also tried to use ipaddress
but I can't seem to get them to compare correctly. Using ipaddress I have the following code:
networks = (('1.1.6.0/20',), ('2.8.2.0/19',), ('7.2.2.0/19',), ('2.2.0.0/19',))
ips = ((8888, 'customer', b'2.8.4.64', '8888*200'),(8888, 'customer', b'1.1.6.3', '8888*201'), (8888, 'customer', b'122.223.159.3', '8888*202'))
straglers = list()
for ip in ips:
exclude = 0
for network in networks:
subnet = ip_network(network[0])
if ip_address(ip[2]) in subnet:
exclude = 1
if exclude == 0:
straglers.append([ip[3],ip[2],ip[1]]) # extension, customer_ip, company
As things stand the code gives a value error as follows: ValueError: b'82.148.47.64' does not appear to be an IPv4 or IPv6 address
I have tried converting ip[2]
to an utf-8 string but this makes no difference.
Upvotes: 1
Views: 1932
Reputation:
What you are describing as a list is actually a tuple.
First, when I ran your code I did not receive the error you are getting
ValueError: b'82.148.47.64' does not appear to be an IPv4 or IPv6 address
Instead I received the following
raise ValueError('%s has host bits set' % self) ValueError: 1.1.6.0/20 has host bits set
Is this the error your are actually receiving? If so, this is how to properly correct it.
Referenced from ipaddress module Defining Networks:
By default, attempting to create a network object with host bits set will result in ValueError being raised. To request that the additional bits instead be coerced to zero, the flag strict=False can be passed to the constructor:
This is because the host bits are set and will need to be coerced to zero, as the documentation states above. Pass the following flag strict=False to the constructor.
For example.
subnet = ip_network(network[0], strict=False)
Also, in your ips contained in your tuple need only to be formatted to a string.
For example.
ips = ((8888, 'customer', '2.8.4.64', '8888*200')
OR the following will be presented to you.
'ValueError: b'2.8.4.64' does not appear to be an IPv4 or IPv6 address'
The full working code.
from ipaddress import ip_network, ip_address
networks = (('1.1.6.0/20',), ('2.8.2.0/19',), ('7.2.2.0/19',), ('2.2.0.0/19',))
ips = ((8888, 'customer', b'2.8.4.64', '8888*200'),(8888, 'customer', b'1.1.6.3', '8888*201'), (8888, 'customer', b'122.223.159.3', '8888*202'))
straglers = list()
for ip in ips:
exclude = 0
for network in networks:
subnet = ip_network(network[0], strict=False)
print(ip_address(ip[2].decode('utf-8')))
print(subnet)
if ip_address(ip[2].decode('utf-8')) in subnet:
exclude = 1
if exclude == 0:
straglers.append([ip[3],ip[2],ip[1]]) # extension, customer_ip, company
print(straglers)
Upvotes: 4