netwatch.py/netaddr-0.7.10/netaddr/ip/nmap.py

102 lines
3.7 KiB
Python

#-----------------------------------------------------------------------------
# Copyright (c) 2008-2012, David P. D. Moss. All rights reserved.
#
# Released under the BSD license. See the LICENSE file for details.
#-----------------------------------------------------------------------------
"""
Routines for dealing with nmap-style IPv4 address ranges.
Based on nmap's Target Specification :-
http://nmap.org/book/man-target-specification.html
"""
from netaddr.core import AddrFormatError
from netaddr.ip import IPAddress
from netaddr.compat import _iter_range, _is_str
#-----------------------------------------------------------------------------
def _nmap_octet_target_values(spec):
# Generates sequence of values for an individual octet as defined in the
# nmap Target Specification.
values = set()
for element in spec.split(','):
if '-' in element:
left, right = element.split('-', 1)
if not left:
left = 0
if not right:
right = 255
low = int(left)
high = int(right)
if not ((0 <= low <= 255) and (0 <= high <= 255)):
raise ValueError('octet value overflow for spec %s!' % spec)
if low > high:
raise ValueError('left side of hyphen must be < right %r' % element)
for octet in _iter_range(low, high + 1):
values.add(octet)
else:
octet = int(element)
if not (0 <= octet <= 255):
raise ValueError('octet value overflow for spec %s!' % spec)
values.add(octet)
return sorted(values)
#-----------------------------------------------------------------------------
def _generate_nmap_octet_ranges(nmap_target_spec):
# Generate 4 lists containing all octets defined by a given nmap Target
# specification.
if not _is_str(nmap_target_spec):
raise TypeError('string expected, not %s' % type(nmap_target_spec))
if not nmap_target_spec:
raise ValueError('nmap target specification cannot be blank!')
tokens = nmap_target_spec.split('.')
if len(tokens) != 4:
raise AddrFormatError('invalid nmap range: %s' % nmap_target_spec)
if tokens[0] == '-':
raise AddrFormatError('first octet cannot be a sole hyphen!')
return (_nmap_octet_target_values(tokens[0]),
_nmap_octet_target_values(tokens[1]),
_nmap_octet_target_values(tokens[2]),
_nmap_octet_target_values(tokens[3]))
#-----------------------------------------------------------------------------
def valid_nmap_range(nmap_target_spec):
"""
:param nmap_target_spec: an nmap-style IP range target specification.
:return: ``True`` if IP range target spec is valid, ``False`` otherwise.
"""
try:
_generate_nmap_octet_ranges(nmap_target_spec)
return True
except (TypeError, ValueError, AddrFormatError):
pass
return False
#-----------------------------------------------------------------------------
def iter_nmap_range(nmap_target_spec):
"""
The nmap security tool supports a custom type of IPv4 range using multiple
hyphenated octets. This generator provides iterators yielding IP addresses
according to this rule set.
:param nmap_target_spec: an nmap-style IP range target specification.
:return: an iterator producing IPAddress objects for each IP in the range.
"""
octet_ranges = _generate_nmap_octet_ranges(nmap_target_spec)
for w in octet_ranges[0]:
for x in octet_ranges[1]:
for y in octet_ranges[2]:
for z in octet_ranges[3]:
yield IPAddress("%d.%d.%d.%d" % (w, x, y, z))