autocracy/python-ipy

Issue with IPSet iterator?

Closed this issue · 3 comments

Hello,

Would like to first start off by saying that Python is not my my strong suit so apologies in advanced for any terminology I may not be using properly or improper syntax, etc.

I've been utilizing this package in conjunction with poodle-prober. I've forked the repo and I am attempting to add a CSV input/output option to the script. I'm having trouble with this PoC:

import IPy
import csv

net = IPy.IPSet()
with open('test.csv', newline='') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    for row in reader:
        net.add(IPy.IP(row[0]))

print(len(net))
count = 0
for ip in net:
    count += 1
print(count)

I'm attempting to read a CSV file which contains a list of IP addresses. The addresses are both public and private in various ranges. I believe they are being stored in the following way:

$ file test.csv
test.csv: ASCII text, with CRLF line terminators

My issue is that in my end result of my script, I've been tearing my hair out trying to figure out why the length of the output file differed from the input file. I've narrowed it down to the above code.

The total amount of IP addresses in the list for this test was 262.
I noticed that len(net) was 262 and count was 229.
If I change the IPSet object to just a regular list and do .append() instead of .add(), then the count matches 262.
Is there a reason for why this is happening? Is this a bug?

Thanks

What is most likely happening is that you're finding overlapping addresses ranges or neighboring addresses that are being condensed into smaller representation by IPSet.

from IPy import IP, IPSet
a = IPSet([IP('192.168.1.2'), IP('192.168.1.3'), IP('192.168.1.4')])
print "Length: %i" % (a.len())
print a

print
print "Simple print:"
for x in a:
    print x

print
print "Complex print"
for x in a:
    for y in x:
        print y

Length: 3
IPSet([IP('192.168.1.2/31'), IP('192.168.1.4')])

Simple print:
192.168.1.2/31
192.168.1.4

Complex print
192.168.1.2
192.168.1.3
192.168.1.4

Or:

for ip in net:
count += ip.len()

Understood, thank you!