[Tutor] searching for an ip and subnets in a dir of csv's

Martin A. Brown martin at linux-ip.net
Wed Jul 29 16:04:28 CEST 2009

Hash: SHA1


 : The script will be ran from a third party tool so only one 
 : argument can be passed to it which will be an entire IP address.  
 : If within the CSV's there is no 32 bit match there could be a 
 : subnet that might match, thats why I need it to loop over the 
 : dots.  If there is a 32 bit and a subnet match both will be 
 : returned which is desirable .
 : I figured out a way to cut of the ends from the dots using the 
 : following code,
 : string.rsplit('.',1)[:1];

You, very likely, know something about your data that I do not, 
however, I couldn't help but notice that your choice of octet 
boundaries is not really quite sufficient when trying to find the 
network in which a given host would live.  The /24, /16 and /8 
boundaries are used in classful routing (class C, class B and class 
A respectively), which has largely been supplanted by CIDR.

Classless InterDomain Routing (CIDR) allows for netmasks which do 
not fall on the octet boundaries.  Consider the IP  
Here are some of the network addresses (prefixes) that could contain 
that host:

If you found any of these in your input data, that would indicate 
that the host would be inside that network.  With that 
said, here's a little function (my bad reimplementation of something 
probably in an IP handling library like ipaddr [0]) that will return 
a list of prefixes in string form which you can search for in your 
input text.

Remember when searching for IPs in their string form that you should 
anchor (at absolute least) at the beginning of the string.  In 
short, without the anchoring, you'll get three results, where only 
one should actually match.  (Imagine looking for '' 
without an anchor at the front.  You'd also match '' 
and ''.)

 : looping over this and incrementing the first digit cuts of the 
 : octets from the IP correctly.  My problem now is that the rsplit 
 : returns a list and I need a string.  I am stuck on how to use the 
 : rsplit. Thanks.
 : ipAdres = re.compile(sys.argv[1])
 : print ipAdres.pattern
 : print ipAdres.pattern.rsplit('.',1)[:1]
 : for arg in args:
 :     for f in files:
 :         ff = csv.reader(open (f, 'rb'), delimiter=' ', quotechar='|')
 :         for row in ff:
 :             if any(ipAdres.search(cell) for cell in row):
 :                 print f
 :                 print ', '.join(row)

Good luck in your text searching!

- -Martin

 [0] An IP address handling library that is much richer than the 
     hastily-written snippet below:

  #! /usr/bin/env python
  import sys
  import struct
  import socket
  maxmasklen = 32
  def list_networks( ip, minmasklen=8, defaultmasklen=32 ):
    if ip is None:
      raise ValueError, "Supply an IP to this function"
    mask = defaultmasklen
    ip = struct.unpack('>L',socket.inet_aton( ip )) 
    networks = list()
    while mask >= minmasklen:
      bits  = maxmasklen - mask
      ip    = ( ( ( ip[0] >> bits ) << bits ), )
      net   = socket.inet_ntoa( struct.pack( '>L', ip[0] ) ) + '/' + str( mask )
      networks.append( net )
      mask -= 1
    return networks
  if __name__ == '__main__':
    for ip in sys.argv[1:]:
      networks = list_networks( ip );
      for network in networks:
        print network
  # -- end of file

- -- 
Martin A. Brown
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: pgf-0.72 (http://linux-ip.net/sw/pine-gpg-filter/)


More information about the Tutor mailing list