Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/netaddr/ip/nmap.py: 14%
64 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:45 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:45 +0000
1#-----------------------------------------------------------------------------
2# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
3#
4# Released under the BSD license. See the LICENSE file for details.
5#-----------------------------------------------------------------------------
6"""
7Routines for dealing with nmap-style IPv4 address ranges.
9Based on nmap's Target Specification :-
11 http://nmap.org/book/man-target-specification.html
12"""
14from netaddr.core import AddrFormatError
15from netaddr.ip import IPAddress, IPNetwork
16from netaddr.compat import _iter_range, _is_str, _iter_next
19def _nmap_octet_target_values(spec):
20 # Generates sequence of values for an individual octet as defined in the
21 # nmap Target Specification.
22 values = set()
24 for element in spec.split(','):
25 if '-' in element:
26 left, right = element.split('-', 1)
27 if not left:
28 left = 0
29 if not right:
30 right = 255
31 low = int(left)
32 high = int(right)
33 if not ((0 <= low <= 255) and (0 <= high <= 255)):
34 raise ValueError('octet value overflow for spec %s!' % (spec,))
35 if low > high:
36 raise ValueError('left side of hyphen must be <= right %r' % (element,))
37 for octet in _iter_range(low, high + 1):
38 values.add(octet)
39 else:
40 octet = int(element)
41 if not (0 <= octet <= 255):
42 raise ValueError('octet value overflow for spec %s!' % (spec,))
43 values.add(octet)
45 return sorted(values)
48def _generate_nmap_octet_ranges(nmap_target_spec):
49 # Generate 4 lists containing all octets defined by a given nmap Target
50 # specification.
51 if not _is_str(nmap_target_spec):
52 raise TypeError('string expected, not %s' % type(nmap_target_spec))
54 if not nmap_target_spec:
55 raise ValueError('nmap target specification cannot be blank!')
57 tokens = nmap_target_spec.split('.')
59 if len(tokens) != 4:
60 raise AddrFormatError('invalid nmap range: %s' % (nmap_target_spec,))
62 return (_nmap_octet_target_values(tokens[0]),
63 _nmap_octet_target_values(tokens[1]),
64 _nmap_octet_target_values(tokens[2]),
65 _nmap_octet_target_values(tokens[3]))
68def _parse_nmap_target_spec(target_spec):
69 if '/' in target_spec:
70 _, prefix = target_spec.split('/', 1)
71 if not (0 < int(prefix) < 33):
72 raise AddrFormatError('CIDR prefix expected, not %s' % (prefix,))
73 net = IPNetwork(target_spec)
74 if net.version != 4:
75 raise AddrFormatError('CIDR only support for IPv4!')
76 for ip in net:
77 yield ip
78 elif ':' in target_spec:
79 # nmap only currently supports IPv6 addresses without prefixes.
80 yield IPAddress(target_spec)
81 else:
82 octet_ranges = _generate_nmap_octet_ranges(target_spec)
83 for w in octet_ranges[0]:
84 for x in octet_ranges[1]:
85 for y in octet_ranges[2]:
86 for z in octet_ranges[3]:
87 yield IPAddress("%d.%d.%d.%d" % (w, x, y, z), 4)
90def valid_nmap_range(target_spec):
91 """
92 :param target_spec: an nmap-style IP range target specification.
94 :return: ``True`` if IP range target spec is valid, ``False`` otherwise.
95 """
96 try:
97 _iter_next(_parse_nmap_target_spec(target_spec))
98 return True
99 except (TypeError, ValueError, AddrFormatError):
100 pass
101 return False
104def iter_nmap_range(*nmap_target_spec):
105 """
106 An generator that yields IPAddress objects from defined by nmap target
107 specifications.
109 See https://nmap.org/book/man-target-specification.html for details.
111 :param *nmap_target_spec: one or more nmap IP range target specification.
113 :return: an iterator producing IPAddress objects for each IP in the target spec(s).
114 """
115 for target_spec in nmap_target_spec:
116 for addr in _parse_nmap_target_spec(target_spec):
117 yield addr