Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/netaddr/ip/__init__.py: 29%

849 statements  

« 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"""Routines for IPv4 and IPv6 addresses, subnets and ranges.""" 

7 

8import sys as _sys 

9 

10from netaddr.core import AddrFormatError, AddrConversionError, num_bits, \ 

11 DictDotLookup, NOHOST, N, INET_PTON, P, ZEROFILL, Z 

12 

13from netaddr.strategy import ipv4 as _ipv4, ipv6 as _ipv6 

14 

15from netaddr.compat import _sys_maxint, _iter_next, _iter_range, _is_str, _int_type, \ 

16 _str_type 

17 

18 

19class BaseIP(object): 

20 """ 

21 An abstract base class for common operations shared between various IP 

22 related subclasses. 

23 

24 """ 

25 __slots__ = ('_value', '_module', '__weakref__') 

26 

27 def __init__(self): 

28 """Constructor.""" 

29 self._value = None 

30 self._module = None 

31 

32 def _set_value(self, value): 

33 if not isinstance(value, _int_type): 

34 raise TypeError('int argument expected, not %s' % type(value)) 

35 if not 0 <= value <= self._module.max_int: 

36 raise AddrFormatError('value out of bounds for an %s address!' \ 

37 % self._module.family_name) 

38 self._value = value 

39 

40 value = property(lambda self: self._value, _set_value, 

41 doc='a positive integer representing the value of IP address/subnet.') 

42 

43 def key(self): 

44 """ 

45 :return: a key tuple that uniquely identifies this IP address. 

46 """ 

47 return NotImplemented 

48 

49 def sort_key(self): 

50 """ 

51 :return: A key tuple used to compare and sort this `IPAddress` 

52 correctly. 

53 """ 

54 return NotImplemented 

55 

56 def __hash__(self): 

57 """ 

58 :return: A hash value uniquely indentifying this IP object. 

59 """ 

60 return hash(self.key()) 

61 

62 def __eq__(self, other): 

63 """ 

64 :param other: an `IPAddress` or `IPNetwork` object. 

65 

66 :return: ``True`` if this `IPAddress` or `IPNetwork` object is 

67 equivalent to ``other``, ``False`` otherwise. 

68 """ 

69 try: 

70 return self.key() == other.key() 

71 except (AttributeError, TypeError): 

72 return NotImplemented 

73 

74 def __ne__(self, other): 

75 """ 

76 :param other: an `IPAddress` or `IPNetwork` object. 

77 

78 :return: ``True`` if this `IPAddress` or `IPNetwork` object is 

79 not equivalent to ``other``, ``False`` otherwise. 

80 """ 

81 try: 

82 return self.key() != other.key() 

83 except (AttributeError, TypeError): 

84 return NotImplemented 

85 

86 def __lt__(self, other): 

87 """ 

88 :param other: an `IPAddress` or `IPNetwork` object. 

89 

90 :return: ``True`` if this `IPAddress` or `IPNetwork` object is 

91 less than ``other``, ``False`` otherwise. 

92 """ 

93 try: 

94 return self.sort_key() < other.sort_key() 

95 except (AttributeError, TypeError): 

96 return NotImplemented 

97 

98 def __le__(self, other): 

99 """ 

100 :param other: an `IPAddress` or `IPNetwork` object. 

101 

102 :return: ``True`` if this `IPAddress` or `IPNetwork` object is 

103 less than or equal to ``other``, ``False`` otherwise. 

104 """ 

105 try: 

106 return self.sort_key() <= other.sort_key() 

107 except (AttributeError, TypeError): 

108 return NotImplemented 

109 

110 def __gt__(self, other): 

111 """ 

112 :param other: an `IPAddress` or `IPNetwork` object. 

113 

114 :return: ``True`` if this `IPAddress` or `IPNetwork` object is 

115 greater than ``other``, ``False`` otherwise. 

116 """ 

117 try: 

118 return self.sort_key() > other.sort_key() 

119 except (AttributeError, TypeError): 

120 return NotImplemented 

121 

122 def __ge__(self, other): 

123 """ 

124 :param other: an `IPAddress` or `IPNetwork` object. 

125 

126 :return: ``True`` if this `IPAddress` or `IPNetwork` object is 

127 greater than or equal to ``other``, ``False`` otherwise. 

128 """ 

129 try: 

130 return self.sort_key() >= other.sort_key() 

131 except (AttributeError, TypeError): 

132 return NotImplemented 

133 

134 def is_unicast(self): 

135 """:return: ``True`` if this IP is unicast, ``False`` otherwise""" 

136 return not self.is_multicast() 

137 

138 def is_multicast(self): 

139 """:return: ``True`` if this IP is multicast, ``False`` otherwise""" 

140 if self._module == _ipv4: 

141 return self in IPV4_MULTICAST 

142 elif self._module == _ipv6: 

143 return self in IPV6_MULTICAST 

144 

145 def is_loopback(self): 

146 """ 

147 :return: ``True`` if this IP is loopback address (not for network 

148 transmission), ``False`` otherwise. 

149 References: RFC 3330 and 4291. 

150 """ 

151 if self._module.version == 4: 

152 return self in IPV4_LOOPBACK 

153 elif self._module.version == 6: 

154 return self in IPV6_LOOPBACK 

155 

156 def is_private(self): 

157 """ 

158 :return: ``True`` if this IP is for internal/private use only 

159 (i.e. non-public), ``False`` otherwise. Reference: RFCs 1918, 

160 3330, 4193, 3879 and 2365. 

161 """ 

162 if self._module.version == 4: 

163 for cidr in IPV4_PRIVATE: 

164 if self in cidr: 

165 return True 

166 elif self._module.version == 6: 

167 for cidr in IPV6_PRIVATE: 

168 if self in cidr: 

169 return True 

170 

171 if self.is_link_local(): 

172 return True 

173 

174 return False 

175 

176 def is_link_local(self): 

177 """ 

178 :return: ``True`` if this IP is link-local address ``False`` otherwise. 

179 Reference: RFCs 3927 and 4291. 

180 """ 

181 if self._module.version == 4: 

182 return self in IPV4_LINK_LOCAL 

183 elif self._module.version == 6: 

184 return self in IPV6_LINK_LOCAL 

185 

186 def is_reserved(self): 

187 """ 

188 :return: ``True`` if this IP is in IANA reserved range, ``False`` 

189 otherwise. Reference: RFCs 3330 and 3171. 

190 """ 

191 if self._module.version == 4: 

192 for cidr in IPV4_RESERVED: 

193 if self in cidr: 

194 return True 

195 elif self._module.version == 6: 

196 for cidr in IPV6_RESERVED: 

197 if self in cidr: 

198 return True 

199 return False 

200 

201 def is_ipv4_mapped(self): 

202 """ 

203 :return: ``True`` if this IP is IPv4-compatible IPv6 address, ``False`` 

204 otherwise. 

205 """ 

206 return self._module.version == 6 and (self._value >> 32) == 0xffff 

207 

208 def is_ipv4_compat(self): 

209 """ 

210 :return: ``True`` if this IP is IPv4-mapped IPv6 address, ``False`` 

211 otherwise. 

212 """ 

213 return self._module.version == 6 and (self._value >> 32) == 0 

214 

215 @property 

216 def info(self): 

217 """ 

218 A record dict containing IANA registration details for this IP address 

219 if available, None otherwise. 

220 """ 

221 # Lazy loading of IANA data structures. 

222 from netaddr.ip.iana import query 

223 return DictDotLookup(query(self)) 

224 

225 @property 

226 def version(self): 

227 """the IP protocol version represented by this IP object.""" 

228 return self._module.version 

229 

230 

231class IPAddress(BaseIP): 

232 """ 

233 An individual IPv4 or IPv6 address without a net mask or subnet prefix. 

234 

235 To support these and other network based operations, see `IPNetwork`. 

236 

237 """ 

238 __slots__ = () 

239 

240 def __init__(self, addr, version=None, flags=0): 

241 """ 

242 Constructor. 

243 

244 :param addr: an IPv4 or IPv6 address which may be represented in an 

245 accepted string format, as an unsigned integer or as another 

246 IPAddress object (copy construction). 

247 

248 :param version: (optional) optimizes version detection if specified 

249 and distinguishes between IPv4 and IPv6 for addresses with an 

250 equivalent integer value. 

251 

252 :param flags: (optional) decides which rules are applied to the 

253 interpretation of the addr value. Supported constants are 

254 INET_PTON and ZEROFILL. See the netaddr.core docs for further 

255 details. 

256 

257 """ 

258 super(IPAddress, self).__init__() 

259 

260 if isinstance(addr, BaseIP): 

261 # Copy constructor. 

262 if version is not None and version != addr._module.version: 

263 raise ValueError('cannot switch IP versions using ' 

264 'copy constructor!') 

265 self._value = addr._value 

266 self._module = addr._module 

267 else: 

268 # Explicit IP address version. 

269 if version is not None: 

270 if version == 4: 

271 self._module = _ipv4 

272 elif version == 6: 

273 self._module = _ipv6 

274 else: 

275 raise ValueError('%r is an invalid IP version!' % version) 

276 

277 if _is_str(addr) and '/' in addr: 

278 raise ValueError('%s() does not support netmasks or subnet' \ 

279 ' prefixes! See documentation for details.' 

280 % self.__class__.__name__) 

281 

282 if self._module is None: 

283 # IP version is implicit, detect it from addr. 

284 if isinstance(addr, _int_type): 

285 try: 

286 if 0 <= int(addr) <= _ipv4.max_int: 

287 self._value = int(addr) 

288 self._module = _ipv4 

289 elif _ipv4.max_int < int(addr) <= _ipv6.max_int: 

290 self._value = int(addr) 

291 self._module = _ipv6 

292 except ValueError: 

293 pass 

294 else: 

295 for module in _ipv4, _ipv6: 

296 try: 

297 self._value = module.str_to_int(addr, flags) 

298 except: 

299 continue 

300 else: 

301 self._module = module 

302 break 

303 

304 if self._module is None: 

305 raise AddrFormatError('failed to detect a valid IP ' \ 

306 'address from %r' % addr) 

307 else: 

308 # IP version is explicit. 

309 if _is_str(addr): 

310 try: 

311 self._value = self._module.str_to_int(addr, flags) 

312 except AddrFormatError: 

313 raise AddrFormatError('base address %r is not IPv%d' 

314 % (addr, self._module.version)) 

315 else: 

316 if 0 <= int(addr) <= self._module.max_int: 

317 self._value = int(addr) 

318 else: 

319 raise AddrFormatError('bad address format: %r' % (addr,)) 

320 

321 def __getstate__(self): 

322 """:returns: Pickled state of an `IPAddress` object.""" 

323 return self._value, self._module.version 

324 

325 def __setstate__(self, state): 

326 """ 

327 :param state: data used to unpickle a pickled `IPAddress` object. 

328 

329 """ 

330 value, version = state 

331 

332 self._value = value 

333 

334 if version == 4: 

335 self._module = _ipv4 

336 elif version == 6: 

337 self._module = _ipv6 

338 else: 

339 raise ValueError('unpickling failed for object state: %s' \ 

340 % str(state)) 

341 

342 def netmask_bits(self): 

343 """ 

344 @return: If this IP is a valid netmask, the number of non-zero 

345 bits are returned, otherwise it returns the width in bits for 

346 the IP address version. 

347 """ 

348 if not self.is_netmask(): 

349 return self._module.width 

350 

351 # the '0' address (e.g. 0.0.0.0 or 0000::) is a valid netmask with 

352 # no bits set. 

353 if self._value == 0: 

354 return 0 

355 

356 i_val = self._value 

357 numbits = 0 

358 

359 while i_val > 0: 

360 if i_val & 1 == 1: 

361 break 

362 numbits += 1 

363 i_val >>= 1 

364 

365 mask_length = self._module.width - numbits 

366 

367 if not 0 <= mask_length <= self._module.width: 

368 raise ValueError('Unexpected mask length %d for address type!' \ 

369 % mask_length) 

370 

371 return mask_length 

372 

373 def is_hostmask(self): 

374 """ 

375 :return: ``True`` if this IP address host mask, ``False`` otherwise. 

376 """ 

377 int_val = self._value + 1 

378 return (int_val & (int_val - 1) == 0) 

379 

380 def is_netmask(self): 

381 """ 

382 :return: ``True`` if this IP address network mask, ``False`` otherwise. 

383 """ 

384 int_val = (self._value ^ self._module.max_int) + 1 

385 return (int_val & (int_val - 1) == 0) 

386 

387 def __iadd__(self, num): 

388 """ 

389 Increases the numerical value of this IPAddress by num. 

390 

391 An IndexError is raised if result exceeds maximum IP address value or 

392 is less than zero. 

393 

394 :param num: size of IP address increment. 

395 """ 

396 new_value = int(self._value + num) 

397 if 0 <= new_value <= self._module.max_int: 

398 self._value = new_value 

399 return self 

400 raise IndexError('result outside valid IP address boundary!') 

401 

402 def __isub__(self, num): 

403 """ 

404 Decreases the numerical value of this IPAddress by num. 

405 

406 An IndexError is raised if result is less than zero or exceeds maximum 

407 IP address value. 

408 

409 :param num: size of IP address decrement. 

410 """ 

411 new_value = int(self._value - num) 

412 if 0 <= new_value <= self._module.max_int: 

413 self._value = new_value 

414 return self 

415 raise IndexError('result outside valid IP address boundary!') 

416 

417 def __add__(self, num): 

418 """ 

419 Add the numerical value of this IP address to num and provide the 

420 result as a new IPAddress object. 

421 

422 :param num: size of IP address increase. 

423 

424 :return: a new IPAddress object with its numerical value increased by num. 

425 """ 

426 new_value = int(self._value + num) 

427 if 0 <= new_value <= self._module.max_int: 

428 return self.__class__(new_value, self._module.version) 

429 raise IndexError('result outside valid IP address boundary!') 

430 

431 __radd__ = __add__ 

432 

433 def __sub__(self, num): 

434 """ 

435 Subtract the numerical value of this IP address from num providing 

436 the result as a new IPAddress object. 

437 

438 :param num: size of IP address decrease. 

439 

440 :return: a new IPAddress object with its numerical value decreased by num. 

441 """ 

442 new_value = int(self._value - num) 

443 if 0 <= new_value <= self._module.max_int: 

444 return self.__class__(new_value, self._module.version) 

445 raise IndexError('result outside valid IP address boundary!') 

446 

447 def __rsub__(self, num): 

448 """ 

449 Subtract num (lvalue) from the numerical value of this IP address 

450 (rvalue) providing the result as a new IPAddress object. 

451 

452 :param num: size of IP address decrease. 

453 

454 :return: a new IPAddress object with its numerical value decreased by num. 

455 """ 

456 new_value = int(num - self._value) 

457 if 0 <= new_value <= self._module.max_int: 

458 return self.__class__(new_value, self._module.version) 

459 raise IndexError('result outside valid IP address boundary!') 

460 

461 def key(self): 

462 """ 

463 :return: a key tuple that uniquely identifies this IP address. 

464 """ 

465 # NB - we return the value here twice because this IP Address may 

466 # be sorted with a list of networks and it should still end up 

467 # in the expected order. 

468 return self._module.version, self._value 

469 

470 def sort_key(self): 

471 """:return: A key tuple used to compare and sort this `IPAddress` correctly.""" 

472 return self._module.version, self._value, self._module.width 

473 

474 def __int__(self): 

475 """:return: the value of this IP address as an unsigned integer""" 

476 return self._value 

477 

478 def __long__(self): 

479 """:return: the value of this IP address as an unsigned integer""" 

480 return self._value 

481 

482 def __oct__(self): 

483 """:return: an octal string representation of this IP address.""" 

484 # Python 2.x 

485 if self._value == 0: 

486 return '0' 

487 return '0%o' % self._value 

488 

489 def __hex__(self): 

490 """:return: a hexadecimal string representation of this IP address.""" 

491 # Python 2.x 

492 return '0x%x' % self._value 

493 

494 def __index__(self): 

495 """ 

496 :return: return the integer value of this IP address when called by \ 

497 hex(), oct() or bin(). 

498 """ 

499 # Python 3.x 

500 return self._value 

501 

502 def __bytes__(self): 

503 """  

504 :return: a bytes object equivalent to this IP address. In network 

505 byte order, big-endian. 

506 """ 

507 # Python 3.x 

508 return self._value.to_bytes(self._module.width//8, 'big') 

509 

510 def bits(self, word_sep=None): 

511 """ 

512 :param word_sep: (optional) the separator to insert between words. 

513 Default: None - use default separator for address type. 

514 

515 :return: the value of this IP address as a binary digit string.""" 

516 return self._module.int_to_bits(self._value, word_sep) 

517 

518 @property 

519 def packed(self): 

520 """The value of this IP address as a packed binary string.""" 

521 return self._module.int_to_packed(self._value) 

522 

523 @property 

524 def words(self): 

525 """ 

526 A list of unsigned integer words (octets for IPv4, hextets for IPv6) 

527 found in this IP address. 

528 """ 

529 return self._module.int_to_words(self._value) 

530 

531 @property 

532 def bin(self): 

533 """ 

534 The value of this IP adddress in standard Python binary 

535 representational form (0bxxx). A back port of the format provided by 

536 the builtin bin() function found in Python 2.6.x and higher. 

537 """ 

538 return self._module.int_to_bin(self._value) 

539 

540 @property 

541 def reverse_dns(self): 

542 """The reverse DNS lookup record for this IP address""" 

543 return self._module.int_to_arpa(self._value) 

544 

545 def ipv4(self): 

546 """ 

547 Raises an `AddrConversionError` if IPv6 address cannot be converted 

548 to IPv4. 

549 

550 :return: A numerically equivalent version 4 `IPAddress` object. 

551 """ 

552 ip = None 

553 klass = self.__class__ 

554 

555 if self._module.version == 4: 

556 ip = klass(self._value, 4) 

557 elif self._module.version == 6: 

558 if 0 <= self._value <= _ipv4.max_int: 

559 ip = klass(self._value, 4) 

560 elif _ipv4.max_int <= self._value <= 0xffffffffffff: 

561 ip = klass(self._value - 0xffff00000000, 4) 

562 else: 

563 raise AddrConversionError('IPv6 address %s unsuitable for ' \ 

564 'conversion to IPv4!' % self) 

565 return ip 

566 

567 def ipv6(self, ipv4_compatible=False): 

568 """ 

569 .. note:: The IPv4-mapped IPv6 address format is now considered \ 

570 deprecated. See RFC 4291 or later for details. 

571 

572 :param ipv4_compatible: If ``True`` returns an IPv4-mapped address 

573 (::ffff:x.x.x.x), an IPv4-compatible (::x.x.x.x) address 

574 otherwise. Default: False (IPv4-mapped). 

575 

576 :return: A numerically equivalent version 6 `IPAddress` object. 

577 """ 

578 ip = None 

579 klass = self.__class__ 

580 

581 if self._module.version == 6: 

582 if ipv4_compatible and \ 

583 (0xffff00000000 <= self._value <= 0xffffffffffff): 

584 ip = klass(self._value - 0xffff00000000, 6) 

585 else: 

586 ip = klass(self._value, 6) 

587 elif self._module.version == 4: 

588 # IPv4-Compatible IPv6 address 

589 ip = klass(self._value, 6) 

590 if not ipv4_compatible: 

591 # IPv4-Mapped IPv6 address 

592 ip = klass(0xffff00000000 + self._value, 6) 

593 

594 return ip 

595 

596 def format(self, dialect=None): 

597 """ 

598 Only relevant for IPv6 addresses. Has no effect for IPv4. 

599 

600 :param dialect: An ipv6_* dialect class. 

601 

602 :return: an alternate string representation for this IP address. 

603 """ 

604 if dialect is not None: 

605 if not hasattr(dialect, 'word_fmt'): 

606 raise TypeError( 

607 'custom dialects should subclass ipv6_verbose!') 

608 return self._module.int_to_str(self._value, dialect=dialect) 

609 

610 def __or__(self, other): 

611 """ 

612 :param other: An `IPAddress` object (or other int-like object). 

613 

614 :return: bitwise OR (x | y) between the integer value of this IP 

615 address and ``other``. 

616 """ 

617 return self.__class__(self._value | int(other), self._module.version) 

618 

619 def __and__(self, other): 

620 """ 

621 :param other: An `IPAddress` object (or other int-like object). 

622 

623 :return: bitwise AND (x & y) between the integer value of this IP 

624 address and ``other``. 

625 """ 

626 return self.__class__(self._value & int(other), self._module.version) 

627 

628 def __xor__(self, other): 

629 """ 

630 :param other: An `IPAddress` object (or other int-like object). 

631 

632 :return: bitwise exclusive OR (x ^ y) between the integer value of 

633 this IP address and ``other``. 

634 """ 

635 return self.__class__(self._value ^ int(other), self._module.version) 

636 

637 def __lshift__(self, numbits): 

638 """ 

639 :param numbits: size of bitwise shift. 

640 

641 :return: an `IPAddress` object based on this one with its integer 

642 value left shifted by ``numbits``. 

643 """ 

644 return self.__class__(self._value << numbits, self._module.version) 

645 

646 def __rshift__(self, numbits): 

647 """ 

648 :param numbits: size of bitwise shift. 

649 

650 :return: an `IPAddress` object based on this one with its integer 

651 value right shifted by ``numbits``. 

652 """ 

653 return self.__class__(self._value >> numbits, self._module.version) 

654 

655 def __nonzero__(self): 

656 """:return: ``True`` if the numerical value of this IP address is not \ 

657 zero, ``False`` otherwise.""" 

658 # Python 2.x. 

659 return bool(self._value) 

660 

661 __bool__ = __nonzero__ # Python 3.x. 

662 

663 def __str__(self): 

664 """:return: IP address in presentational format""" 

665 return self._module.int_to_str(self._value) 

666 

667 def __repr__(self): 

668 """:return: Python statement to create an equivalent object""" 

669 return "%s('%s')" % (self.__class__.__name__, self) 

670 

671 

672class IPListMixin(object): 

673 """ 

674 A mixin class providing shared list-like functionality to classes 

675 representing groups of IP addresses. 

676 

677 """ 

678 __slots__ = () 

679 def __iter__(self): 

680 """ 

681 :return: An iterator providing access to all `IPAddress` objects 

682 within range represented by this ranged IP object. 

683 """ 

684 start_ip = IPAddress(self.first, self._module.version) 

685 end_ip = IPAddress(self.last, self._module.version) 

686 return iter_iprange(start_ip, end_ip) 

687 

688 @property 

689 def size(self): 

690 """ 

691 The total number of IP addresses within this ranged IP object. 

692 """ 

693 return int(self.last - self.first + 1) 

694 

695 def __len__(self): 

696 """ 

697 :return: the number of IP addresses in this ranged IP object. Raises 

698 an `IndexError` if size > system max int (a Python 2.x 

699 limitation). Use the .size property for subnets of any size. 

700 """ 

701 size = self.size 

702 if size > _sys_maxint: 

703 raise IndexError(("range contains more than %d (sys.maxint) " 

704 "IP addresses! Use the .size property instead." % _sys_maxint)) 

705 return size 

706 

707 def __getitem__(self, index): 

708 """ 

709 :return: The IP address(es) in this `IPNetwork` object referenced by 

710 index or slice. As slicing can produce large sequences of objects 

711 an iterator is returned instead of the more usual `list`. 

712 """ 

713 item = None 

714 

715 if hasattr(index, 'indices'): 

716 if self._module.version == 6: 

717 raise TypeError('IPv6 slices are not supported!') 

718 

719 (start, stop, step) = index.indices(self.size) 

720 

721 if (start + step < 0) or (step > stop): 

722 # step value exceeds start and stop boundaries. 

723 item = iter([IPAddress(self.first, self._module.version)]) 

724 else: 

725 start_ip = IPAddress(self.first + start, self._module.version) 

726 end_ip = IPAddress(self.first + stop - step, self._module.version) 

727 item = iter_iprange(start_ip, end_ip, step) 

728 else: 

729 try: 

730 index = int(index) 

731 if (- self.size) <= index < 0: 

732 # negative index. 

733 item = IPAddress(self.last + index + 1, self._module.version) 

734 elif 0 <= index <= (self.size - 1): 

735 # Positive index or zero index. 

736 item = IPAddress(self.first + index, self._module.version) 

737 else: 

738 raise IndexError('index out range for address range size!') 

739 except ValueError: 

740 raise TypeError('unsupported index type %r!' % index) 

741 

742 return item 

743 

744 def __contains__(self, other): 

745 """ 

746 :param other: an `IPAddress` or ranged IP object. 

747 

748 :return: ``True`` if other falls within the boundary of this one, 

749 ``False`` otherwise. 

750 """ 

751 if isinstance(other, BaseIP): 

752 if self._module.version != other._module.version: 

753 return False 

754 if isinstance(other, IPAddress): 

755 return other._value >= self.first and other._value <= self.last 

756 # Assume that we (and the other) provide .first and .last. 

757 return other.first >= self.first and other.last <= self.last 

758 

759 # Whatever it is, try to interpret it as IPAddress. 

760 return IPAddress(other) in self 

761 

762 def __nonzero__(self): 

763 """ 

764 Ranged IP objects always represent a sequence of at least one IP 

765 address and are therefore always True in the boolean context. 

766 """ 

767 # Python 2.x. 

768 return True 

769 

770 __bool__ = __nonzero__ # Python 3.x. 

771 

772 

773def parse_ip_network(module, addr, implicit_prefix=False, flags=0): 

774 if isinstance(addr, tuple): 

775 # CIDR integer tuple 

776 if len(addr) != 2: 

777 raise AddrFormatError('invalid %s tuple!' % module.family_name) 

778 value, prefixlen = addr 

779 

780 if not(0 <= value <= module.max_int): 

781 raise AddrFormatError('invalid address value for %s tuple!' 

782 % module.family_name) 

783 if not(0 <= prefixlen <= module.width): 

784 raise AddrFormatError('invalid prefix for %s tuple!' \ 

785 % module.family_name) 

786 elif isinstance(addr, _str_type): 

787 # CIDR-like string subnet 

788 if implicit_prefix: 

789 #TODO: deprecate this option in netaddr 0.8.x 

790 addr = cidr_abbrev_to_verbose(addr) 

791 

792 if '/' in addr: 

793 val1, val2 = addr.split('/', 1) 

794 else: 

795 val1 = addr 

796 val2 = None 

797 

798 try: 

799 ip = IPAddress(val1, module.version, flags=INET_PTON) 

800 except AddrFormatError: 

801 if module.version == 4: 

802 # Try a partial IPv4 network address... 

803 expanded_addr = _ipv4.expand_partial_address(val1) 

804 ip = IPAddress(expanded_addr, module.version, flags=INET_PTON) 

805 else: 

806 raise AddrFormatError('invalid IPNetwork address %s!' % addr) 

807 value = ip._value 

808 

809 try: 

810 # Integer CIDR prefix. 

811 prefixlen = int(val2) 

812 except TypeError: 

813 if val2 is None: 

814 # No prefix was specified. 

815 prefixlen = module.width 

816 except ValueError: 

817 # Not an integer prefix, try a netmask/hostmask prefix. 

818 mask = IPAddress(val2, module.version, flags=INET_PTON) 

819 if mask.is_netmask(): 

820 prefixlen = module.netmask_to_prefix[mask._value] 

821 elif mask.is_hostmask(): 

822 prefixlen = module.hostmask_to_prefix[mask._value] 

823 else: 

824 raise AddrFormatError('addr %r is not a valid IPNetwork!' \ 

825 % addr) 

826 

827 if not 0 <= prefixlen <= module.width: 

828 raise AddrFormatError('invalid prefix for %s address!' \ 

829 % module.family_name) 

830 else: 

831 raise TypeError('unexpected type %s for addr arg' % type(addr)) 

832 

833 if flags & NOHOST: 

834 # Remove host bits. 

835 netmask = module.prefix_to_netmask[prefixlen] 

836 value = value & netmask 

837 

838 return value, prefixlen 

839 

840 

841class IPNetwork(BaseIP, IPListMixin): 

842 """ 

843 An IPv4 or IPv6 network or subnet. 

844 

845 A combination of an IP address and a network mask. 

846 

847 Accepts CIDR and several related variants : 

848 

849 a) Standard CIDR:: 

850 

851 x.x.x.x/y -> 192.0.2.0/24 

852 x::/y -> fe80::/10 

853 

854 b) Hybrid CIDR format (netmask address instead of prefix), where 'y' \ 

855 address represent a valid netmask:: 

856 

857 x.x.x.x/y.y.y.y -> 192.0.2.0/255.255.255.0 

858 x::/y:: -> fe80::/ffc0:: 

859 

860 c) ACL hybrid CIDR format (hostmask address instead of prefix like \ 

861 Cisco's ACL bitmasks), where 'y' address represent a valid netmask:: 

862 

863 x.x.x.x/y.y.y.y -> 192.0.2.0/0.0.0.255 

864 x::/y:: -> fe80::/3f:ffff:ffff:ffff:ffff:ffff:ffff:ffff 

865 

866 d) Abbreviated CIDR format (as of netaddr 0.7.x this requires the \ 

867 optional constructor argument ``implicit_prefix=True``):: 

868 

869 x -> 192 

870 x/y -> 10/8 

871 x.x/y -> 192.168/16 

872 x.x.x/y -> 192.168.0/24 

873 

874 which are equivalent to:: 

875 

876 x.0.0.0/y -> 192.0.0.0/24 

877 x.0.0.0/y -> 10.0.0.0/8 

878 x.x.0.0/y -> 192.168.0.0/16 

879 x.x.x.0/y -> 192.168.0.0/24 

880 

881 .. warning:: 

882 

883 The next release (0.9.0) will contain a backwards incompatible change 

884 connected to handling of RFC 6164 IPv6 addresses (/127 and /128 subnets). 

885 When iterating ``IPNetwork`` and ``IPNetwork.iter_hosts()`` the first 

886 addresses in the networks will no longer be excluded and ``broadcast`` 

887 will be ``None``. 

888 """ 

889 __slots__ = ('_prefixlen',) 

890 

891 def __init__(self, addr, implicit_prefix=False, version=None, flags=0): 

892 """ 

893 Constructor. 

894 

895 :param addr: an IPv4 or IPv6 address with optional CIDR prefix, 

896 netmask or hostmask. May be an IP address in presentation 

897 (string) format, an tuple containing and integer address and a 

898 network prefix, or another IPAddress/IPNetwork object (copy 

899 construction). 

900 

901 :param implicit_prefix: (optional) if True, the constructor uses 

902 classful IPv4 rules to select a default prefix when one is not 

903 provided. If False it uses the length of the IP address version. 

904 (default: False) 

905 

906 :param version: (optional) optimizes version detection if specified 

907 and distinguishes between IPv4 and IPv6 for addresses with an 

908 equivalent integer value. 

909 

910 :param flags: (optional) decides which rules are applied to the 

911 interpretation of the addr value. Currently only supports the 

912 NOHOST option. See the netaddr.core docs for further details. 

913 

914 """ 

915 super(IPNetwork, self).__init__() 

916 

917 value, prefixlen, module = None, None, None 

918 

919 if hasattr(addr, '_prefixlen'): 

920 # IPNetwork object copy constructor 

921 value = addr._value 

922 module = addr._module 

923 prefixlen = addr._prefixlen 

924 elif hasattr(addr, '_value'): 

925 # IPAddress object copy constructor 

926 value = addr._value 

927 module = addr._module 

928 prefixlen = module.width 

929 elif version == 4: 

930 value, prefixlen = parse_ip_network(_ipv4, addr, 

931 implicit_prefix=implicit_prefix, flags=flags) 

932 module = _ipv4 

933 elif version == 6: 

934 value, prefixlen = parse_ip_network(_ipv6, addr, 

935 implicit_prefix=implicit_prefix, flags=flags) 

936 module = _ipv6 

937 else: 

938 if version is not None: 

939 raise ValueError('%r is an invalid IP version!' % version) 

940 try: 

941 module = _ipv4 

942 value, prefixlen = parse_ip_network(module, addr, 

943 implicit_prefix, flags) 

944 except AddrFormatError: 

945 try: 

946 module = _ipv6 

947 value, prefixlen = parse_ip_network(module, addr, 

948 implicit_prefix, flags) 

949 except AddrFormatError: 

950 pass 

951 

952 if value is None: 

953 raise AddrFormatError('invalid IPNetwork %s' % (addr,)) 

954 

955 self._value = value 

956 self._prefixlen = prefixlen 

957 self._module = module 

958 

959 def __getstate__(self): 

960 """:return: Pickled state of an `IPNetwork` object.""" 

961 return self._value, self._prefixlen, self._module.version 

962 

963 def __setstate__(self, state): 

964 """ 

965 :param state: data used to unpickle a pickled `IPNetwork` object. 

966 

967 """ 

968 value, prefixlen, version = state 

969 

970 self._value = value 

971 

972 if version == 4: 

973 self._module = _ipv4 

974 elif version == 6: 

975 self._module = _ipv6 

976 else: 

977 raise ValueError('unpickling failed for object state %s' \ 

978 % (state,)) 

979 

980 if 0 <= prefixlen <= self._module.width: 

981 self._prefixlen = prefixlen 

982 else: 

983 raise ValueError('unpickling failed for object state %s' \ 

984 % (state,)) 

985 

986 def _set_prefixlen(self, value): 

987 if not isinstance(value, _int_type): 

988 raise TypeError('int argument expected, not %s' % type(value)) 

989 if not 0 <= value <= self._module.width: 

990 raise AddrFormatError('invalid prefix for an %s address!' \ 

991 % self._module.family_name) 

992 self._prefixlen = value 

993 

994 prefixlen = property(lambda self: self._prefixlen, _set_prefixlen, 

995 doc='size of the bitmask used to separate the network from the host bits') 

996 

997 @property 

998 def ip(self): 

999 """ 

1000 The IP address of this `IPNetwork` object. This is may or may not be 

1001 the same as the network IP address which varies according to the value 

1002 of the CIDR subnet prefix. 

1003 """ 

1004 return IPAddress(self._value, self._module.version) 

1005 

1006 @property 

1007 def network(self): 

1008 """The network address of this `IPNetwork` object.""" 

1009 return IPAddress(self._value & self._netmask_int, self._module.version) 

1010 

1011 @property 

1012 def broadcast(self): 

1013 """The broadcast address of this `IPNetwork` object. 

1014 

1015 .. warning:: 

1016 

1017 The next release (0.9.0) will contain a backwards incompatible change 

1018 connected to handling of RFC 6164 IPv6 addresses (/127 and /128 subnets). 

1019 ``broadcast`` will be ``None`` when dealing with those networks. 

1020 """ 

1021 if self._module.version == 4 and (self._module.width - self._prefixlen) <= 1: 

1022 return None 

1023 else: 

1024 return IPAddress(self._value | self._hostmask_int, self._module.version) 

1025 

1026 @property 

1027 def first(self): 

1028 """ 

1029 The integer value of first IP address found within this `IPNetwork` 

1030 object. 

1031 """ 

1032 return self._value & (self._module.max_int ^ self._hostmask_int) 

1033 

1034 @property 

1035 def last(self): 

1036 """ 

1037 The integer value of last IP address found within this `IPNetwork` 

1038 object. 

1039 """ 

1040 hostmask = (1 << (self._module.width - self._prefixlen)) - 1 

1041 return self._value | hostmask 

1042 

1043 @property 

1044 def netmask(self): 

1045 """The subnet mask of this `IPNetwork` object.""" 

1046 netmask = self._module.max_int ^ self._hostmask_int 

1047 return IPAddress(netmask, self._module.version) 

1048 

1049 @netmask.setter 

1050 def netmask(self, value): 

1051 """Set the prefixlen using a subnet mask""" 

1052 ip = IPAddress(value) 

1053 

1054 if ip.version != self.version: 

1055 raise ValueError("IP version mismatch: %s and %s" % (ip, self)) 

1056 

1057 if not ip.is_netmask(): 

1058 raise ValueError("Invalid subnet mask specified: %s" % str(value)) 

1059 

1060 self.prefixlen = ip.netmask_bits() 

1061 

1062 @property 

1063 def _netmask_int(self): 

1064 """Same as self.netmask, but in integer format""" 

1065 return self._module.max_int ^ self._hostmask_int 

1066 

1067 @property 

1068 def hostmask(self): 

1069 """The host mask of this `IPNetwork` object.""" 

1070 hostmask = (1 << (self._module.width - self._prefixlen)) - 1 

1071 return IPAddress(hostmask, self._module.version) 

1072 

1073 @property 

1074 def _hostmask_int(self): 

1075 """Same as self.hostmask, but in integer format""" 

1076 return (1 << (self._module.width - self._prefixlen)) - 1 

1077 

1078 @property 

1079 def cidr(self): 

1080 """ 

1081 The true CIDR address for this `IPNetwork` object which omits any 

1082 host bits to the right of the CIDR subnet prefix. 

1083 """ 

1084 return IPNetwork( 

1085 (self._value & self._netmask_int, self._prefixlen), 

1086 version=self._module.version) 

1087 

1088 def __iadd__(self, num): 

1089 """ 

1090 Increases the value of this `IPNetwork` object by the current size 

1091 multiplied by ``num``. 

1092 

1093 An `IndexError` is raised if result exceeds maximum IP address value 

1094 or is less than zero. 

1095 

1096 :param num: (optional) number of `IPNetwork` blocks to increment \ 

1097 this IPNetwork's value by. 

1098 """ 

1099 new_value = int(self.network) + (self.size * num) 

1100 

1101 if (new_value + (self.size - 1)) > self._module.max_int: 

1102 raise IndexError('increment exceeds address boundary!') 

1103 if new_value < 0: 

1104 raise IndexError('increment is less than zero!') 

1105 

1106 self._value = new_value 

1107 return self 

1108 

1109 def __isub__(self, num): 

1110 """ 

1111 Decreases the value of this `IPNetwork` object by the current size 

1112 multiplied by ``num``. 

1113 

1114 An `IndexError` is raised if result is less than zero or exceeds 

1115 maximum IP address value. 

1116 

1117 :param num: (optional) number of `IPNetwork` blocks to decrement \ 

1118 this IPNetwork's value by. 

1119 """ 

1120 new_value = int(self.network) - (self.size * num) 

1121 

1122 if new_value < 0: 

1123 raise IndexError('decrement is less than zero!') 

1124 if (new_value + (self.size - 1)) > self._module.max_int: 

1125 raise IndexError('decrement exceeds address boundary!') 

1126 

1127 self._value = new_value 

1128 return self 

1129 

1130 def __contains__(self, other): 

1131 """ 

1132 :param other: an `IPAddress` or ranged IP object. 

1133 

1134 :return: ``True`` if other falls within the boundary of this one, 

1135 ``False`` otherwise. 

1136 """ 

1137 if isinstance(other, BaseIP): 

1138 if self._module.version != other._module.version: 

1139 return False 

1140 

1141 # self_net will contain only the network bits. 

1142 shiftwidth = self._module.width - self._prefixlen 

1143 self_net = self._value >> shiftwidth 

1144 if isinstance(other, IPRange): 

1145 # IPRange has no _value. 

1146 # (self_net+1)<<shiftwidth is not our last address, but the one 

1147 # after the last one. 

1148 return ((self_net << shiftwidth) <= other._start._value and 

1149 (((self_net + 1) << shiftwidth) > other._end._value)) 

1150 

1151 other_net = other._value >> shiftwidth 

1152 if isinstance(other, IPAddress): 

1153 return other_net == self_net 

1154 if isinstance(other, IPNetwork): 

1155 return self_net == other_net and self._prefixlen <= other._prefixlen 

1156 

1157 # Whatever it is, try to interpret it as IPNetwork 

1158 return IPNetwork(other) in self 

1159 

1160 def key(self): 

1161 """ 

1162 :return: A key tuple used to uniquely identify this `IPNetwork`. 

1163 """ 

1164 return self._module.version, self.first, self.last 

1165 

1166 def sort_key(self): 

1167 """ 

1168 :return: A key tuple used to compare and sort this `IPNetwork` correctly. 

1169 """ 

1170 net_size_bits = self._prefixlen - 1 

1171 first = self._value & (self._module.max_int ^ self._hostmask_int) 

1172 host_bits = self._value - first 

1173 return self._module.version, first, net_size_bits, host_bits 

1174 

1175 def ipv4(self): 

1176 """ 

1177 :return: A numerically equivalent version 4 `IPNetwork` object. \ 

1178 Raises an `AddrConversionError` if IPv6 address cannot be \ 

1179 converted to IPv4. 

1180 """ 

1181 ip = None 

1182 klass = self.__class__ 

1183 

1184 if self._module.version == 4: 

1185 ip = klass('%s/%d' % (self.ip, self.prefixlen)) 

1186 elif self._module.version == 6: 

1187 if 0 <= self._value <= _ipv4.max_int: 

1188 addr = _ipv4.int_to_str(self._value) 

1189 ip = klass('%s/%d' % (addr, self.prefixlen - 96)) 

1190 elif _ipv4.max_int <= self._value <= 0xffffffffffff: 

1191 addr = _ipv4.int_to_str(self._value - 0xffff00000000) 

1192 ip = klass('%s/%d' % (addr, self.prefixlen - 96)) 

1193 else: 

1194 raise AddrConversionError('IPv6 address %s unsuitable for ' \ 

1195 'conversion to IPv4!' % self) 

1196 return ip 

1197 

1198 def ipv6(self, ipv4_compatible=False): 

1199 """ 

1200 .. note:: the IPv4-mapped IPv6 address format is now considered \ 

1201 deprecated. See RFC 4291 or later for details. 

1202 

1203 :param ipv4_compatible: If ``True`` returns an IPv4-mapped address 

1204 (::ffff:x.x.x.x), an IPv4-compatible (::x.x.x.x) address 

1205 otherwise. Default: False (IPv4-mapped). 

1206 

1207 :return: A numerically equivalent version 6 `IPNetwork` object. 

1208 """ 

1209 ip = None 

1210 klass = self.__class__ 

1211 

1212 if self._module.version == 6: 

1213 if ipv4_compatible and \ 

1214 (0xffff00000000 <= self._value <= 0xffffffffffff): 

1215 ip = klass((self._value - 0xffff00000000, self._prefixlen), 

1216 version=6) 

1217 else: 

1218 ip = klass((self._value, self._prefixlen), version=6) 

1219 elif self._module.version == 4: 

1220 if ipv4_compatible: 

1221 # IPv4-Compatible IPv6 address 

1222 ip = klass((self._value, self._prefixlen + 96), version=6) 

1223 else: 

1224 # IPv4-Mapped IPv6 address 

1225 ip = klass((0xffff00000000 + self._value, 

1226 self._prefixlen + 96), version=6) 

1227 

1228 return ip 

1229 

1230 def previous(self, step=1): 

1231 """ 

1232 :param step: the number of IP subnets between this `IPNetwork` object 

1233 and the expected subnet. Default: 1 (the previous IP subnet). 

1234 

1235 :return: The adjacent subnet preceding this `IPNetwork` object. 

1236 """ 

1237 ip_copy = self.__class__('%s/%d' % (self.network, self.prefixlen), 

1238 self._module.version) 

1239 ip_copy -= step 

1240 return ip_copy 

1241 

1242 def next(self, step=1): 

1243 """ 

1244 :param step: the number of IP subnets between this `IPNetwork` object 

1245 and the expected subnet. Default: 1 (the next IP subnet). 

1246 

1247 :return: The adjacent subnet succeeding this `IPNetwork` object. 

1248 """ 

1249 ip_copy = self.__class__('%s/%d' % (self.network, self.prefixlen), 

1250 self._module.version) 

1251 ip_copy += step 

1252 return ip_copy 

1253 

1254 def supernet(self, prefixlen=0): 

1255 """ 

1256 Provides a list of supernets for this `IPNetwork` object between the 

1257 size of the current prefix and (if specified) an endpoint prefix. 

1258 

1259 :param prefixlen: (optional) a CIDR prefix for the maximum supernet. 

1260 Default: 0 - returns all possible supernets. 

1261 

1262 :return: a tuple of supernet `IPNetwork` objects. 

1263 """ 

1264 if not 0 <= prefixlen <= self._module.width: 

1265 raise ValueError('CIDR prefix /%d invalid for IPv%d!' \ 

1266 % (prefixlen, self._module.version)) 

1267 

1268 supernets = [] 

1269 # Use a copy of self as we'll be editing it. 

1270 supernet = self.cidr 

1271 supernet._prefixlen = prefixlen 

1272 while supernet._prefixlen != self._prefixlen: 

1273 supernets.append(supernet.cidr) 

1274 supernet._prefixlen += 1 

1275 return supernets 

1276 

1277 def subnet(self, prefixlen, count=None, fmt=None): 

1278 """ 

1279 A generator that divides up this IPNetwork's subnet into smaller 

1280 subnets based on a specified CIDR prefix. 

1281 

1282 :param prefixlen: a CIDR prefix indicating size of subnets to be 

1283 returned. 

1284 

1285 :param count: (optional) number of consecutive IP subnets to be 

1286 returned. 

1287 

1288 :return: an iterator containing IPNetwork subnet objects. 

1289 """ 

1290 if not 0 <= self.prefixlen <= self._module.width: 

1291 raise ValueError('CIDR prefix /%d invalid for IPv%d!' \ 

1292 % (prefixlen, self._module.version)) 

1293 

1294 if not self.prefixlen <= prefixlen: 

1295 # Don't return anything. 

1296 return 

1297 

1298 # Calculate number of subnets to be returned. 

1299 width = self._module.width 

1300 max_subnets = 2 ** (width - self.prefixlen) // 2 ** (width - prefixlen) 

1301 

1302 if count is None: 

1303 count = max_subnets 

1304 

1305 if not 1 <= count <= max_subnets: 

1306 raise ValueError('count outside of current IP subnet boundary!') 

1307 

1308 base_subnet = self._module.int_to_str(self.first) 

1309 i = 0 

1310 while(i < count): 

1311 subnet = self.__class__('%s/%d' % (base_subnet, prefixlen), 

1312 self._module.version) 

1313 subnet.value += (subnet.size * i) 

1314 subnet.prefixlen = prefixlen 

1315 i += 1 

1316 yield subnet 

1317 

1318 def iter_hosts(self): 

1319 """ 

1320 A generator that provides all the IP addresses that can be assigned 

1321 to hosts within the range of this IP object's subnet. 

1322 

1323 - for IPv4, the network and broadcast addresses are always excluded. \ 

1324 for subnets that contains less than 4 IP addresses /31 and /32 \ 

1325 report in a manner per RFC 3021 

1326 

1327 - for IPv6, only the unspecified address '::' or Subnet-Router anycast \ 

1328 address (first address in the network) is excluded. 

1329 

1330 .. warning:: 

1331 

1332 The next release (0.9.0) will contain a backwards incompatible change 

1333 connected to handling of RFC 6164 IPv6 addresses (/127 and /128 subnets). 

1334 When iterating ``IPNetwork`` and ``IPNetwork.iter_hosts()`` the first 

1335 addresses in the networks will no longer be excluded. 

1336 

1337 :return: an IPAddress iterator 

1338 """ 

1339 it_hosts = iter([]) 

1340 

1341 if self._module.version == 4: 

1342 # IPv4 logic. 

1343 if self.size >= 4: 

1344 it_hosts = iter_iprange( 

1345 IPAddress(self.first + 1, self._module.version), 

1346 IPAddress(self.last - 1, self._module.version)) 

1347 else: 

1348 it_hosts = iter_iprange( 

1349 IPAddress(self.first, self._module.version), 

1350 IPAddress(self.last, self._module.version)) 

1351 else: 

1352 # IPv6 logic. 

1353 # RFC 4291 section 2.6.1 says that the first IP in the network is 

1354 # the Subnet-Router anycast address. This address cannot be 

1355 # assigned to a host, so use self.first+1. 

1356 if self.size >= 2: 

1357 it_hosts = iter_iprange( 

1358 IPAddress(self.first + 1, self._module.version), 

1359 IPAddress(self.last, self._module.version)) 

1360 return it_hosts 

1361 

1362 def __str__(self): 

1363 """:return: this IPNetwork in CIDR format""" 

1364 addr = self._module.int_to_str(self._value) 

1365 return "%s/%s" % (addr, self.prefixlen) 

1366 

1367 def __repr__(self): 

1368 """:return: Python statement to create an equivalent object""" 

1369 return "%s('%s')" % (self.__class__.__name__, self) 

1370 

1371 

1372class IPRange(BaseIP, IPListMixin): 

1373 """ 

1374 An arbitrary IPv4 or IPv6 address range. 

1375 

1376 Formed from a lower and upper bound IP address. The upper bound IP cannot 

1377 be numerically smaller than the lower bound and the IP version of both 

1378 must match. 

1379 

1380 """ 

1381 __slots__ = ('_start', '_end') 

1382 

1383 def __init__(self, start, end, flags=0): 

1384 """ 

1385 Constructor. 

1386 

1387 :param start: an IPv4 or IPv6 address that forms the lower 

1388 boundary of this IP range. 

1389 

1390 :param end: an IPv4 or IPv6 address that forms the upper 

1391 boundary of this IP range. 

1392 

1393 :param flags: (optional) decides which rules are applied to the 

1394 interpretation of the start and end values. Supported constants 

1395 are INET_PTON and ZEROFILL. See the netaddr.core docs for further 

1396 details. 

1397 

1398 """ 

1399 self._start = IPAddress(start, flags=flags) 

1400 self._module = self._start._module 

1401 self._end = IPAddress(end, self._module.version, flags=flags) 

1402 if int(self._start) > int(self._end): 

1403 raise AddrFormatError('lower bound IP greater than upper bound!') 

1404 

1405 def __getstate__(self): 

1406 """:return: Pickled state of an `IPRange` object.""" 

1407 return self._start.value, self._end.value, self._module.version 

1408 

1409 def __setstate__(self, state): 

1410 """ 

1411 :param state: data used to unpickle a pickled `IPRange` object. 

1412 """ 

1413 start, end, version = state 

1414 

1415 self._start = IPAddress(start, version) 

1416 self._module = self._start._module 

1417 self._end = IPAddress(end, version) 

1418 

1419 def __contains__(self, other): 

1420 if isinstance(other, BaseIP): 

1421 if self._module.version != other._module.version: 

1422 return False 

1423 if isinstance(other, IPAddress): 

1424 return (self._start._value <= other._value and 

1425 self._end._value >= other._value) 

1426 if isinstance(other, IPRange): 

1427 return (self._start._value <= other._start._value and 

1428 self._end._value >= other._end._value) 

1429 if isinstance(other, IPNetwork): 

1430 shiftwidth = other._module.width - other._prefixlen 

1431 other_start = (other._value >> shiftwidth) << shiftwidth 

1432 # Start of the next network after other 

1433 other_next_start = other_start + (1 << shiftwidth) 

1434 

1435 return (self._start._value <= other_start and 

1436 self._end._value > other_next_start) 

1437 

1438 # Whatever it is, try to interpret it as IPAddress. 

1439 return IPAddress(other) in self 

1440 

1441 @property 

1442 def first(self): 

1443 """The integer value of first IP address in this `IPRange` object.""" 

1444 return int(self._start) 

1445 

1446 @property 

1447 def last(self): 

1448 """The integer value of last IP address in this `IPRange` object.""" 

1449 return int(self._end) 

1450 

1451 def key(self): 

1452 """ 

1453 :return: A key tuple used to uniquely identify this `IPRange`. 

1454 """ 

1455 return self._module.version, self.first, self.last 

1456 

1457 def sort_key(self): 

1458 """ 

1459 :return: A key tuple used to compare and sort this `IPRange` correctly. 

1460 """ 

1461 skey = self._module.width - num_bits(self.size) 

1462 return self._module.version, self._start._value, skey 

1463 

1464 def cidrs(self): 

1465 """ 

1466 The list of CIDR addresses found within the lower and upper bound 

1467 addresses of this `IPRange`. 

1468 """ 

1469 return iprange_to_cidrs(self._start, self._end) 

1470 

1471 def __str__(self): 

1472 """:return: this `IPRange` in a common representational format.""" 

1473 return "%s-%s" % (self._start, self._end) 

1474 

1475 def __repr__(self): 

1476 """:return: Python statement to create an equivalent object""" 

1477 return "%s('%s', '%s')" % (self.__class__.__name__, 

1478 self._start, self._end) 

1479 

1480 

1481def iter_unique_ips(*args): 

1482 """ 

1483 :param args: A list of IP addresses and subnets passed in as arguments. 

1484 

1485 :return: A generator that flattens out IP subnets, yielding unique 

1486 individual IP addresses (no duplicates). 

1487 """ 

1488 for cidr in cidr_merge(args): 

1489 for ip in cidr: 

1490 yield ip 

1491 

1492 

1493def cidr_abbrev_to_verbose(abbrev_cidr): 

1494 """ 

1495 A function that converts abbreviated IPv4 CIDRs to their more verbose 

1496 equivalent. 

1497 

1498 :param abbrev_cidr: an abbreviated CIDR. 

1499 

1500 Uses the old-style classful IP address rules to decide on a default 

1501 subnet prefix if one is not explicitly provided. 

1502 

1503 Only supports IPv4 addresses. 

1504 

1505 Examples :: 

1506 

1507 10 - 10.0.0.0/8 

1508 10/16 - 10.0.0.0/16 

1509 128 - 128.0.0.0/16 

1510 128/8 - 128.0.0.0/8 

1511 192.168 - 192.168.0.0/16 

1512 

1513 :return: A verbose CIDR from an abbreviated CIDR or old-style classful \ 

1514 network address. The original value if it was not recognised as a \ 

1515 supported abbreviation. 

1516 """ 

1517 # Internal function that returns a prefix value based on the old IPv4 

1518 # classful network scheme that has been superseded (almost) by CIDR. 

1519 def classful_prefix(octet): 

1520 octet = int(octet) 

1521 if not 0 <= octet <= 255: 

1522 raise IndexError('Invalid octet: %r!' % octet) 

1523 if 0 <= octet <= 127: # Legacy class 'A' classification. 

1524 return 8 

1525 elif 128 <= octet <= 191: # Legacy class 'B' classification. 

1526 return 16 

1527 elif 192 <= octet <= 223: # Legacy class 'C' classification. 

1528 return 24 

1529 elif 224 <= octet <= 239: # Multicast address range. 

1530 return 4 

1531 return 32 # Default. 

1532 

1533 if _is_str(abbrev_cidr): 

1534 if ':' in abbrev_cidr or abbrev_cidr == '': 

1535 return abbrev_cidr 

1536 

1537 try: 

1538 # Single octet partial integer or string address. 

1539 i = int(abbrev_cidr) 

1540 return "%s.0.0.0/%s" % (i, classful_prefix(i)) 

1541 except ValueError: 

1542 # Multi octet partial string address with optional prefix. 

1543 if '/' in abbrev_cidr: 

1544 part_addr, prefix = abbrev_cidr.split('/', 1) 

1545 

1546 # Check prefix for validity. 

1547 try: 

1548 if not 0 <= int(prefix) <= 32: 

1549 raise ValueError('prefixlen in address %r out of range' \ 

1550 ' for IPv4!' % (abbrev_cidr,)) 

1551 except ValueError: 

1552 return abbrev_cidr 

1553 else: 

1554 part_addr = abbrev_cidr 

1555 prefix = None 

1556 

1557 tokens = part_addr.split('.') 

1558 if len(tokens) > 4: 

1559 # Not a recognisable format. 

1560 return abbrev_cidr 

1561 for i in range(4 - len(tokens)): 

1562 tokens.append('0') 

1563 

1564 if prefix is None: 

1565 try: 

1566 prefix = classful_prefix(tokens[0]) 

1567 except ValueError: 

1568 return abbrev_cidr 

1569 

1570 return "%s/%s" % ('.'.join(tokens), prefix) 

1571 except (TypeError, IndexError): 

1572 # Not a recognisable format. 

1573 return abbrev_cidr 

1574 

1575 

1576 

1577def cidr_merge(ip_addrs): 

1578 """ 

1579 A function that accepts an iterable sequence of IP addresses and subnets 

1580 merging them into the smallest possible list of CIDRs. It merges adjacent 

1581 subnets where possible, those contained within others and also removes 

1582 any duplicates. 

1583 

1584 :param ip_addrs: an iterable sequence of IP addresses, subnets or ranges. 

1585 

1586 :return: a summarized list of `IPNetwork` objects. 

1587 """ 

1588 # The algorithm is quite simple: For each CIDR we create an IP range. 

1589 # Sort them and merge when possible. Afterwars split them again 

1590 # optimally. 

1591 if not hasattr(ip_addrs, '__iter__'): 

1592 raise ValueError('A sequence or iterator is expected!') 

1593 

1594 ranges = [] 

1595 

1596 for ip in ip_addrs: 

1597 if isinstance(ip, (IPNetwork, IPRange)): 

1598 net = ip 

1599 else: 

1600 net = IPNetwork(ip) 

1601 # Since non-overlapping ranges are the common case, remember the original 

1602 ranges.append( (net.version, net.last, net.first, net) ) 

1603 

1604 ranges.sort() 

1605 i = len(ranges) - 1 

1606 while i > 0: 

1607 if ranges[i][0] == ranges[i - 1][0] and ranges[i][2] - 1 <= ranges[i - 1][1]: 

1608 ranges[i - 1] = (ranges[i][0], ranges[i][1], min(ranges[i - 1][2], ranges[i][2])) 

1609 del ranges[i] 

1610 i -= 1 

1611 merged = [] 

1612 for range_tuple in ranges: 

1613 # If this range wasn't merged we can simply use the old cidr. 

1614 if len(range_tuple) == 4: 

1615 original = range_tuple[3] 

1616 if isinstance(original, IPRange): 

1617 merged.extend(original.cidrs()) 

1618 else: 

1619 merged.append(original) 

1620 else: 

1621 version = range_tuple[0] 

1622 range_start = IPAddress(range_tuple[2], version=version) 

1623 range_stop = IPAddress(range_tuple[1], version=version) 

1624 merged.extend(iprange_to_cidrs(range_start, range_stop)) 

1625 return merged 

1626 

1627 

1628def cidr_exclude(target, exclude): 

1629 """ 

1630 Removes an exclude IP address or subnet from target IP subnet. 

1631 

1632 :param target: the target IP address or subnet to be divided up. 

1633 

1634 :param exclude: the IP address or subnet to be removed from target. 

1635 

1636 :return: list of `IPNetwork` objects remaining after exclusion. 

1637 """ 

1638 left, _, right = cidr_partition(target, exclude) 

1639 

1640 return left + right 

1641 

1642def cidr_partition(target, exclude): 

1643 """ 

1644 Partitions a target IP subnet on an exclude IP address. 

1645 

1646 :param target: the target IP address or subnet to be divided up. 

1647 

1648 :param exclude: the IP address or subnet to partition on 

1649 

1650 :return: list of `IPNetwork` objects before, the partition and after, sorted. 

1651 

1652 Adding the three lists returns the equivalent of the original subnet. 

1653 """ 

1654 

1655 target = IPNetwork(target) 

1656 exclude = IPNetwork(exclude) 

1657 

1658 if exclude.last < target.first: 

1659 # Exclude subnet's upper bound address less than target 

1660 # subnet's lower bound. 

1661 return [], [], [target.cidr] 

1662 elif target.last < exclude.first: 

1663 # Exclude subnet's lower bound address greater than target 

1664 # subnet's upper bound. 

1665 return [target.cidr], [], [] 

1666 

1667 if target.prefixlen >= exclude.prefixlen: 

1668 # Exclude contains the target 

1669 return [], [target], [] 

1670 

1671 left = [] 

1672 right = [] 

1673 

1674 new_prefixlen = target.prefixlen + 1 

1675 # Some @properties that are expensive to get and don't change below. 

1676 target_module_width = target._module.width 

1677 

1678 target_first = target.first 

1679 version = exclude.version 

1680 i_lower = target_first 

1681 i_upper = target_first + (2 ** (target_module_width - new_prefixlen)) 

1682 

1683 while exclude.prefixlen >= new_prefixlen: 

1684 if exclude.first >= i_upper: 

1685 left.append(IPNetwork((i_lower, new_prefixlen), version=version)) 

1686 matched = i_upper 

1687 else: 

1688 right.append(IPNetwork((i_upper, new_prefixlen), version=version)) 

1689 matched = i_lower 

1690 

1691 new_prefixlen += 1 

1692 

1693 if new_prefixlen > target_module_width: 

1694 break 

1695 

1696 i_lower = matched 

1697 i_upper = matched + (2 ** (target_module_width - new_prefixlen)) 

1698 

1699 return left, [exclude], right[::-1] 

1700 

1701 

1702def spanning_cidr(ip_addrs): 

1703 """ 

1704 Function that accepts a sequence of IP addresses and subnets returning 

1705 a single `IPNetwork` subnet that is large enough to span the lower and 

1706 upper bound IP addresses with a possible overlap on either end. 

1707 

1708 :param ip_addrs: sequence of IP addresses and subnets. 

1709 

1710 :return: a single spanning `IPNetwork` subnet. 

1711 """ 

1712 ip_addrs_iter = iter(ip_addrs) 

1713 try: 

1714 network_a = IPNetwork(_iter_next(ip_addrs_iter)) 

1715 network_b = IPNetwork(_iter_next(ip_addrs_iter)) 

1716 except StopIteration: 

1717 raise ValueError('IP sequence must contain at least 2 elements!') 

1718 

1719 if network_a < network_b: 

1720 min_network = network_a 

1721 max_network = network_b 

1722 else: 

1723 min_network = network_b 

1724 max_network = network_a 

1725 

1726 for ip in ip_addrs_iter: 

1727 network = IPNetwork(ip) 

1728 if network < min_network: 

1729 min_network = network 

1730 if network > max_network: 

1731 max_network = network 

1732 

1733 if min_network.version != max_network.version: 

1734 raise TypeError('IP sequence cannot contain both IPv4 and IPv6!') 

1735 

1736 ipnum = max_network.last 

1737 prefixlen = max_network.prefixlen 

1738 lowest_ipnum = min_network.first 

1739 width = max_network._module.width 

1740 

1741 while prefixlen > 0 and ipnum > lowest_ipnum: 

1742 prefixlen -= 1 

1743 ipnum &= -(1<<(width-prefixlen)) 

1744 

1745 return IPNetwork( (ipnum, prefixlen), version=min_network.version ) 

1746 

1747 

1748def iter_iprange(start, end, step=1): 

1749 """ 

1750 A generator that produces IPAddress objects between an arbitrary start 

1751 and stop IP address with intervals of step between them. Sequences 

1752 produce are inclusive of boundary IPs. 

1753 

1754 :param start: start IP address. 

1755 

1756 :param end: end IP address. 

1757 

1758 :param step: (optional) size of step between IP addresses. Default: 1 

1759 

1760 :return: an iterator of one or more `IPAddress` objects. 

1761 """ 

1762 start = IPAddress(start) 

1763 end = IPAddress(end) 

1764 

1765 if start.version != end.version: 

1766 raise TypeError('start and stop IP versions do not match!') 

1767 version = start.version 

1768 

1769 step = int(step) 

1770 if step == 0: 

1771 raise ValueError('step argument cannot be zero') 

1772 

1773 # We don't need objects from here, just integers. 

1774 start = int(start) 

1775 stop = int(end) 

1776 

1777 negative_step = False 

1778 

1779 if step < 0: 

1780 negative_step = True 

1781 

1782 index = start - step 

1783 while True: 

1784 index += step 

1785 if negative_step: 

1786 if not index >= stop: 

1787 break 

1788 else: 

1789 if not index <= stop: 

1790 break 

1791 yield IPAddress(index, version) 

1792 

1793 

1794 

1795def iprange_to_cidrs(start, end): 

1796 """ 

1797 A function that accepts an arbitrary start and end IP address or subnet 

1798 and returns a list of CIDR subnets that fit exactly between the boundaries 

1799 of the two with no overlap. 

1800 

1801 :param start: the start IP address or subnet. 

1802 

1803 :param end: the end IP address or subnet. 

1804 

1805 :return: a list of one or more IP addresses and subnets. 

1806 """ 

1807 cidr_list = [] 

1808 

1809 start = IPNetwork(start) 

1810 end = IPNetwork(end) 

1811 

1812 iprange = [start.first, end.last] 

1813 

1814 # Get spanning CIDR covering both addresses. 

1815 cidr_span = spanning_cidr([start, end]) 

1816 width = start._module.width 

1817 

1818 if cidr_span.first < iprange[0]: 

1819 exclude = IPNetwork((iprange[0]-1, width), version=start.version) 

1820 cidr_list = cidr_partition(cidr_span, exclude)[2] 

1821 cidr_span = cidr_list.pop() 

1822 if cidr_span.last > iprange[1]: 

1823 exclude = IPNetwork((iprange[1]+1, width), version=start.version) 

1824 cidr_list += cidr_partition(cidr_span, exclude)[0] 

1825 else: 

1826 cidr_list.append(cidr_span) 

1827 

1828 return cidr_list 

1829 

1830 

1831def smallest_matching_cidr(ip, cidrs): 

1832 """ 

1833 Matches an IP address or subnet against a given sequence of IP addresses 

1834 and subnets. 

1835 

1836 :param ip: a single IP address or subnet. 

1837 

1838 :param cidrs: a sequence of IP addresses and/or subnets. 

1839 

1840 :return: the smallest (most specific) matching IPAddress or IPNetwork 

1841 object from the provided sequence, None if there was no match. 

1842 """ 

1843 match = None 

1844 

1845 if not hasattr(cidrs, '__iter__'): 

1846 raise TypeError('IP address/subnet sequence expected, not %r!' 

1847 % (cidrs,)) 

1848 

1849 ip = IPAddress(ip) 

1850 for cidr in sorted([IPNetwork(cidr) for cidr in cidrs]): 

1851 if ip in cidr: 

1852 match = cidr 

1853 else: 

1854 if match is not None and cidr.network not in match: 

1855 break 

1856 

1857 return match 

1858 

1859 

1860def largest_matching_cidr(ip, cidrs): 

1861 """ 

1862 Matches an IP address or subnet against a given sequence of IP addresses 

1863 and subnets. 

1864 

1865 :param ip: a single IP address or subnet. 

1866 

1867 :param cidrs: a sequence of IP addresses and/or subnets. 

1868 

1869 :return: the largest (least specific) matching IPAddress or IPNetwork 

1870 object from the provided sequence, None if there was no match. 

1871 """ 

1872 match = None 

1873 

1874 if not hasattr(cidrs, '__iter__'): 

1875 raise TypeError('IP address/subnet sequence expected, not %r!' 

1876 % (cidrs,)) 

1877 

1878 ip = IPAddress(ip) 

1879 for cidr in sorted([IPNetwork(cidr) for cidr in cidrs]): 

1880 if ip in cidr: 

1881 match = cidr 

1882 break 

1883 

1884 return match 

1885 

1886 

1887def all_matching_cidrs(ip, cidrs): 

1888 """ 

1889 Matches an IP address or subnet against a given sequence of IP addresses 

1890 and subnets. 

1891 

1892 :param ip: a single IP address. 

1893 

1894 :param cidrs: a sequence of IP addresses and/or subnets. 

1895 

1896 :return: all matching IPAddress and/or IPNetwork objects from the provided 

1897 sequence, an empty list if there was no match. 

1898 """ 

1899 matches = [] 

1900 

1901 if not hasattr(cidrs, '__iter__'): 

1902 raise TypeError('IP address/subnet sequence expected, not %r!' 

1903 % (cidrs,)) 

1904 

1905 ip = IPAddress(ip) 

1906 for cidr in sorted([IPNetwork(cidr) for cidr in cidrs]): 

1907 if ip in cidr: 

1908 matches.append(cidr) 

1909 else: 

1910 if matches and cidr.network not in matches[-1]: 

1911 break 

1912 

1913 return matches 

1914 

1915#----------------------------------------------------------------------------- 

1916# Cached IPv4 address range lookups. 

1917#----------------------------------------------------------------------------- 

1918IPV4_LOOPBACK = IPNetwork('127.0.0.0/8') # Loopback addresses (RFC 990) 

1919 

1920IPV4_PRIVATE = ( 

1921 IPNetwork('10.0.0.0/8'), # Class A private network local communication (RFC 1918) 

1922 IPNetwork('100.64.0.0/10'), # Carrier grade NAT (RFC 6598) 

1923 IPNetwork('172.16.0.0/12'), # Private network - local communication (RFC 1918) 

1924 IPNetwork('192.0.0.0/24'), # IANA IPv4 Special Purpose Address Registry (RFC 5736) 

1925 IPNetwork('192.168.0.0/16'), # Class B private network local communication (RFC 1918) 

1926 IPNetwork('198.18.0.0/15'), # Testing of inter-network communications between subnets (RFC 2544) 

1927 IPRange('239.0.0.0', '239.255.255.255'), # Administrative Multicast 

1928) 

1929 

1930IPV4_LINK_LOCAL = IPNetwork('169.254.0.0/16') 

1931 

1932IPV4_MULTICAST = IPNetwork('224.0.0.0/4') 

1933 

1934IPV4_6TO4 = IPNetwork('192.88.99.0/24') # 6to4 anycast relays (RFC 3068) 

1935 

1936IPV4_RESERVED = ( 

1937 IPNetwork('0.0.0.0/8'), # Broadcast message (RFC 1700) 

1938 IPNetwork('192.0.2.0/24'), # TEST-NET examples and documentation (RFC 5737) 

1939 IPNetwork('240.0.0.0/4'), # Reserved for multicast assignments (RFC 5771) 

1940 IPNetwork('198.51.100.0/24'), # TEST-NET-2 examples and documentation (RFC 5737) 

1941 IPNetwork('203.0.113.0/24'), # TEST-NET-3 examples and documentation (RFC 5737) 

1942 

1943 # Reserved multicast 

1944 IPNetwork('233.252.0.0/24'), # Multicast test network 

1945 IPRange('234.0.0.0', '238.255.255.255'), 

1946 IPRange('225.0.0.0', '231.255.255.255'), 

1947) + (IPV4_LOOPBACK, IPV4_6TO4) 

1948 

1949#----------------------------------------------------------------------------- 

1950# Cached IPv6 address range lookups. 

1951#----------------------------------------------------------------------------- 

1952IPV6_LOOPBACK = IPNetwork('::1/128') 

1953 

1954IPV6_PRIVATE = ( 

1955 IPNetwork('fc00::/7'), # Unique Local Addresses (ULA) 

1956 IPNetwork('fec0::/10'), # Site Local Addresses (deprecated - RFC 3879) 

1957) 

1958 

1959IPV6_LINK_LOCAL = IPNetwork('fe80::/10') 

1960 

1961IPV6_MULTICAST = IPNetwork('ff00::/8') 

1962 

1963IPV6_RESERVED = ( 

1964 IPNetwork('ff00::/12'), IPNetwork('::/8'), 

1965 IPNetwork('0100::/8'), IPNetwork('0200::/7'), 

1966 IPNetwork('0400::/6'), IPNetwork('0800::/5'), 

1967 IPNetwork('1000::/4'), IPNetwork('4000::/3'), 

1968 IPNetwork('6000::/3'), IPNetwork('8000::/3'), 

1969 IPNetwork('A000::/3'), IPNetwork('C000::/3'), 

1970 IPNetwork('E000::/4'), IPNetwork('F000::/5'), 

1971 IPNetwork('F800::/6'), IPNetwork('FE00::/9'), 

1972)