# -----------------------------------------------------------------------------# Copyright (c) 2008 by 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"""fromnetaddr.coreimportAddrFormatErrorfromnetaddr.ipimportIPAddress,IPNetworkdef_nmap_octet_target_values(spec):# Generates sequence of values for an individual octet as defined in the# nmap Target Specification.values=set()forelementinspec.split(','):if'-'inelement:left,right=element.split('-',1)ifnotleft:left=0ifnotright:right=255low=int(left)high=int(right)ifnot((0<=low<=255)and(0<=high<=255)):raiseValueError('octet value overflow for spec %s!'%(spec,))iflow>high:raiseValueError('left side of hyphen must be <= right %r'%(element,))foroctetinrange(low,high+1):values.add(octet)else:octet=int(element)ifnot(0<=octet<=255):raiseValueError('octet value overflow for spec %s!'%(spec,))values.add(octet)returnsorted(values)def_generate_nmap_octet_ranges(nmap_target_spec):# Generate 4 lists containing all octets defined by a given nmap Target# specification.ifnotisinstance(nmap_target_spec,str):raiseTypeError('string expected, not %s'%type(nmap_target_spec))ifnotnmap_target_spec:raiseValueError('nmap target specification cannot be blank!')tokens=nmap_target_spec.split('.')iflen(tokens)!=4:raiseAddrFormatError('invalid nmap range: %s'%(nmap_target_spec,))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_parse_nmap_target_spec(target_spec):if'/'intarget_spec:_,prefix=target_spec.split('/',1)ifnot(0<int(prefix)<33):raiseAddrFormatError('CIDR prefix expected, not %s'%(prefix,))net=IPNetwork(target_spec)ifnet.version!=4:raiseAddrFormatError('CIDR only support for IPv4!')foripinnet:yieldipelif':'intarget_spec:# nmap only currently supports IPv6 addresses without prefixes.yieldIPAddress(target_spec)else:octet_ranges=_generate_nmap_octet_ranges(target_spec)forwinoctet_ranges[0]:forxinoctet_ranges[1]:foryinoctet_ranges[2]:forzinoctet_ranges[3]:yieldIPAddress('%d.%d.%d.%d'%(w,x,y,z),4)
[docs]defvalid_nmap_range(target_spec):""" :param target_spec: an nmap-style IP range target specification. :return: ``True`` if IP range target spec is valid, ``False`` otherwise. """try:next(_parse_nmap_target_spec(target_spec))returnTrueexcept(TypeError,ValueError,AddrFormatError):passreturnFalse
[docs]defiter_nmap_range(*nmap_target_spec):""" An generator that yields IPAddress objects from defined by nmap target specifications. See https://nmap.org/book/man-target-specification.html for details. :param nmap_target_spec: one or more nmap IP range target specification. :return: an iterator producing IPAddress objects for each IP in the target spec(s). """fortarget_specinnmap_target_spec:foraddrin_parse_nmap_target_spec(target_spec):yieldaddr