Skip to content

Instantly share code, notes, and snippets.

@epinna
Forked from reorx/iprange.py
Created November 29, 2019 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save epinna/dc3dc72dfac6294f0036e3d0760fafa8 to your computer and use it in GitHub Desktop.
Save epinna/dc3dc72dfac6294f0036e3d0760fafa8 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# coding: utf-8
#
# Copyright (C) Michael Ihde 2004 <mike.ihde@randomwalking.com>
#
# Distributed under the Python License
#
# iprange is a useful module that creates iprange generators similar
# to python's xrange. This allows you to write statements such as
#
# for ip in iprange("192.168.1.0/24")
# print ip
#
# The above statement will scan the class "C" subnet. You can also
# use wildcards, or specify a beginning and an end ip address
#
# Revision history
# 0.1 - Aug 17th 2004 : Initial release
#
#
# Todo : Add sanity checks to IP address
import socket
import struct
import re
class InvalidIPAddress(ValueError):
"""The ip address given to ipaddr is improperly formatted"""
def ipaddr_to_binary(ipaddr):
"""
A useful routine to convert a ipaddr string into a 32 bit long integer
"""
# from Greg Jorgensens python mailing list message
q = ipaddr.split('.')
return reduce(lambda a, b: long(a) * 256 + long(b), q)
def binary_to_ipaddr(ipbinary):
"""
Convert a 32-bit long integer into an ipaddr dotted-quad string
"""
# This one is from Rikard Bosnjakovic
return socket.inet_ntoa(struct.pack('!I', ipbinary))
def iprange(ipaddr):
"""
Creates a generator that iterates through all of the IP addresses.
The range can be specified in multiple formats.
"192.168.1.0-192.168.1.255" : beginning-end
"192.168.1.0/24" : CIDR
"192.168.1.*" : wildcard
"""
# Did we get the IP address in the span format?
span_re = re.compile(r'''(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The beginning IP Address
\s*-\s*
(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The end IP Address
''', re.VERBOSE)
res = span_re.match(ipaddr)
if res:
beginning = res.group(1)
end = res.group(2)
return span_iprange(beginning, end)
# Did we get the IP address in the CIDR format?
cidr_re = re.compile(r'''(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The IP Address
/(\d{1,2}) # The mask
''', re.VERBOSE)
res = cidr_re.match(ipaddr)
if res:
addr = res.group(1)
cidrmask = res.group(2)
return cidr_iprange(addr, cidrmask)
# Did we get the IP address in the wildcard format?
wild_re = re.compile(r'''(\d{1,3}|\*)\.
(\d{1,3}|\*)\.
(\d{1,3}|\*)\.
(\d{1,3}|\*) # The IP Address
''', re.VERBOSE)
res = wild_re.match(ipaddr)
if res:
return wildcard_iprange(ipaddr)
raise InvalidIPAddress
def span_iprange(beginning, end):
"""
Takes a begining and an end ipaddress and creates a generator
"""
b = ipaddr_to_binary(beginning)
e = ipaddr_to_binary(end)
while (b <= e):
yield binary_to_ipaddr(b)
b = b + 1
def cidr_iprange(ipaddr, cidrmask):
"""
Creates a generator that iterated through all of the IP addresses
in a range given in CIDR notation
"""
# Get all the binary one's
mask = (long(2) ** long(32 - long(cidrmask))) - 1
b = ipaddr_to_binary(ipaddr)
e = ipaddr_to_binary(ipaddr)
b = long(b & ~mask)
e = long(e | mask)
while (b <= e):
yield binary_to_ipaddr(b)
b = b + 1
def wildcard_iprange(ipaddr):
"""
Creates a generator that iterates through all of the IP address
in a range given with wild card notation
"""
beginning = []
end = []
tmp = ipaddr.split('.')
for i in tmp:
if i == '*':
beginning.append("0")
end.append("255")
else:
beginning.append(i)
end.append(i)
b = beginning[:]
e = end[:]
while int(b[0]) <= int(e[0]):
while int(b[1]) <= int(e[1]):
while int(b[2]) <= int(e[2]):
while int(b[3]) <= int(e[3]):
yield b[0] + '.' + b[1] + '.' + b[2] + '.' + b[3]
b[3] = "%d" % (int(b[3]) + 1)
b[2] = "%d" % (int(b[2]) + 1)
b[3] = beginning[3]
b[1] = "%d" % (int(b[1]) + 1)
b[2] = beginning[2]
b[0] = "%d" % (int(b[0]) + 1)
b[1] = beginning[1]
if __name__ == '__main__':
for ip in iprange("192.168.1.1-192.168.1.3"):
print ip
for ip in iprange("192.168.1.1/30"):
print ip
for ip in iprange("192.168.*.148"):
print ip
# Cause an exception
for ip in iprange("192.168./*.148"):
print ip
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment