Changeset - 4cf5607f61be
[Not reviewed]
default
0 1 0
timeless@gmail.com - 10 years ago 2016-05-03 13:54:14
timeless@gmail.com
spelling: functionally
1 file changed with 1 insertions and 1 deletions:
0 comments (0 inline, 0 general)
kallithea/lib/ipaddr.py
Show inline comments
 
@@ -1152,193 +1152,193 @@ class _BaseV4(object):
 

	
 
    @property
 
    def is_loopback(self):
 
        """Test if the address is a loopback address.
 

	
 
        Returns:
 
            A boolean, True if the address is a loopback per RFC 3330.
 

	
 
        """
 
        return self in IPv4Network('127.0.0.0/8')
 

	
 
    @property
 
    def is_link_local(self):
 
        """Test if the address is reserved for link-local.
 

	
 
        Returns:
 
            A boolean, True if the address is link-local per RFC 3927.
 

	
 
        """
 
        return self in IPv4Network('169.254.0.0/16')
 

	
 

	
 
class IPv4Address(_BaseV4, _BaseIP):
 

	
 
    """Represent and manipulate single IPv4 Addresses."""
 

	
 
    def __init__(self, address):
 

	
 
        """
 
        Args:
 
            address: A string or integer representing the IP
 
              '192.168.1.1'
 

	
 
              Additionally, an integer can be passed, so
 
              IPv4Address('192.168.1.1') == IPv4Address(3232235777).
 
              or, more generally
 
              IPv4Address(int(IPv4Address('192.168.1.1'))) ==
 
                IPv4Address('192.168.1.1')
 

	
 
        Raises:
 
            AddressValueError: If ipaddr isn't a valid IPv4 address.
 

	
 
        """
 
        _BaseV4.__init__(self, address)
 

	
 
        # Efficient constructor from integer.
 
        if isinstance(address, (int, long)):
 
            self._ip = address
 
            if address < 0 or address > self._ALL_ONES:
 
                raise AddressValueError(address)
 
            return
 

	
 
        # Constructing from a packed address
 
        if isinstance(address, Bytes):
 
            try:
 
                self._ip, = struct.unpack('!I', address)
 
            except struct.error:
 
                raise AddressValueError(address)  # Wrong length.
 
            return
 

	
 
        # Assume input argument to be string or any object representation
 
        # which converts into a formatted IP string.
 
        addr_str = str(address)
 
        self._ip = self._ip_int_from_string(addr_str)
 

	
 

	
 
class IPv4Network(_BaseV4, _BaseNet):
 

	
 
    """This class represents and manipulates 32-bit IPv4 networks.
 

	
 
    Attributes: [examples for IPv4Network('1.2.3.4/27')]
 
        ._ip: 16909060
 
        .ip: IPv4Address('1.2.3.4')
 
        .network: IPv4Address('1.2.3.0')
 
        .hostmask: IPv4Address('0.0.0.31')
 
        .broadcast: IPv4Address('1.2.3.31')
 
        .netmask: IPv4Address('255.255.255.224')
 
        .prefixlen: 27
 

	
 
    """
 

	
 
    # the valid octets for host and netmasks. only useful for IPv4.
 
    _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
 

	
 
    def __init__(self, address, strict=False):
 
        """Instantiate a new IPv4 network object.
 

	
 
        Args:
 
            address: A string or integer representing the IP [& network].
 
              '192.168.1.1/24'
 
              '192.168.1.1/255.255.255.0'
 
              '192.168.1.1/0.0.0.255'
 
              are all functionally the same in IPv4. Similarly,
 
              '192.168.1.1'
 
              '192.168.1.1/255.255.255.255'
 
              '192.168.1.1/32'
 
              are also functionaly equivalent. That is to say, failing to
 
              are also functionally equivalent. That is to say, failing to
 
              provide a subnetmask will create an object with a mask of /32.
 

	
 
              If the mask (portion after the / in the argument) is given in
 
              dotted quad form, it is treated as a netmask if it starts with a
 
              non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
 
              starts with a zero field (e.g. 0.255.255.255 == /8), with the
 
              single exception of an all-zero mask which is treated as a
 
              netmask == /0. If no mask is given, a default of /32 is used.
 

	
 
              Additionally, an integer can be passed, so
 
              IPv4Network('192.168.1.1') == IPv4Network(3232235777).
 
              or, more generally
 
              IPv4Network(int(IPv4Network('192.168.1.1'))) ==
 
                IPv4Network('192.168.1.1')
 

	
 
            strict: A boolean. If true, ensure that we have been passed
 
              A true network address, eg, 192.168.1.0/24 and not an
 
              IP address on a network, eg, 192.168.1.1/24.
 

	
 
        Raises:
 
            AddressValueError: If ipaddr isn't a valid IPv4 address.
 
            NetmaskValueError: If the netmask isn't valid for
 
              an IPv4 address.
 
            ValueError: If strict was True and a network address was not
 
              supplied.
 

	
 
        """
 
        _BaseNet.__init__(self, address)
 
        _BaseV4.__init__(self, address)
 

	
 
        # Constructing from an integer or packed bytes.
 
        if isinstance(address, (int, long, Bytes)):
 
            self.ip = IPv4Address(address)
 
            self._ip = self.ip._ip
 
            self._prefixlen = self._max_prefixlen
 
            self.netmask = IPv4Address(self._ALL_ONES)
 
            return
 

	
 
        # Assume input argument to be string or any object representation
 
        # which converts into a formatted IP prefix string.
 
        addr = str(address).split('/')
 

	
 
        if len(addr) > 2:
 
            raise AddressValueError(address)
 

	
 
        self._ip = self._ip_int_from_string(addr[0])
 
        self.ip = IPv4Address(self._ip)
 

	
 
        if len(addr) == 2:
 
            mask = addr[1].split('.')
 
            if len(mask) == 4:
 
                # We have dotted decimal netmask.
 
                if self._is_valid_netmask(addr[1]):
 
                    self.netmask = IPv4Address(self._ip_int_from_string(
 
                            addr[1]))
 
                elif self._is_hostmask(addr[1]):
 
                    self.netmask = IPv4Address(
 
                        self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
 
                else:
 
                    raise NetmaskValueError('%s is not a valid netmask'
 
                                                     % addr[1])
 

	
 
                self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
 
            else:
 
                # We have a netmask in prefix length form.
 
                if not self._is_valid_netmask(addr[1]):
 
                    raise NetmaskValueError(addr[1])
 
                self._prefixlen = int(addr[1])
 
                self.netmask = IPv4Address(self._ip_int_from_prefix(
 
                    self._prefixlen))
 
        else:
 
            self._prefixlen = self._max_prefixlen
 
            self.netmask = IPv4Address(self._ip_int_from_prefix(
 
                self._prefixlen))
 
        if strict:
 
            if self.ip != self.network:
 
                raise ValueError('%s has host bits set' %
 
                                 self.ip)
 
        if self._prefixlen == (self._max_prefixlen - 1):
 
            self.iterhosts = self.__iter__
 

	
 
    def _is_hostmask(self, ip_str):
 
        """Test if the IP string is a hostmask (rather than a netmask).
 

	
 
        Args:
 
            ip_str: A string, the potential hostmask.
 

	
 
        Returns:
 
            A boolean, True if the IP string is a hostmask.
 

	
 
        """
 
        bits = ip_str.split('.')
 
        try:
 
            parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
 
        except ValueError:
 
            return False
0 comments (0 inline, 0 general)