Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/netaddr/ip/nmap.py: 12%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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
18def _nmap_octet_target_values(spec):
19 # Generates sequence of values for an individual octet as defined in the
20 # nmap Target Specification.
21 values = set()
23 for element in spec.split(','):
24 if '-' in element:
25 left, right = element.split('-', 1)
26 if not left:
27 left = 0
28 if not right:
29 right = 255
30 low = int(left)
31 high = int(right)
32 if not ((0 <= low <= 255) and (0 <= high <= 255)):
33 raise ValueError('octet value overflow for spec %s!' % (spec,))
34 if low > high:
35 raise ValueError('left side of hyphen must be <= right %r' % (element,))
36 for octet in range(low, high + 1):
37 values.add(octet)
38 else:
39 octet = int(element)
40 if not (0 <= octet <= 255):
41 raise ValueError('octet value overflow for spec %s!' % (spec,))
42 values.add(octet)
44 return sorted(values)
47def _generate_nmap_octet_ranges(nmap_target_spec):
48 # Generate 4 lists containing all octets defined by a given nmap Target
49 # specification.
50 if not isinstance(nmap_target_spec, str):
51 raise TypeError('string expected, not %s' % type(nmap_target_spec))
53 if not nmap_target_spec:
54 raise ValueError('nmap target specification cannot be blank!')
56 tokens = nmap_target_spec.split('.')
58 if len(tokens) != 4:
59 raise AddrFormatError('invalid nmap range: %s' % (nmap_target_spec,))
61 return (
62 _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]),
66 )
69def _parse_nmap_target_spec(target_spec):
70 if '/' in target_spec:
71 _, prefix = target_spec.split('/', 1)
72 if not (0 < int(prefix) < 33):
73 raise AddrFormatError('CIDR prefix expected, not %s' % (prefix,))
74 net = IPNetwork(target_spec)
75 if net.version != 4:
76 raise AddrFormatError('CIDR only support for IPv4!')
77 for ip in net:
78 yield ip
79 elif ':' in target_spec:
80 # nmap only currently supports IPv6 addresses without prefixes.
81 yield IPAddress(target_spec)
82 else:
83 octet_ranges = _generate_nmap_octet_ranges(target_spec)
84 for w in octet_ranges[0]:
85 for x in octet_ranges[1]:
86 for y in octet_ranges[2]:
87 for z in octet_ranges[3]:
88 yield IPAddress('%d.%d.%d.%d' % (w, x, y, z), 4)
91def valid_nmap_range(target_spec):
92 """
93 :param target_spec: an nmap-style IP range target specification.
95 :return: ``True`` if IP range target spec is valid, ``False`` otherwise.
96 """
97 try:
98 next(_parse_nmap_target_spec(target_spec))
99 return True
100 except (TypeError, ValueError, AddrFormatError):
101 pass
102 return False
105def iter_nmap_range(*nmap_target_spec):
106 """
107 An generator that yields IPAddress objects from defined by nmap target
108 specifications.
110 See https://nmap.org/book/man-target-specification.html for details.
112 :param nmap_target_spec: one or more nmap IP range target specification.
114 :return: an iterator producing IPAddress objects for each IP in the target spec(s).
115 """
116 for target_spec in nmap_target_spec:
117 for addr in _parse_nmap_target_spec(target_spec):
118 yield addr