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

64 statements  

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. 

8 

9Based on nmap's Target Specification :- 

10 

11 http://nmap.org/book/man-target-specification.html 

12""" 

13 

14from netaddr.core import AddrFormatError 

15from netaddr.ip import IPAddress, IPNetwork 

16 

17 

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() 

22 

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) 

43 

44 return sorted(values) 

45 

46 

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)) 

52 

53 if not nmap_target_spec: 

54 raise ValueError('nmap target specification cannot be blank!') 

55 

56 tokens = nmap_target_spec.split('.') 

57 

58 if len(tokens) != 4: 

59 raise AddrFormatError('invalid nmap range: %s' % (nmap_target_spec,)) 

60 

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 ) 

67 

68 

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) 

89 

90 

91def valid_nmap_range(target_spec): 

92 """ 

93 :param target_spec: an nmap-style IP range target specification. 

94 

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 

103 

104 

105def iter_nmap_range(*nmap_target_spec): 

106 """ 

107 An generator that yields IPAddress objects from defined by nmap target 

108 specifications. 

109 

110 See https://nmap.org/book/man-target-specification.html for details. 

111 

112 :param nmap_target_spec: one or more nmap IP range target specification. 

113 

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