blob: cc6760b7aa6ca749e73f9f84d3eba5f602925ee5 [file] [log] [blame]
Nick Coghlandc9b2552012-05-20 21:01:57 +10001# Copyright 2007 Google Inc.
2# Licensed to PSF under a Contributor Agreement.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13# implied. See the License for the specific language governing
14# permissions and limitations under the License.
15
16"""A fast, lightweight IPv4/IPv6 manipulation library in Python.
17
18This library is used to create/poke/manipulate IPv4 and IPv6 addresses
19and networks.
20
21"""
22
23__version__ = '1.0'
24
25import struct
26
27IPV4LENGTH = 32
28IPV6LENGTH = 128
29
30
31class AddressValueError(ValueError):
32 """A Value Error related to the address."""
33
34
35class NetmaskValueError(ValueError):
36 """A Value Error related to the netmask."""
37
38
39def ip_address(address, version=None):
40 """Take an IP string/int and return an object of the correct type.
41
42 Args:
43 address: A string or integer, the IP address. Either IPv4 or
44 IPv6 addresses may be supplied; integers less than 2**32 will
45 be considered to be IPv4 by default.
Sandro Tosi876ecad2012-05-23 22:26:55 +020046 version: An integer, 4 or 6. If set, don't try to automatically
47 determine what the IP address type is. Important for things
Nick Coghlandc9b2552012-05-20 21:01:57 +100048 like ip_address(1), which could be IPv4, '192.0.2.1', or IPv6,
49 '2001:db8::1'.
50
51 Returns:
52 An IPv4Address or IPv6Address object.
53
54 Raises:
Sandro Tosi876ecad2012-05-23 22:26:55 +020055 ValueError: if the *address* passed isn't either a v4 or a v6
56 address, or if the version is not None, 4, or 6.
Nick Coghlandc9b2552012-05-20 21:01:57 +100057
58 """
Sandro Tosi876ecad2012-05-23 22:26:55 +020059 if version is not None:
Nick Coghlandc9b2552012-05-20 21:01:57 +100060 if version == 4:
61 return IPv4Address(address)
62 elif version == 6:
63 return IPv6Address(address)
Sandro Tosi876ecad2012-05-23 22:26:55 +020064 else:
65 raise ValueError()
Nick Coghlandc9b2552012-05-20 21:01:57 +100066
67 try:
68 return IPv4Address(address)
69 except (AddressValueError, NetmaskValueError):
70 pass
71
72 try:
73 return IPv6Address(address)
74 except (AddressValueError, NetmaskValueError):
75 pass
76
77 raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
78 address)
79
80
81def ip_network(address, version=None, strict=True):
82 """Take an IP string/int and return an object of the correct type.
83
84 Args:
85 address: A string or integer, the IP network. Either IPv4 or
86 IPv6 networks may be supplied; integers less than 2**32 will
87 be considered to be IPv4 by default.
Sandro Tosi876ecad2012-05-23 22:26:55 +020088 version: An integer, 4 or 6. If set, don't try to automatically
89 determine what the IP address type is. Important for things
Nick Coghlandc9b2552012-05-20 21:01:57 +100090 like ip_network(1), which could be IPv4, '192.0.2.1/32', or IPv6,
91 '2001:db8::1/128'.
92
93 Returns:
94 An IPv4Network or IPv6Network object.
95
96 Raises:
97 ValueError: if the string passed isn't either a v4 or a v6
Sandro Tosi876ecad2012-05-23 22:26:55 +020098 address. Or if the network has host bits set. Or if the version
99 is not None, 4, or 6.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000100
101 """
Sandro Tosi876ecad2012-05-23 22:26:55 +0200102 if version is not None:
Nick Coghlandc9b2552012-05-20 21:01:57 +1000103 if version == 4:
104 return IPv4Network(address, strict)
105 elif version == 6:
106 return IPv6Network(address, strict)
Sandro Tosi876ecad2012-05-23 22:26:55 +0200107 else:
108 raise ValueError()
Nick Coghlandc9b2552012-05-20 21:01:57 +1000109
110 try:
111 return IPv4Network(address, strict)
112 except (AddressValueError, NetmaskValueError):
113 pass
114
115 try:
116 return IPv6Network(address, strict)
117 except (AddressValueError, NetmaskValueError):
118 pass
119
120 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
121 address)
122
123
124def ip_interface(address, version=None):
125 """Take an IP string/int and return an object of the correct type.
126
127 Args:
128 address: A string or integer, the IP address. Either IPv4 or
129 IPv6 addresses may be supplied; integers less than 2**32 will
130 be considered to be IPv4 by default.
Sandro Tosi876ecad2012-05-23 22:26:55 +0200131 version: An integer, 4 or 6. If set, don't try to automatically
132 determine what the IP address type is. Important for things
133 like ip_interface(1), which could be IPv4, '192.0.2.1/32', or IPv6,
Nick Coghlandc9b2552012-05-20 21:01:57 +1000134 '2001:db8::1/128'.
135
136 Returns:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200137 An IPv4Interface or IPv6Interface object.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000138
139 Raises:
140 ValueError: if the string passed isn't either a v4 or a v6
Sandro Tosi876ecad2012-05-23 22:26:55 +0200141 address. Or if the version is not None, 4, or 6.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000142
143 Notes:
144 The IPv?Interface classes describe an Address on a particular
145 Network, so they're basically a combination of both the Address
146 and Network classes.
Sandro Tosib95c6342012-05-23 23:17:22 +0200147
Nick Coghlandc9b2552012-05-20 21:01:57 +1000148 """
Sandro Tosi876ecad2012-05-23 22:26:55 +0200149 if version is not None:
Nick Coghlandc9b2552012-05-20 21:01:57 +1000150 if version == 4:
151 return IPv4Interface(address)
152 elif version == 6:
153 return IPv6Interface(address)
Sandro Tosi876ecad2012-05-23 22:26:55 +0200154 else:
155 raise ValueError()
Nick Coghlandc9b2552012-05-20 21:01:57 +1000156
157 try:
158 return IPv4Interface(address)
159 except (AddressValueError, NetmaskValueError):
160 pass
161
162 try:
163 return IPv6Interface(address)
164 except (AddressValueError, NetmaskValueError):
165 pass
166
167 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
168 address)
169
170
171def v4_int_to_packed(address):
Sandro Tosi876ecad2012-05-23 22:26:55 +0200172 """Represent an address as 4 packed bytes in network (big-endian) order.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000173
174 Args:
175 address: An integer representation of an IPv4 IP address.
176
177 Returns:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200178 The integer address packed as 4 bytes in network (big-endian) order.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000179
180 Raises:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200181 ValueError: If the integer is negative or too large to be an
182 IPv4 IP address.
Sandro Tosib95c6342012-05-23 23:17:22 +0200183
Nick Coghlandc9b2552012-05-20 21:01:57 +1000184 """
Sandro Tosi876ecad2012-05-23 22:26:55 +0200185 try:
186 return struct.pack('!I', address)
187 except:
188 raise ValueError("Address negative or too large for IPv4")
Nick Coghlandc9b2552012-05-20 21:01:57 +1000189
190
191def v6_int_to_packed(address):
Sandro Tosi876ecad2012-05-23 22:26:55 +0200192 """Represent an address as 16 packed bytes in network (big-endian) order.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000193
194 Args:
195 address: An integer representation of an IPv4 IP address.
196
197 Returns:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200198 The integer address packed as 16 bytes in network (big-endian) order.
Sandro Tosib95c6342012-05-23 23:17:22 +0200199
Nick Coghlandc9b2552012-05-20 21:01:57 +1000200 """
Sandro Tosi876ecad2012-05-23 22:26:55 +0200201 try:
202 return struct.pack('!QQ', address >> 64, address & (2**64 - 1))
203 except:
204 raise ValueError("Address negative or too large for IPv6")
Nick Coghlandc9b2552012-05-20 21:01:57 +1000205
206
207def _find_address_range(addresses):
Sandro Tosi876ecad2012-05-23 22:26:55 +0200208 """Find a sequence of IPv#Address.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000209
210 Args:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200211 addresses: a list of IPv#Address objects.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000212
213 Returns:
214 A tuple containing the first and last IP addresses in the sequence.
215
216 """
217 first = last = addresses[0]
218 for ip in addresses[1:]:
219 if ip._ip == last._ip + 1:
220 last = ip
221 else:
222 break
223 return (first, last)
224
Sandro Tosib95c6342012-05-23 23:17:22 +0200225
Nick Coghlandc9b2552012-05-20 21:01:57 +1000226def _get_prefix_length(number1, number2, bits):
227 """Get the number of leading bits that are same for two numbers.
228
229 Args:
230 number1: an integer.
231 number2: another integer.
232 bits: the maximum number of bits to compare.
233
234 Returns:
235 The number of leading bits that are the same for two numbers.
236
237 """
238 for i in range(bits):
239 if number1 >> i == number2 >> i:
240 return bits - i
241 return 0
242
Sandro Tosib95c6342012-05-23 23:17:22 +0200243
Nick Coghlandc9b2552012-05-20 21:01:57 +1000244def _count_righthand_zero_bits(number, bits):
245 """Count the number of zero bits on the right hand side.
246
247 Args:
248 number: an integer.
249 bits: maximum number of bits to count.
250
251 Returns:
252 The number of zero bits on the right hand side of the number.
253
254 """
255 if number == 0:
256 return bits
257 for i in range(bits):
258 if (number >> i) % 2:
259 return i
260
261
262def summarize_address_range(first, last):
263 """Summarize a network range given the first and last IP addresses.
264
265 Example:
266 >>> summarize_address_range(IPv4Address('192.0.2.0'),
267 IPv4Address('192.0.2.130'))
268 [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'),
269 IPv4Network('192.0.2.130/32')]
270
271 Args:
272 first: the first IPv4Address or IPv6Address in the range.
273 last: the last IPv4Address or IPv6Address in the range.
274
275 Returns:
276 An iterator of the summarized IPv(4|6) network objects.
277
278 Raise:
279 TypeError:
280 If the first and last objects are not IP addresses.
281 If the first and last objects are not the same version.
282 ValueError:
283 If the last object is not greater than the first.
284 If the version is not 4 or 6.
285
286 """
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200287 if (not (isinstance(first, _BaseAddress) and
288 isinstance(last, _BaseAddress))):
Nick Coghlandc9b2552012-05-20 21:01:57 +1000289 raise TypeError('first and last must be IP addresses, not networks')
290 if first.version != last.version:
291 raise TypeError("%s and %s are not of the same version" % (
292 str(first), str(last)))
293 if first > last:
294 raise ValueError('last IP address must be greater than first')
295
Nick Coghlandc9b2552012-05-20 21:01:57 +1000296 if first.version == 4:
297 ip = IPv4Network
298 elif first.version == 6:
299 ip = IPv6Network
300 else:
301 raise ValueError('unknown IP version')
302
303 ip_bits = first._max_prefixlen
304 first_int = first._ip
305 last_int = last._ip
306 while first_int <= last_int:
307 nbits = _count_righthand_zero_bits(first_int, ip_bits)
308 current = None
309 while nbits >= 0:
310 addend = 2**nbits - 1
311 current = first_int + addend
312 nbits -= 1
313 if current <= last_int:
314 break
315 prefix = _get_prefix_length(first_int, current, ip_bits)
316 net = ip('%s/%d' % (str(first), prefix))
317 yield net
Nick Coghlandc9b2552012-05-20 21:01:57 +1000318 if current == ip._ALL_ONES:
319 break
320 first_int = current + 1
321 first = ip_address(first_int, version=first._version)
322
Sandro Tosib95c6342012-05-23 23:17:22 +0200323
Nick Coghlandc9b2552012-05-20 21:01:57 +1000324def _collapse_addresses_recursive(addresses):
325 """Loops through the addresses, collapsing concurrent netblocks.
326
327 Example:
328
329 ip1 = IPv4Network('192.0.2.0/26')
330 ip2 = IPv4Network('192.0.2.64/26')
331 ip3 = IPv4Network('192.0.2.128/26')
332 ip4 = IPv4Network('192.0.2.192/26')
333
334 _collapse_addresses_recursive([ip1, ip2, ip3, ip4]) ->
335 [IPv4Network('192.0.2.0/24')]
336
337 This shouldn't be called directly; it is called via
338 collapse_addresses([]).
339
340 Args:
341 addresses: A list of IPv4Network's or IPv6Network's
342
343 Returns:
344 A list of IPv4Network's or IPv6Network's depending on what we were
345 passed.
346
347 """
348 ret_array = []
349 optimized = False
350
351 for cur_addr in addresses:
352 if not ret_array:
353 ret_array.append(cur_addr)
354 continue
355 if (cur_addr.network_address >= ret_array[-1].network_address and
356 cur_addr.broadcast_address <= ret_array[-1].broadcast_address):
357 optimized = True
358 elif cur_addr == list(ret_array[-1].supernet().subnets())[1]:
359 ret_array.append(ret_array.pop().supernet())
360 optimized = True
361 else:
362 ret_array.append(cur_addr)
363
364 if optimized:
365 return _collapse_addresses_recursive(ret_array)
366
367 return ret_array
368
369
370def collapse_addresses(addresses):
371 """Collapse a list of IP objects.
372
373 Example:
374 collapse_addresses([IPv4Network('192.0.2.0/25'),
375 IPv4Network('192.0.2.128/25')]) ->
376 [IPv4Network('192.0.2.0/24')]
377
378 Args:
379 addresses: An iterator of IPv4Network or IPv6Network objects.
380
381 Returns:
382 An iterator of the collapsed IPv(4|6)Network objects.
383
384 Raises:
385 TypeError: If passed a list of mixed version objects.
386
387 """
388 i = 0
389 addrs = []
390 ips = []
391 nets = []
392
393 # split IP addresses and networks
394 for ip in addresses:
395 if isinstance(ip, _BaseAddress):
396 if ips and ips[-1]._version != ip._version:
397 raise TypeError("%s and %s are not of the same version" % (
398 str(ip), str(ips[-1])))
399 ips.append(ip)
400 elif ip._prefixlen == ip._max_prefixlen:
401 if ips and ips[-1]._version != ip._version:
402 raise TypeError("%s and %s are not of the same version" % (
403 str(ip), str(ips[-1])))
404 try:
405 ips.append(ip.ip)
406 except AttributeError:
407 ips.append(ip.network_address)
408 else:
409 if nets and nets[-1]._version != ip._version:
410 raise TypeError("%s and %s are not of the same version" % (
411 str(ip), str(ips[-1])))
412 nets.append(ip)
413
414 # sort and dedup
415 ips = sorted(set(ips))
416 nets = sorted(set(nets))
417
418 while i < len(ips):
419 (first, last) = _find_address_range(ips[i:])
420 i = ips.index(last) + 1
421 addrs.extend(summarize_address_range(first, last))
422
423 return iter(_collapse_addresses_recursive(sorted(
424 addrs + nets, key=_BaseNetwork._get_networks_key)))
425
426
427def get_mixed_type_key(obj):
428 """Return a key suitable for sorting between networks and addresses.
429
430 Address and Network objects are not sortable by default; they're
431 fundamentally different so the expression
432
433 IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24')
434
435 doesn't make any sense. There are some times however, where you may wish
436 to have ipaddress sort these for you anyway. If you need to do this, you
437 can use this function as the key= argument to sorted().
438
439 Args:
440 obj: either a Network or Address object.
441 Returns:
442 appropriate key.
443
444 """
445 if isinstance(obj, _BaseNetwork):
446 return obj._get_networks_key()
447 elif isinstance(obj, _BaseAddress):
448 return obj._get_address_key()
449 return NotImplemented
450
451
452class _IPAddressBase(object):
453
454 """The mother class."""
455
456 @property
457 def exploded(self):
458 """Return the longhand version of the IP address as a string."""
459 return self._explode_shorthand_ip_string()
460
461 @property
462 def compressed(self):
463 """Return the shorthand version of the IP address as a string."""
464 return str(self)
465
466 def _ip_int_from_prefix(self, prefixlen=None):
467 """Turn the prefix length netmask into a int for comparison.
468
469 Args:
470 prefixlen: An integer, the prefix length.
471
472 Returns:
473 An integer.
474
475 """
476 if not prefixlen and prefixlen != 0:
477 prefixlen = self._prefixlen
478 return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
479
480 def _prefix_from_ip_int(self, ip_int, mask=32):
481 """Return prefix length from the decimal netmask.
482
483 Args:
484 ip_int: An integer, the IP address.
485 mask: The netmask. Defaults to 32.
486
487 Returns:
488 An integer, the prefix length.
489
490 """
491 while mask:
492 if ip_int & 1 == 1:
493 break
494 ip_int >>= 1
495 mask -= 1
496
497 return mask
498
499 def _ip_string_from_prefix(self, prefixlen=None):
500 """Turn a prefix length into a dotted decimal string.
501
502 Args:
503 prefixlen: An integer, the netmask prefix length.
504
505 Returns:
506 A string, the dotted decimal netmask string.
507
508 """
509 if not prefixlen:
510 prefixlen = self._prefixlen
511 return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
512
513
514class _BaseAddress(_IPAddressBase):
515
516 """A generic IP object.
517
518 This IP class contains the version independent methods which are
519 used by single IP addresses.
520
521 """
522
523 def __init__(self, address):
524 if (not isinstance(address, bytes)
525 and '/' in str(address)):
526 raise AddressValueError(address)
527
528 def __index__(self):
529 return self._ip
530
531 def __int__(self):
532 return self._ip
533
534 def __hex__(self):
535 return hex(self._ip)
536
537 def __eq__(self, other):
538 try:
539 return (self._ip == other._ip
540 and self._version == other._version)
541 except AttributeError:
542 return NotImplemented
543
544 def __ne__(self, other):
545 eq = self.__eq__(other)
546 if eq is NotImplemented:
547 return NotImplemented
548 return not eq
549
550 def __le__(self, other):
551 gt = self.__gt__(other)
552 if gt is NotImplemented:
553 return NotImplemented
554 return not gt
555
556 def __ge__(self, other):
557 lt = self.__lt__(other)
558 if lt is NotImplemented:
559 return NotImplemented
560 return not lt
561
562 def __lt__(self, other):
563 if self._version != other._version:
564 raise TypeError('%s and %s are not of the same version' % (
565 str(self), str(other)))
566 if not isinstance(other, _BaseAddress):
567 raise TypeError('%s and %s are not of the same type' % (
568 str(self), str(other)))
569 if self._ip != other._ip:
570 return self._ip < other._ip
571 return False
572
573 def __gt__(self, other):
574 if self._version != other._version:
575 raise TypeError('%s and %s are not of the same version' % (
576 str(self), str(other)))
577 if not isinstance(other, _BaseAddress):
578 raise TypeError('%s and %s are not of the same type' % (
579 str(self), str(other)))
580 if self._ip != other._ip:
581 return self._ip > other._ip
582 return False
583
584 # Shorthand for Integer addition and subtraction. This is not
585 # meant to ever support addition/subtraction of addresses.
586 def __add__(self, other):
587 if not isinstance(other, int):
588 return NotImplemented
589 return ip_address(int(self) + other, version=self._version)
590
591 def __sub__(self, other):
592 if not isinstance(other, int):
593 return NotImplemented
594 return ip_address(int(self) - other, version=self._version)
595
596 def __repr__(self):
597 return '%s(%r)' % (self.__class__.__name__, str(self))
598
599 def __str__(self):
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200600 return str(self._string_from_ip_int(self._ip))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000601
602 def __hash__(self):
603 return hash(hex(int(self._ip)))
604
605 def _get_address_key(self):
606 return (self._version, self)
607
608 @property
609 def version(self):
610 raise NotImplementedError('BaseIP has no version')
611
612
613class _BaseNetwork(_IPAddressBase):
614
615 """A generic IP object.
616
617 This IP class contains the version independent methods which are
618 used by networks.
619
620 """
621
622 def __init__(self, address):
623 self._cache = {}
624
625 def __index__(self):
626 return int(self.network_address) ^ self.prefixlen
627
628 def __int__(self):
629 return int(self.network_address)
630
631 def __repr__(self):
632 return '%s(%r)' % (self.__class__.__name__, str(self))
633
634 def hosts(self):
635 """Generate Iterator over usable hosts in a network.
636
Sandro Tosib95c6342012-05-23 23:17:22 +0200637 This is like __iter__ except it doesn't return the network
638 or broadcast addresses.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000639
640 """
641 cur = int(self.network_address) + 1
642 bcast = int(self.broadcast_address) - 1
643 while cur <= bcast:
644 cur += 1
645 yield ip_address(cur - 1, version=self._version)
646
647 def __iter__(self):
648 cur = int(self.network_address)
649 bcast = int(self.broadcast_address)
650 while cur <= bcast:
651 cur += 1
652 yield ip_address(cur - 1, version=self._version)
653
654 def __getitem__(self, n):
655 network = int(self.network_address)
656 broadcast = int(self.broadcast_address)
657 if n >= 0:
658 if network + n > broadcast:
659 raise IndexError
660 return ip_address(network + n, version=self._version)
661 else:
662 n += 1
663 if broadcast + n < network:
664 raise IndexError
665 return ip_address(broadcast + n, version=self._version)
666
667 def __lt__(self, other):
668 if self._version != other._version:
669 raise TypeError('%s and %s are not of the same version' % (
670 str(self), str(other)))
671 if not isinstance(other, _BaseNetwork):
672 raise TypeError('%s and %s are not of the same type' % (
673 str(self), str(other)))
674 if self.network_address != other.network_address:
675 return self.network_address < other.network_address
676 if self.netmask != other.netmask:
677 return self.netmask < other.netmask
678 return False
679
680 def __gt__(self, other):
681 if self._version != other._version:
682 raise TypeError('%s and %s are not of the same version' % (
683 str(self), str(other)))
684 if not isinstance(other, _BaseNetwork):
685 raise TypeError('%s and %s are not of the same type' % (
686 str(self), str(other)))
687 if self.network_address != other.network_address:
688 return self.network_address > other.network_address
689 if self.netmask != other.netmask:
690 return self.netmask > other.netmask
691 return False
692
693 def __le__(self, other):
694 gt = self.__gt__(other)
695 if gt is NotImplemented:
696 return NotImplemented
697 return not gt
698
699 def __ge__(self, other):
700 lt = self.__lt__(other)
701 if lt is NotImplemented:
702 return NotImplemented
703 return not lt
704
705 def __eq__(self, other):
706 if not isinstance(other, _BaseNetwork):
707 raise TypeError('%s and %s are not of the same type' % (
708 str(self), str(other)))
709 return (self._version == other._version and
710 self.network_address == other.network_address and
711 int(self.netmask) == int(other.netmask))
712
713 def __ne__(self, other):
714 eq = self.__eq__(other)
715 if eq is NotImplemented:
716 return NotImplemented
717 return not eq
718
719 def __str__(self):
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200720 return '%s/%s' % (self.ip, self._prefixlen)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000721
722 def __hash__(self):
723 return hash(int(self.network_address) ^ int(self.netmask))
724
725 def __contains__(self, other):
726 # always false if one is v4 and the other is v6.
727 if self._version != other._version:
728 return False
729 # dealing with another network.
730 if isinstance(other, _BaseNetwork):
731 return False
732 # dealing with another address
733 else:
734 # address
735 return (int(self.network_address) <= int(other._ip) <=
736 int(self.broadcast_address))
737
738 def overlaps(self, other):
739 """Tell if self is partly contained in other."""
740 return self.network_address in other or (
741 self.broadcast_address in other or (
742 other.network_address in self or (
743 other.broadcast_address in self)))
744
745 @property
746 def broadcast_address(self):
747 x = self._cache.get('broadcast_address')
748 if x is None:
749 x = ip_address(int(self.network_address) | int(self.hostmask),
750 version=self._version)
751 self._cache['broadcast_address'] = x
752 return x
753
754 @property
755 def hostmask(self):
756 x = self._cache.get('hostmask')
757 if x is None:
758 x = ip_address(int(self.netmask) ^ self._ALL_ONES,
759 version=self._version)
760 self._cache['hostmask'] = x
761 return x
762
763 @property
764 def network(self):
765 return ip_network('%s/%d' % (str(self.network_address),
766 self.prefixlen))
767
768 @property
769 def with_prefixlen(self):
770 return '%s/%d' % (str(self.ip), self._prefixlen)
771
772 @property
773 def with_netmask(self):
774 return '%s/%s' % (str(self.ip), str(self.netmask))
775
776 @property
777 def with_hostmask(self):
778 return '%s/%s' % (str(self.ip), str(self.hostmask))
779
780 @property
781 def num_addresses(self):
782 """Number of hosts in the current subnet."""
783 return int(self.broadcast_address) - int(self.network_address) + 1
784
785 @property
786 def version(self):
787 raise NotImplementedError('BaseNet has no version')
788
789 @property
790 def prefixlen(self):
791 return self._prefixlen
792
793 def address_exclude(self, other):
794 """Remove an address from a larger block.
795
796 For example:
797
798 addr1 = ip_network('192.0.2.0/28')
799 addr2 = ip_network('192.0.2.1/32')
800 addr1.address_exclude(addr2) =
801 [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'),
802 IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')]
803
804 or IPv6:
805
806 addr1 = ip_network('2001:db8::1/32')
807 addr2 = ip_network('2001:db8::1/128')
808 addr1.address_exclude(addr2) =
809 [ip_network('2001:db8::1/128'),
810 ip_network('2001:db8::2/127'),
811 ip_network('2001:db8::4/126'),
812 ip_network('2001:db8::8/125'),
813 ...
814 ip_network('2001:db8:8000::/33')]
815
816 Args:
817 other: An IPv4Network or IPv6Network object of the same type.
818
819 Returns:
820 An iterator of the the IPv(4|6)Network objects which is self
821 minus other.
822
823 Raises:
824 TypeError: If self and other are of difffering address
825 versions, or if other is not a network object.
826 ValueError: If other is not completely contained by self.
827
828 """
829 if not self._version == other._version:
830 raise TypeError("%s and %s are not of the same version" % (
831 str(self), str(other)))
832
833 if not isinstance(other, _BaseNetwork):
834 raise TypeError("%s is not a network object" % str(other))
835
836 if not (other.network_address >= self.network_address and
837 other.broadcast_address <= self.broadcast_address):
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200838 raise ValueError('%s not contained in %s' % (other, self))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000839 if other == self:
840 raise StopIteration
841
Nick Coghlandc9b2552012-05-20 21:01:57 +1000842 # Make sure we're comparing the network of other.
843 other = ip_network('%s/%s' % (str(other.network_address),
844 str(other.prefixlen)),
845 version=other._version)
846
847 s1, s2 = self.subnets()
848 while s1 != other and s2 != other:
849 if (other.network_address >= s1.network_address and
850 other.broadcast_address <= s1.broadcast_address):
851 yield s2
852 s1, s2 = s1.subnets()
853 elif (other.network_address >= s2.network_address and
854 other.broadcast_address <= s2.broadcast_address):
855 yield s1
856 s1, s2 = s2.subnets()
857 else:
858 # If we got here, there's a bug somewhere.
859 raise AssertionError('Error performing exclusion: '
860 's1: %s s2: %s other: %s' %
861 (str(s1), str(s2), str(other)))
862 if s1 == other:
863 yield s2
864 elif s2 == other:
865 yield s1
866 else:
867 # If we got here, there's a bug somewhere.
868 raise AssertionError('Error performing exclusion: '
869 's1: %s s2: %s other: %s' %
870 (str(s1), str(s2), str(other)))
871
872 def compare_networks(self, other):
873 """Compare two IP objects.
874
875 This is only concerned about the comparison of the integer
876 representation of the network addresses. This means that the
877 host bits aren't considered at all in this method. If you want
878 to compare host bits, you can easily enough do a
879 'HostA._ip < HostB._ip'
880
881 Args:
882 other: An IP object.
883
884 Returns:
885 If the IP versions of self and other are the same, returns:
886
887 -1 if self < other:
888 eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25')
889 IPv6Network('2001:db8::1000/124') <
890 IPv6Network('2001:db8::2000/124')
891 0 if self == other
892 eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24')
893 IPv6Network('2001:db8::1000/124') ==
894 IPv6Network('2001:db8::1000/124')
895 1 if self > other
896 eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25')
897 IPv6Network('2001:db8::2000/124') >
898 IPv6Network('2001:db8::1000/124')
899
900 Raises:
901 TypeError if the IP versions are different.
902
903 """
904 # does this need to raise a ValueError?
905 if self._version != other._version:
906 raise TypeError('%s and %s are not of the same type' % (
907 str(self), str(other)))
908 # self._version == other._version below here:
909 if self.network_address < other.network_address:
910 return -1
911 if self.network_address > other.network_address:
912 return 1
913 # self.network_address == other.network_address below here:
914 if self.netmask < other.netmask:
915 return -1
916 if self.netmask > other.netmask:
917 return 1
918 return 0
919
920 def _get_networks_key(self):
921 """Network-only key function.
922
923 Returns an object that identifies this address' network and
924 netmask. This function is a suitable "key" argument for sorted()
925 and list.sort().
926
927 """
928 return (self._version, self.network_address, self.netmask)
929
930 def subnets(self, prefixlen_diff=1, new_prefix=None):
931 """The subnets which join to make the current subnet.
932
933 In the case that self contains only one IP
934 (self._prefixlen == 32 for IPv4 or self._prefixlen == 128
935 for IPv6), yield an iterator with just ourself.
936
937 Args:
938 prefixlen_diff: An integer, the amount the prefix length
939 should be increased by. This should not be set if
940 new_prefix is also set.
941 new_prefix: The desired new prefix length. This must be a
942 larger number (smaller prefix) than the existing prefix.
943 This should not be set if prefixlen_diff is also set.
944
945 Returns:
946 An iterator of IPv(4|6) objects.
947
948 Raises:
949 ValueError: The prefixlen_diff is too small or too large.
950 OR
951 prefixlen_diff and new_prefix are both set or new_prefix
952 is a smaller number than the current prefix (smaller
953 number means a larger network)
954
955 """
956 if self._prefixlen == self._max_prefixlen:
957 yield self
958 return
959
960 if new_prefix is not None:
961 if new_prefix < self._prefixlen:
962 raise ValueError('new prefix must be longer')
963 if prefixlen_diff != 1:
964 raise ValueError('cannot set prefixlen_diff and new_prefix')
965 prefixlen_diff = new_prefix - self._prefixlen
966
967 if prefixlen_diff < 0:
968 raise ValueError('prefix length diff must be > 0')
969 new_prefixlen = self._prefixlen + prefixlen_diff
970
971 if not self._is_valid_netmask(str(new_prefixlen)):
972 raise ValueError(
973 'prefix length diff %d is invalid for netblock %s' % (
974 new_prefixlen, str(self)))
975
976 first = ip_network('%s/%s' % (str(self.network_address),
977 str(self._prefixlen + prefixlen_diff)),
978 version=self._version)
979
980 yield first
981 current = first
982 while True:
983 broadcast = current.broadcast_address
984 if broadcast == self.broadcast_address:
985 return
986 new_addr = ip_address(int(broadcast) + 1, version=self._version)
987 current = ip_network('%s/%s' % (str(new_addr), str(new_prefixlen)),
988 version=self._version)
989
990 yield current
991
992 def masked(self):
993 """Return the network object with the host bits masked out."""
994 return ip_network('%s/%d' % (self.network_address, self._prefixlen),
995 version=self._version)
996
997 def supernet(self, prefixlen_diff=1, new_prefix=None):
998 """The supernet containing the current network.
999
1000 Args:
1001 prefixlen_diff: An integer, the amount the prefix length of
1002 the network should be decreased by. For example, given a
1003 /24 network and a prefixlen_diff of 3, a supernet with a
1004 /21 netmask is returned.
1005
1006 Returns:
1007 An IPv4 network object.
1008
1009 Raises:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001010 ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have
1011 a negative prefix length.
Nick Coghlandc9b2552012-05-20 21:01:57 +10001012 OR
1013 If prefixlen_diff and new_prefix are both set or new_prefix is a
1014 larger number than the current prefix (larger number means a
1015 smaller network)
1016
1017 """
1018 if self._prefixlen == 0:
1019 return self
1020
1021 if new_prefix is not None:
1022 if new_prefix > self._prefixlen:
1023 raise ValueError('new prefix must be shorter')
1024 if prefixlen_diff != 1:
1025 raise ValueError('cannot set prefixlen_diff and new_prefix')
1026 prefixlen_diff = self._prefixlen - new_prefix
1027
Nick Coghlandc9b2552012-05-20 21:01:57 +10001028 if self.prefixlen - prefixlen_diff < 0:
1029 raise ValueError(
1030 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
1031 (self.prefixlen, prefixlen_diff))
1032 # TODO (pmoody): optimize this.
1033 t = ip_network('%s/%d' % (str(self.network_address),
1034 self.prefixlen - prefixlen_diff),
1035 version=self._version, strict=False)
1036 return ip_network('%s/%d' % (str(t.network_address), t.prefixlen),
1037 version=t._version)
1038
1039
1040class _BaseV4(object):
1041
1042 """Base IPv4 object.
1043
1044 The following methods are used by IPv4 objects in both single IP
1045 addresses and networks.
1046
1047 """
1048
1049 # Equivalent to 255.255.255.255 or 32 bits of 1's.
1050 _ALL_ONES = (2**IPV4LENGTH) - 1
1051 _DECIMAL_DIGITS = frozenset('0123456789')
1052
1053 def __init__(self, address):
1054 self._version = 4
1055 self._max_prefixlen = IPV4LENGTH
1056
1057 def _explode_shorthand_ip_string(self):
1058 return str(self)
1059
1060 def _ip_int_from_string(self, ip_str):
1061 """Turn the given IP string into an integer for comparison.
1062
1063 Args:
1064 ip_str: A string, the IP ip_str.
1065
1066 Returns:
1067 The IP ip_str as an integer.
1068
1069 Raises:
1070 AddressValueError: if ip_str isn't a valid IPv4 Address.
1071
1072 """
1073 octets = ip_str.split('.')
1074 if len(octets) != 4:
1075 raise AddressValueError(ip_str)
1076
1077 packed_ip = 0
1078 for oc in octets:
1079 try:
1080 packed_ip = (packed_ip << 8) | self._parse_octet(oc)
1081 except ValueError:
1082 raise AddressValueError(ip_str)
1083 return packed_ip
1084
1085 def _parse_octet(self, octet_str):
1086 """Convert a decimal octet into an integer.
1087
1088 Args:
1089 octet_str: A string, the number to parse.
1090
1091 Returns:
1092 The octet as an integer.
1093
1094 Raises:
1095 ValueError: if the octet isn't strictly a decimal from [0..255].
1096
1097 """
1098 # Whitelist the characters, since int() allows a lot of bizarre stuff.
1099 if not self._DECIMAL_DIGITS.issuperset(octet_str):
1100 raise ValueError
1101 octet_int = int(octet_str, 10)
1102 # Disallow leading zeroes, because no clear standard exists on
1103 # whether these should be interpreted as decimal or octal.
1104 if octet_int > 255 or (octet_str[0] == '0' and len(octet_str) > 1):
1105 raise ValueError
1106 return octet_int
1107
1108 def _string_from_ip_int(self, ip_int):
1109 """Turns a 32-bit integer into dotted decimal notation.
1110
1111 Args:
1112 ip_int: An integer, the IP address.
1113
1114 Returns:
1115 The IP address as a string in dotted decimal notation.
1116
1117 """
1118 octets = []
1119 for _ in range(4):
1120 octets.insert(0, str(ip_int & 0xFF))
1121 ip_int >>= 8
1122 return '.'.join(octets)
1123
1124 @property
1125 def max_prefixlen(self):
1126 return self._max_prefixlen
1127
1128 @property
1129 def version(self):
1130 return self._version
1131
1132 @property
1133 def is_reserved(self):
1134 """Test if the address is otherwise IETF reserved.
1135
1136 Returns:
1137 A boolean, True if the address is within the
1138 reserved IPv4 Network range.
1139
1140 """
1141 reserved_network = IPv4Network('240.0.0.0/4')
1142 if isinstance(self, _BaseAddress):
1143 return self in reserved_network
1144 return (self.network_address in reserved_network and
1145 self.broadcast_address in reserved_network)
1146
1147 @property
1148 def is_private(self):
1149 """Test if this address is allocated for private networks.
1150
1151 Returns:
1152 A boolean, True if the address is reserved per RFC 1918.
1153
1154 """
1155 private_10 = IPv4Network('10.0.0.0/8')
1156 private_172 = IPv4Network('172.16.0.0/12')
1157 private_192 = IPv4Network('192.168.0.0/16')
1158 if isinstance(self, _BaseAddress):
1159 return (self in private_10 or self in private_172 or
1160 self in private_192)
1161 else:
1162 return ((self.network_address in private_10 and
1163 self.broadcast_address in private_10) or
1164 (self.network_address in private_172 and
1165 self.broadcast_address in private_172) or
1166 (self.network_address in private_192 and
1167 self.broadcast_address in private_192))
1168
1169 @property
1170 def is_multicast(self):
1171 """Test if the address is reserved for multicast use.
1172
1173 Returns:
1174 A boolean, True if the address is multicast.
1175 See RFC 3171 for details.
1176
1177 """
1178 multicast_network = IPv4Network('224.0.0.0/4')
1179 if isinstance(self, _BaseAddress):
1180 return self in IPv4Network('224.0.0.0/4')
1181 return (self.network_address in multicast_network and
1182 self.broadcast_address in multicast_network)
1183
1184 @property
1185 def is_unspecified(self):
1186 """Test if the address is unspecified.
1187
1188 Returns:
1189 A boolean, True if this is the unspecified address as defined in
1190 RFC 5735 3.
1191
1192 """
1193 unspecified_address = IPv4Address('0.0.0.0')
1194 if isinstance(self, _BaseAddress):
1195 return self in unspecified_address
1196 return (self.network_address == self.broadcast_address ==
1197 unspecified_address)
1198
1199 @property
1200 def is_loopback(self):
1201 """Test if the address is a loopback address.
1202
1203 Returns:
1204 A boolean, True if the address is a loopback per RFC 3330.
1205
1206 """
1207 loopback_address = IPv4Network('127.0.0.0/8')
1208 if isinstance(self, _BaseAddress):
1209 return self in loopback_address
1210
1211 return (self.network_address in loopback_address and
1212 self.broadcast_address in loopback_address)
1213
1214 @property
1215 def is_link_local(self):
1216 """Test if the address is reserved for link-local.
1217
1218 Returns:
1219 A boolean, True if the address is link-local per RFC 3927.
1220
1221 """
1222 linklocal_network = IPv4Network('169.254.0.0/16')
1223 if isinstance(self, _BaseAddress):
1224 return self in linklocal_network
1225 return (self.network_address in linklocal_network and
1226 self.broadcast_address in linklocal_network)
1227
1228
1229class IPv4Address(_BaseV4, _BaseAddress):
1230
1231 """Represent and manipulate single IPv4 Addresses."""
1232
1233 def __init__(self, address):
1234
1235 """
1236 Args:
1237 address: A string or integer representing the IP
1238
1239 Additionally, an integer can be passed, so
1240 IPv4Address('192.0.2.1') == IPv4Address(3221225985).
1241 or, more generally
1242 IPv4Address(int(IPv4Address('192.0.2.1'))) ==
1243 IPv4Address('192.0.2.1')
1244
1245 Raises:
1246 AddressValueError: If ipaddressisn't a valid IPv4 address.
1247
1248 """
1249 _BaseAddress.__init__(self, address)
1250 _BaseV4.__init__(self, address)
1251
1252 # Efficient constructor from integer.
1253 if isinstance(address, int):
1254 self._ip = address
1255 if address < 0 or address > self._ALL_ONES:
1256 raise AddressValueError(address)
1257 return
1258
1259 # Constructing from a packed address
1260 if isinstance(address, bytes) and len(address) == 4:
1261 self._ip = struct.unpack('!I', address)[0]
1262 return
1263
1264 # Assume input argument to be string or any object representation
1265 # which converts into a formatted IP string.
1266 addr_str = str(address)
1267 self._ip = self._ip_int_from_string(addr_str)
1268
1269 @property
1270 def packed(self):
1271 """The binary representation of this address."""
1272 return v4_int_to_packed(self._ip)
1273
1274
1275class IPv4Interface(IPv4Address):
1276
1277 # the valid octets for host and netmasks. only useful for IPv4.
1278 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1279
1280 def __init__(self, address):
1281 if isinstance(address, (bytes, int)):
1282 IPv4Address.__init__(self, address)
1283 self.network = IPv4Network(self._ip)
1284 self._prefixlen = self._max_prefixlen
1285 return
1286
1287 addr = str(address).split('/')
1288 if len(addr) > 2:
1289 raise AddressValueError(address)
1290 IPv4Address.__init__(self, addr[0])
1291
1292 self.network = IPv4Network(address, strict=False)
1293 self._prefixlen = self.network._prefixlen
1294
1295 self.netmask = self.network.netmask
1296 self.hostmask = self.network.hostmask
1297
Nick Coghlandc9b2552012-05-20 21:01:57 +10001298 def __str__(self):
1299 return '%s/%d' % (self._string_from_ip_int(self._ip),
1300 self.network.prefixlen)
1301
1302 def __eq__(self, other):
1303 try:
1304 return (IPv4Address.__eq__(self, other) and
1305 self.network == other.network)
1306 except AttributeError:
1307 return NotImplemented
1308
1309 def __hash__(self):
1310 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
1311
1312 def _is_valid_netmask(self, netmask):
1313 """Verify that the netmask is valid.
1314
1315 Args:
1316 netmask: A string, either a prefix or dotted decimal
1317 netmask.
1318
1319 Returns:
1320 A boolean, True if the prefix represents a valid IPv4
1321 netmask.
1322
1323 """
1324 mask = netmask.split('.')
1325 if len(mask) == 4:
1326 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1327 return False
1328 if [y for idx, y in enumerate(mask) if idx > 0 and
1329 y > mask[idx - 1]]:
1330 return False
1331 return True
1332 try:
1333 netmask = int(netmask)
1334 except ValueError:
1335 return False
1336 return 0 <= netmask <= self._max_prefixlen
1337
1338 def _is_hostmask(self, ip_str):
1339 """Test if the IP string is a hostmask (rather than a netmask).
1340
1341 Args:
1342 ip_str: A string, the potential hostmask.
1343
1344 Returns:
1345 A boolean, True if the IP string is a hostmask.
1346
1347 """
1348 bits = ip_str.split('.')
1349 try:
1350 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1351 except ValueError:
1352 return False
1353 if len(parts) != len(bits):
1354 return False
1355 if parts[0] < parts[-1]:
1356 return True
1357 return False
1358
Nick Coghlandc9b2552012-05-20 21:01:57 +10001359 @property
1360 def prefixlen(self):
1361 return self._prefixlen
1362
1363 @property
1364 def ip(self):
1365 return IPv4Address(self._ip)
1366
1367 @property
1368 def with_prefixlen(self):
1369 return self
1370
1371 @property
1372 def with_netmask(self):
1373 return '%s/%s' % (self._string_from_ip_int(self._ip),
1374 self.netmask)
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001375
Nick Coghlandc9b2552012-05-20 21:01:57 +10001376 @property
1377 def with_hostmask(self):
1378 return '%s/%s' % (self._string_from_ip_int(self._ip),
1379 self.hostmask)
1380
1381
1382class IPv4Network(_BaseV4, _BaseNetwork):
1383
1384 """This class represents and manipulates 32-bit IPv4 network + addresses..
1385
1386 Attributes: [examples for IPv4Network('192.0.2.0/27')]
1387 .network_address: IPv4Address('192.0.2.0')
1388 .hostmask: IPv4Address('0.0.0.31')
1389 .broadcast_address: IPv4Address('192.0.2.32')
1390 .netmask: IPv4Address('255.255.255.224')
1391 .prefixlen: 27
1392
1393 """
1394
1395 # the valid octets for host and netmasks. only useful for IPv4.
1396 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1397
1398 def __init__(self, address, strict=True):
1399
1400 """Instantiate a new IPv4 network object.
1401
1402 Args:
1403 address: A string or integer representing the IP [& network].
1404 '192.0.2.0/24'
1405 '192.0.2.0/255.255.255.0'
1406 '192.0.0.2/0.0.0.255'
1407 are all functionally the same in IPv4. Similarly,
1408 '192.0.2.1'
1409 '192.0.2.1/255.255.255.255'
1410 '192.0.2.1/32'
1411 are also functionaly equivalent. That is to say, failing to
1412 provide a subnetmask will create an object with a mask of /32.
1413
1414 If the mask (portion after the / in the argument) is given in
1415 dotted quad form, it is treated as a netmask if it starts with a
1416 non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
1417 starts with a zero field (e.g. 0.255.255.255 == /8), with the
1418 single exception of an all-zero mask which is treated as a
1419 netmask == /0. If no mask is given, a default of /32 is used.
1420
1421 Additionally, an integer can be passed, so
1422 IPv4Network('192.0.2.1') == IPv4Network(3221225985)
1423 or, more generally
1424 IPv4Interface(int(IPv4Interface('192.0.2.1'))) ==
1425 IPv4Interface('192.0.2.1')
1426
1427 Raises:
1428 AddressValueError: If ipaddressisn't a valid IPv4 address.
1429 NetmaskValueError: If the netmask isn't valid for
1430 an IPv4 address.
1431 ValueError: If strict was True and a network address was not
1432 supplied.
1433
1434 """
1435
1436 _BaseV4.__init__(self, address)
1437 _BaseNetwork.__init__(self, address)
1438
1439 # Constructing from a packed address
1440 if isinstance(address, bytes) and len(address) == 4:
1441 self.network_address = IPv4Address(
1442 struct.unpack('!I', address)[0])
1443 self._prefixlen = self._max_prefixlen
1444 self.netmask = IPv4Address(self._ALL_ONES)
1445 #fixme: address/network test here
1446 return
1447
1448 # Efficient constructor from integer.
1449 if isinstance(address, int):
1450 self._prefixlen = self._max_prefixlen
1451 self.netmask = IPv4Address(self._ALL_ONES)
1452 if address < 0 or address > self._ALL_ONES:
1453 raise AddressValueError(address)
1454 self.network_address = IPv4Address(address)
1455 #fixme: address/network test here.
1456 return
1457
1458 # Assume input argument to be string or any object representation
1459 # which converts into a formatted IP prefix string.
1460 addr = str(address).split('/')
1461 self.network_address = IPv4Address(self._ip_int_from_string(addr[0]))
1462
1463 if len(addr) > 2:
1464 raise AddressValueError(address)
1465
1466 if len(addr) == 2:
1467 mask = addr[1].split('.')
1468
1469 if len(mask) == 4:
1470 # We have dotted decimal netmask.
1471 if self._is_valid_netmask(addr[1]):
1472 self.netmask = IPv4Address(self._ip_int_from_string(
1473 addr[1]))
1474 elif self._is_hostmask(addr[1]):
1475 self.netmask = IPv4Address(
1476 self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
1477 else:
1478 raise NetmaskValueError('%s is not a valid netmask'
1479 % addr[1])
1480
1481 self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
1482 else:
1483 # We have a netmask in prefix length form.
1484 if not self._is_valid_netmask(addr[1]):
1485 raise NetmaskValueError(addr[1])
1486 self._prefixlen = int(addr[1])
1487 self.netmask = IPv4Address(self._ip_int_from_prefix(
1488 self._prefixlen))
1489 else:
1490 self._prefixlen = self._max_prefixlen
1491 self.netmask = IPv4Address(self._ip_int_from_prefix(
1492 self._prefixlen))
1493
1494 if strict:
1495 if (IPv4Address(int(self.network_address) & int(self.netmask)) !=
1496 self.network_address):
1497 raise ValueError('%s has host bits set' % self)
1498 self.network_address = IPv4Address(int(self.network_address) &
1499 int(self.netmask))
1500
1501 if self._prefixlen == (self._max_prefixlen - 1):
1502 self.hosts = self.__iter__
1503
1504 @property
1505 def packed(self):
1506 """The binary representation of this address."""
1507 return v4_int_to_packed(self.network_address)
1508
1509 def __str__(self):
1510 return '%s/%d' % (str(self.network_address),
1511 self.prefixlen)
1512
1513 def _is_valid_netmask(self, netmask):
1514 """Verify that the netmask is valid.
1515
1516 Args:
1517 netmask: A string, either a prefix or dotted decimal
1518 netmask.
1519
1520 Returns:
1521 A boolean, True if the prefix represents a valid IPv4
1522 netmask.
1523
1524 """
1525 mask = netmask.split('.')
1526 if len(mask) == 4:
1527 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1528 return False
1529 if [y for idx, y in enumerate(mask) if idx > 0 and
1530 y > mask[idx - 1]]:
1531 return False
1532 return True
1533 try:
1534 netmask = int(netmask)
1535 except ValueError:
1536 return False
1537 return 0 <= netmask <= self._max_prefixlen
1538
1539 def _is_hostmask(self, ip_str):
1540 """Test if the IP string is a hostmask (rather than a netmask).
1541
1542 Args:
1543 ip_str: A string, the potential hostmask.
1544
1545 Returns:
1546 A boolean, True if the IP string is a hostmask.
1547
1548 """
1549 bits = ip_str.split('.')
1550 try:
1551 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1552 except ValueError:
1553 return False
1554 if len(parts) != len(bits):
1555 return False
1556 if parts[0] < parts[-1]:
1557 return True
1558 return False
1559
1560 @property
1561 def with_prefixlen(self):
1562 return '%s/%d' % (str(self.network_address), self._prefixlen)
1563
1564 @property
1565 def with_netmask(self):
1566 return '%s/%s' % (str(self.network_address), str(self.netmask))
1567
1568 @property
1569 def with_hostmask(self):
1570 return '%s/%s' % (str(self.network_address), str(self.hostmask))
1571
1572
1573class _BaseV6(object):
1574
1575 """Base IPv6 object.
1576
1577 The following methods are used by IPv6 objects in both single IP
1578 addresses and networks.
1579
1580 """
1581
1582 _ALL_ONES = (2**IPV6LENGTH) - 1
1583 _HEXTET_COUNT = 8
1584 _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef')
1585
1586 def __init__(self, address):
1587 self._version = 6
1588 self._max_prefixlen = IPV6LENGTH
1589
1590 def _ip_int_from_string(self, ip_str):
1591 """Turn an IPv6 ip_str into an integer.
1592
1593 Args:
1594 ip_str: A string, the IPv6 ip_str.
1595
1596 Returns:
1597 An int, the IPv6 address
1598
1599 Raises:
1600 AddressValueError: if ip_str isn't a valid IPv6 Address.
1601
1602 """
1603 parts = ip_str.split(':')
1604
1605 # An IPv6 address needs at least 2 colons (3 parts).
1606 if len(parts) < 3:
1607 raise AddressValueError(ip_str)
1608
1609 # If the address has an IPv4-style suffix, convert it to hexadecimal.
1610 if '.' in parts[-1]:
1611 ipv4_int = IPv4Address(parts.pop())._ip
1612 parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF))
1613 parts.append('%x' % (ipv4_int & 0xFFFF))
1614
1615 # An IPv6 address can't have more than 8 colons (9 parts).
1616 if len(parts) > self._HEXTET_COUNT + 1:
1617 raise AddressValueError(ip_str)
1618
1619 # Disregarding the endpoints, find '::' with nothing in between.
1620 # This indicates that a run of zeroes has been skipped.
1621 try:
1622 skip_index, = (
1623 [i for i in range(1, len(parts) - 1) if not parts[i]] or
1624 [None])
1625 except ValueError:
1626 # Can't have more than one '::'
1627 raise AddressValueError(ip_str)
1628
1629 # parts_hi is the number of parts to copy from above/before the '::'
1630 # parts_lo is the number of parts to copy from below/after the '::'
1631 if skip_index is not None:
1632 # If we found a '::', then check if it also covers the endpoints.
1633 parts_hi = skip_index
1634 parts_lo = len(parts) - skip_index - 1
1635 if not parts[0]:
1636 parts_hi -= 1
1637 if parts_hi:
1638 raise AddressValueError(ip_str) # ^: requires ^::
1639 if not parts[-1]:
1640 parts_lo -= 1
1641 if parts_lo:
1642 raise AddressValueError(ip_str) # :$ requires ::$
1643 parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo)
1644 if parts_skipped < 1:
1645 raise AddressValueError(ip_str)
1646 else:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001647 # Otherwise, allocate the entire address to parts_hi. The
1648 # endpoints could still be empty, but _parse_hextet() will check
1649 # for that.
Nick Coghlandc9b2552012-05-20 21:01:57 +10001650 if len(parts) != self._HEXTET_COUNT:
1651 raise AddressValueError(ip_str)
1652 parts_hi = len(parts)
1653 parts_lo = 0
1654 parts_skipped = 0
1655
1656 try:
1657 # Now, parse the hextets into a 128-bit integer.
1658 ip_int = 0
1659 for i in range(parts_hi):
1660 ip_int <<= 16
1661 ip_int |= self._parse_hextet(parts[i])
1662 ip_int <<= 16 * parts_skipped
1663 for i in range(-parts_lo, 0):
1664 ip_int <<= 16
1665 ip_int |= self._parse_hextet(parts[i])
1666 return ip_int
1667 except ValueError:
1668 raise AddressValueError(ip_str)
1669
1670 def _parse_hextet(self, hextet_str):
1671 """Convert an IPv6 hextet string into an integer.
1672
1673 Args:
1674 hextet_str: A string, the number to parse.
1675
1676 Returns:
1677 The hextet as an integer.
1678
1679 Raises:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001680 ValueError: if the input isn't strictly a hex number from
1681 [0..FFFF].
Nick Coghlandc9b2552012-05-20 21:01:57 +10001682
1683 """
1684 # Whitelist the characters, since int() allows a lot of bizarre stuff.
1685 if not self._HEX_DIGITS.issuperset(hextet_str):
1686 raise ValueError
1687 hextet_int = int(hextet_str, 16)
1688 if hextet_int > 0xFFFF:
1689 raise ValueError
1690 return hextet_int
1691
1692 def _compress_hextets(self, hextets):
1693 """Compresses a list of hextets.
1694
1695 Compresses a list of strings, replacing the longest continuous
1696 sequence of "0" in the list with "" and adding empty strings at
1697 the beginning or at the end of the string such that subsequently
1698 calling ":".join(hextets) will produce the compressed version of
1699 the IPv6 address.
1700
1701 Args:
1702 hextets: A list of strings, the hextets to compress.
1703
1704 Returns:
1705 A list of strings.
1706
1707 """
1708 best_doublecolon_start = -1
1709 best_doublecolon_len = 0
1710 doublecolon_start = -1
1711 doublecolon_len = 0
1712 for index in range(len(hextets)):
1713 if hextets[index] == '0':
1714 doublecolon_len += 1
1715 if doublecolon_start == -1:
1716 # Start of a sequence of zeros.
1717 doublecolon_start = index
1718 if doublecolon_len > best_doublecolon_len:
1719 # This is the longest sequence of zeros so far.
1720 best_doublecolon_len = doublecolon_len
1721 best_doublecolon_start = doublecolon_start
1722 else:
1723 doublecolon_len = 0
1724 doublecolon_start = -1
1725
1726 if best_doublecolon_len > 1:
1727 best_doublecolon_end = (best_doublecolon_start +
1728 best_doublecolon_len)
1729 # For zeros at the end of the address.
1730 if best_doublecolon_end == len(hextets):
1731 hextets += ['']
1732 hextets[best_doublecolon_start:best_doublecolon_end] = ['']
1733 # For zeros at the beginning of the address.
1734 if best_doublecolon_start == 0:
1735 hextets = [''] + hextets
1736
1737 return hextets
1738
1739 def _string_from_ip_int(self, ip_int=None):
1740 """Turns a 128-bit integer into hexadecimal notation.
1741
1742 Args:
1743 ip_int: An integer, the IP address.
1744
1745 Returns:
1746 A string, the hexadecimal representation of the address.
1747
1748 Raises:
1749 ValueError: The address is bigger than 128 bits of all ones.
1750
1751 """
1752 if not ip_int and ip_int != 0:
1753 ip_int = int(self._ip)
1754
1755 if ip_int > self._ALL_ONES:
1756 raise ValueError('IPv6 address is too large')
1757
1758 hex_str = '%032x' % ip_int
1759 hextets = []
1760 for x in range(0, 32, 4):
1761 hextets.append('%x' % int(hex_str[x:x+4], 16))
1762
1763 hextets = self._compress_hextets(hextets)
1764 return ':'.join(hextets)
1765
1766 def _explode_shorthand_ip_string(self):
1767 """Expand a shortened IPv6 address.
1768
1769 Args:
1770 ip_str: A string, the IPv6 address.
1771
1772 Returns:
1773 A string, the expanded IPv6 address.
1774
1775 """
1776 if isinstance(self, IPv6Network):
1777 ip_str = str(self.network_address)
1778 elif isinstance(self, IPv6Interface):
1779 ip_str = str(self.ip)
1780 else:
1781 ip_str = str(self)
1782
1783 ip_int = self._ip_int_from_string(ip_str)
1784 parts = []
1785 for i in range(self._HEXTET_COUNT):
1786 parts.append('%04x' % (ip_int & 0xFFFF))
1787 ip_int >>= 16
1788 parts.reverse()
1789 if isinstance(self, (_BaseNetwork, IPv6Interface)):
1790 return '%s/%d' % (':'.join(parts), self.prefixlen)
1791 return ':'.join(parts)
1792
1793 @property
1794 def max_prefixlen(self):
1795 return self._max_prefixlen
1796
1797 @property
1798 def packed(self):
1799 """The binary representation of this address."""
1800 return v6_int_to_packed(self._ip)
1801
1802 @property
1803 def version(self):
1804 return self._version
1805
1806 @property
1807 def is_multicast(self):
1808 """Test if the address is reserved for multicast use.
1809
1810 Returns:
1811 A boolean, True if the address is a multicast address.
1812 See RFC 2373 2.7 for details.
1813
1814 """
1815 multicast_network = IPv6Network('ff00::/8')
1816 if isinstance(self, _BaseAddress):
1817 return self in multicast_network
1818 return (self.network_address in multicast_network and
1819 self.broadcast_address in multicast_network)
1820
1821 @property
1822 def is_reserved(self):
1823 """Test if the address is otherwise IETF reserved.
1824
1825 Returns:
1826 A boolean, True if the address is within one of the
1827 reserved IPv6 Network ranges.
1828
1829 """
1830 reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'),
1831 IPv6Network('200::/7'), IPv6Network('400::/6'),
1832 IPv6Network('800::/5'), IPv6Network('1000::/4'),
1833 IPv6Network('4000::/3'), IPv6Network('6000::/3'),
1834 IPv6Network('8000::/3'), IPv6Network('A000::/3'),
1835 IPv6Network('C000::/3'), IPv6Network('E000::/4'),
1836 IPv6Network('F000::/5'), IPv6Network('F800::/6'),
1837 IPv6Network('FE00::/9')]
1838
1839 if isinstance(self, _BaseAddress):
1840 return len([x for x in reserved_networks if self in x]) > 0
1841 return len([x for x in reserved_networks if self.network_address in x
1842 and self.broadcast_address in x]) > 0
1843
1844 @property
1845 def is_link_local(self):
1846 """Test if the address is reserved for link-local.
1847
1848 Returns:
1849 A boolean, True if the address is reserved per RFC 4291.
1850
1851 """
1852 linklocal_network = IPv6Network('fe80::/10')
1853 if isinstance(self, _BaseAddress):
1854 return self in linklocal_network
1855 return (self.network_address in linklocal_network and
1856 self.broadcast_address in linklocal_network)
1857
1858 @property
1859 def is_site_local(self):
1860 """Test if the address is reserved for site-local.
1861
1862 Note that the site-local address space has been deprecated by RFC 3879.
1863 Use is_private to test if this address is in the space of unique local
1864 addresses as defined by RFC 4193.
1865
1866 Returns:
1867 A boolean, True if the address is reserved per RFC 3513 2.5.6.
1868
1869 """
1870 sitelocal_network = IPv6Network('fec0::/10')
1871 if isinstance(self, _BaseAddress):
1872 return self in sitelocal_network
1873 return (self.network_address in sitelocal_network and
1874 self.broadcast_address in sitelocal_network)
1875
1876 @property
1877 def is_private(self):
1878 """Test if this address is allocated for private networks.
1879
1880 Returns:
1881 A boolean, True if the address is reserved per RFC 4193.
1882
1883 """
1884 private_network = IPv6Network('fc00::/7')
1885 if isinstance(self, _BaseAddress):
1886 return self in private_network
1887 return (self.network_address in private_network and
1888 self.broadcast_address in private_network)
1889
Nick Coghlandc9b2552012-05-20 21:01:57 +10001890 @property
1891 def ipv4_mapped(self):
1892 """Return the IPv4 mapped address.
1893
1894 Returns:
1895 If the IPv6 address is a v4 mapped address, return the
1896 IPv4 mapped address. Return None otherwise.
1897
1898 """
1899 if (self._ip >> 32) != 0xFFFF:
1900 return None
1901 return IPv4Address(self._ip & 0xFFFFFFFF)
1902
1903 @property
1904 def teredo(self):
1905 """Tuple of embedded teredo IPs.
1906
1907 Returns:
1908 Tuple of the (server, client) IPs or None if the address
1909 doesn't appear to be a teredo address (doesn't start with
1910 2001::/32)
1911
1912 """
1913 if (self._ip >> 96) != 0x20010000:
1914 return None
1915 return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
1916 IPv4Address(~self._ip & 0xFFFFFFFF))
1917
1918 @property
1919 def sixtofour(self):
1920 """Return the IPv4 6to4 embedded address.
1921
1922 Returns:
1923 The IPv4 6to4-embedded address if present or None if the
1924 address doesn't appear to contain a 6to4 embedded address.
1925
1926 """
1927 if (self._ip >> 112) != 0x2002:
1928 return None
1929 return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
1930
1931 @property
1932 def is_unspecified(self):
1933 """Test if the address is unspecified.
1934
1935 Returns:
1936 A boolean, True if this is the unspecified address as defined in
1937 RFC 2373 2.5.2.
1938
1939 """
1940 if isinstance(self, (IPv6Network, IPv6Interface)):
1941 return int(self.network_address) == 0 and getattr(
1942 self, '_prefixlen', 128) == 128
1943 return self._ip == 0
1944
1945 @property
1946 def is_loopback(self):
1947 """Test if the address is a loopback address.
1948
1949 Returns:
1950 A boolean, True if the address is a loopback address as defined in
1951 RFC 2373 2.5.3.
1952
1953 """
1954 if isinstance(self, IPv6Network):
1955 return int(self.network) == 1 and getattr(
1956 self, '_prefixlen', 128) == 128
1957 elif isinstance(self, IPv6Interface):
1958 return int(self.network.network_address) == 1 and getattr(
1959 self, '_prefixlen', 128) == 128
1960 return self._ip == 1
1961
1962
1963class IPv6Address(_BaseV6, _BaseAddress):
1964
Sandro Tosib95c6342012-05-23 23:17:22 +02001965 """Represent and manipulate single IPv6 Addresses."""
Nick Coghlandc9b2552012-05-20 21:01:57 +10001966
1967 def __init__(self, address):
1968 """Instantiate a new IPv6 address object.
1969
1970 Args:
1971 address: A string or integer representing the IP
1972
1973 Additionally, an integer can be passed, so
1974 IPv6Address('2001:db8::') ==
1975 IPv6Address(42540766411282592856903984951653826560)
1976 or, more generally
1977 IPv6Address(int(IPv6Address('2001:db8::'))) ==
1978 IPv6Address('2001:db8::')
1979
1980 Raises:
1981 AddressValueError: If address isn't a valid IPv6 address.
1982
1983 """
1984 _BaseAddress.__init__(self, address)
1985 _BaseV6.__init__(self, address)
1986
1987 # Efficient constructor from integer.
1988 if isinstance(address, int):
1989 self._ip = address
1990 if address < 0 or address > self._ALL_ONES:
1991 raise AddressValueError(address)
1992 return
1993
1994 # Constructing from a packed address
1995 if isinstance(address, bytes) and len(address) == 16:
1996 tmp = struct.unpack('!QQ', address)
1997 self._ip = (tmp[0] << 64) | tmp[1]
1998 return
1999
2000 # Assume input argument to be string or any object representation
2001 # which converts into a formatted IP string.
2002 addr_str = str(address)
2003 if not addr_str:
2004 raise AddressValueError('')
2005
2006 self._ip = self._ip_int_from_string(addr_str)
2007
2008
2009class IPv6Interface(IPv6Address):
2010
2011 def __init__(self, address):
2012 if isinstance(address, (bytes, int)):
2013 IPv6Address.__init__(self, address)
2014 self.network = IPv6Network(self._ip)
2015 self._prefixlen = self._max_prefixlen
2016 return
2017
2018 addr = str(address).split('/')
2019 IPv6Address.__init__(self, addr[0])
2020 self.network = IPv6Network(address, strict=False)
2021 self.netmask = self.network.netmask
2022 self._prefixlen = self.network._prefixlen
2023 self.hostmask = self.network.hostmask
2024
Nick Coghlandc9b2552012-05-20 21:01:57 +10002025 def __str__(self):
2026 return '%s/%d' % (self._string_from_ip_int(self._ip),
2027 self.network.prefixlen)
2028
2029 def __eq__(self, other):
2030 try:
2031 return (IPv6Address.__eq__(self, other) and
2032 self.network == other.network)
2033 except AttributeError:
2034 return NotImplemented
2035
2036 def __hash__(self):
2037 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
2038
2039 @property
2040 def prefixlen(self):
2041 return self._prefixlen
Hynek Schlawack072b1e12012-05-26 12:04:56 +02002042
Nick Coghlandc9b2552012-05-20 21:01:57 +10002043 @property
2044 def ip(self):
2045 return IPv6Address(self._ip)
2046
2047 @property
2048 def with_prefixlen(self):
2049 return self
2050
2051 @property
2052 def with_netmask(self):
2053 return self.with_prefixlen
Hynek Schlawack072b1e12012-05-26 12:04:56 +02002054
Nick Coghlandc9b2552012-05-20 21:01:57 +10002055 @property
2056 def with_hostmask(self):
2057 return '%s/%s' % (self._string_from_ip_int(self._ip),
2058 self.hostmask)
2059
2060
2061class IPv6Network(_BaseV6, _BaseNetwork):
2062
2063 """This class represents and manipulates 128-bit IPv6 networks.
2064
2065 Attributes: [examples for IPv6('2001:db8::1000/124')]
2066 .network_address: IPv6Address('2001:db8::1000')
2067 .hostmask: IPv6Address('::f')
2068 .broadcast_address: IPv6Address('2001:db8::100f')
2069 .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0')
2070 .prefixlen: 124
2071
2072 """
2073
2074 def __init__(self, address, strict=True):
2075 """Instantiate a new IPv6 Network object.
2076
2077 Args:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02002078 address: A string or integer representing the IPv6 network or the
2079 IP and prefix/netmask.
Nick Coghlandc9b2552012-05-20 21:01:57 +10002080 '2001:db8::/128'
2081 '2001:db8:0000:0000:0000:0000:0000:0000/128'
2082 '2001:db8::'
2083 are all functionally the same in IPv6. That is to say,
2084 failing to provide a subnetmask will create an object with
2085 a mask of /128.
2086
2087 Additionally, an integer can be passed, so
2088 IPv6Network('2001:db8::') ==
2089 IPv6Network(42540766411282592856903984951653826560)
2090 or, more generally
2091 IPv6Network(int(IPv6Network('2001:db8::'))) ==
2092 IPv6Network('2001:db8::')
2093
2094 strict: A boolean. If true, ensure that we have been passed
2095 A true network address, eg, 2001:db8::1000/124 and not an
2096 IP address on a network, eg, 2001:db8::1/124.
2097
2098 Raises:
2099 AddressValueError: If address isn't a valid IPv6 address.
2100 NetmaskValueError: If the netmask isn't valid for
2101 an IPv6 address.
2102 ValueError: If strict was True and a network address was not
2103 supplied.
2104
2105 """
2106 _BaseV6.__init__(self, address)
2107 _BaseNetwork.__init__(self, address)
2108
2109 # Efficient constructor from integer.
2110 if isinstance(address, int):
2111 if address < 0 or address > self._ALL_ONES:
2112 raise AddressValueError(address)
2113 self.network_address = IPv6Address(address)
2114 self._prefixlen = self._max_prefixlen
2115 self.netmask = IPv6Address(self._ALL_ONES)
2116 if strict:
2117 if (IPv6Address(int(self.network_address) &
2118 int(self.netmask)) != self.network_address):
2119 raise ValueError('%s has host bits set' % str(self))
2120 self.network_address = IPv6Address(int(self.network_address) &
2121 int(self.netmask))
2122 return
2123
2124 # Constructing from a packed address
2125 if isinstance(address, bytes) and len(address) == 16:
2126 tmp = struct.unpack('!QQ', address)
2127 self.network_address = IPv6Address((tmp[0] << 64) | tmp[1])
2128 self._prefixlen = self._max_prefixlen
2129 self.netmask = IPv6Address(self._ALL_ONES)
2130 if strict:
2131 if (IPv6Address(int(self.network_address) &
2132 int(self.netmask)) != self.network_address):
2133 raise ValueError('%s has host bits set' % str(self))
2134 self.network_address = IPv6Address(int(self.network_address) &
2135 int(self.netmask))
2136 return
2137
2138 # Assume input argument to be string or any object representation
2139 # which converts into a formatted IP prefix string.
2140 addr = str(address).split('/')
2141
2142 if len(addr) > 2:
2143 raise AddressValueError(address)
2144
2145 self.network_address = IPv6Address(self._ip_int_from_string(addr[0]))
2146
2147 if len(addr) == 2:
2148 if self._is_valid_netmask(addr[1]):
2149 self._prefixlen = int(addr[1])
2150 else:
2151 raise NetmaskValueError(addr[1])
2152 else:
2153 self._prefixlen = self._max_prefixlen
2154
2155 self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
2156 if strict:
2157 if (IPv6Address(int(self.network_address) & int(self.netmask)) !=
2158 self.network_address):
2159 raise ValueError('%s has host bits set' % str(self))
2160 self.network_address = IPv6Address(int(self.network_address) &
2161 int(self.netmask))
2162
2163 if self._prefixlen == (self._max_prefixlen - 1):
2164 self.hosts = self.__iter__
2165
2166 def __str__(self):
2167 return '%s/%d' % (str(self.network_address),
2168 self.prefixlen)
2169
2170 def _is_valid_netmask(self, prefixlen):
2171 """Verify that the netmask/prefixlen is valid.
2172
2173 Args:
2174 prefixlen: A string, the netmask in prefix length format.
2175
2176 Returns:
2177 A boolean, True if the prefix represents a valid IPv6
2178 netmask.
2179
2180 """
2181 try:
2182 prefixlen = int(prefixlen)
2183 except ValueError:
2184 return False
2185 return 0 <= prefixlen <= self._max_prefixlen
2186
2187 @property
Nick Coghlandc9b2552012-05-20 21:01:57 +10002188 def with_prefixlen(self):
2189 return '%s/%d' % (str(self.network_address), self._prefixlen)
2190
2191 @property
2192 def with_netmask(self):
2193 return '%s/%s' % (str(self.network_address), str(self.netmask))
2194
2195 @property
2196 def with_hostmask(self):
2197 return '%s/%s' % (str(self.network_address), str(self.hostmask))