
    $g                    n   d Z ddlZddlmZmZmZmZmZm	Z	m
Z
 ddlmZmZ  G d de          Z G d de          Z G d	 d
e          ZdKdddZ G d dee          Z G d dee          Zd Zd Zd Zd Zd Zd ZdLdZd Zd Zd Z d Z! ed          Z" ed           ed            ed!          gZ# ed"          Z$ ed#          Z% ed$          Z& ed%           ed&           ed'           ed(           ed)           ed*           ed+d,           ed-d.          fe"e&fz   Z'd/ d0D             Z(d1 d2D             Z) ed3          Z* ed4          Z+ ed5          Z, ed6          Z- ed7           ed8           ed9           ed:           ed;           ed<           ed=           ed>           ed?           ed@           edA           edB           edC           edD           edE           edF          fZ.dG dHD             Z/dI dJD             Z0dS )Mz9Routines for IPv4 and IPv6 addresses, subnets and ranges.    N)AddrFormatErrorAddrConversionErrorDictDotLookupNOHOST	INET_ATON	INET_PTONZEROFILL)ipv4ipv6c                       e Zd ZdZdZd Zd Z ed ed          Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zed             Zed             ZdS )BaseIPzi
    An abstract base class for common operations shared between various IP
    related subclasses.

    )_value_module__weakref__c                 "    d| _         d| _        dS )zConstructor.N)r   r   selfs    S/var/www/html/netbox-4.1.3/venv/lib/python3.11/site-packages/netaddr/ip/__init__.py__init__zBaseIP.__init__    s        c                     t          |t                    st          dt          |          z            d|cxk    r| j        j        k    sn t          d| j        j        z            || _        d S )Nint argument expected, not %sr   z&value out of bounds for an %s address!)	
isinstanceint	TypeErrortyper   max_intr   family_namer   r   values     r   
_set_valuezBaseIP._set_value%   s    %%% 	K;d5kkIJJJE1111T\11111!84<;SS   r   c                     | j         S Nr   r   s    r   <lambda>zBaseIP.<lambda>/   s    T[ r   z?a positive integer representing the value of IP address/subnet.docc                     t           S zP
        :return: a key tuple that uniquely identifies this IP address.
        NotImplementedr   s    r   keyz
BaseIP.key4   s
     r   c                     t           S )zg
        :return: A key tuple used to compare and sort this `IPAddress`
            correctly.
        r*   r   s    r   sort_keyzBaseIP.sort_key:   s
    
 r   c                 D    t          |                                           S )zL
        :return: A hash value uniquely identifying this IP object.
        )hashr,   r   s    r   __hash__zBaseIP.__hash__A   s     DHHJJr   c                     	 |                                  |                                 k    S # t          t          f$ r
 t          cY S w xY w)z
        :param other: an `IPAddress` or `IPNetwork` object.

        :return: ``True`` if this `IPAddress` or `IPNetwork` object is
            equivalent to ``other``, ``False`` otherwise.
        r,   AttributeErrorr   r+   r   others     r   __eq__zBaseIP.__eq__G   N    	"88::,,	* 	" 	" 	"!!!!	"   ), AAc                     	 |                                  |                                 k    S # t          t          f$ r
 t          cY S w xY w)z
        :param other: an `IPAddress` or `IPNetwork` object.

        :return: ``True`` if this `IPAddress` or `IPNetwork` object is
            not equivalent to ``other``, ``False`` otherwise.
        r3   r5   s     r   __ne__zBaseIP.__ne__S   r8   r9   c                     	 |                                  |                                 k     S # t          t          f$ r
 t          cY S w xY w)z
        :param other: an `IPAddress` or `IPNetwork` object.

        :return: ``True`` if this `IPAddress` or `IPNetwork` object is
            less than ``other``, ``False`` otherwise.
        r.   r4   r   r+   r5   s     r   __lt__zBaseIP.__lt___   P    	"==??U^^%5%555	* 	" 	" 	"!!!!	"r9   c                     	 |                                  |                                 k    S # t          t          f$ r
 t          cY S w xY w)z
        :param other: an `IPAddress` or `IPNetwork` object.

        :return: ``True`` if this `IPAddress` or `IPNetwork` object is
            less than or equal to ``other``, ``False`` otherwise.
        r=   r5   s     r   __le__zBaseIP.__le__k   P    	"==??enn&6&666	* 	" 	" 	"!!!!	"r9   c                     	 |                                  |                                 k    S # t          t          f$ r
 t          cY S w xY w)z
        :param other: an `IPAddress` or `IPNetwork` object.

        :return: ``True`` if this `IPAddress` or `IPNetwork` object is
            greater than ``other``, ``False`` otherwise.
        r=   r5   s     r   __gt__zBaseIP.__gt__w   r?   r9   c                     	 |                                  |                                 k    S # t          t          f$ r
 t          cY S w xY w)z
        :param other: an `IPAddress` or `IPNetwork` object.

        :return: ``True`` if this `IPAddress` or `IPNetwork` object is
            greater than or equal to ``other``, ``False`` otherwise.
        r=   r5   s     r   __ge__zBaseIP.__ge__   rB   r9   c                 ,    |                                   S )z<:return: ``True`` if this IP is unicast, ``False`` otherwise)is_multicastr   s    r   
is_unicastzBaseIP.is_unicast   s    $$&&&&r   c                 j    | j         t          k    r	| t          v S | j         t          k    r	| t          v S dS )z>:return: ``True`` if this IP is multicast, ``False`` otherwiseN)r   _ipv4IPV4_MULTICAST_ipv6IPV6_MULTICASTr   s    r   rH   zBaseIP.is_multicast   s:    <5  >))\U"">)) #"r   c                 j    | j         j        dk    r	| t          v S | j         j        dk    r	| t          v S dS )z
        :return: ``True`` if this IP is loopback address (not for network
            transmission), ``False`` otherwise.
            References: RFC 3330 and 4291.

        .. note:: |ipv4_in_ipv6_handling|
              N)r   versionIPV4_LOOPBACKIPV6_LOOPBACKr   s    r   is_loopbackzBaseIP.is_loopback   sB     <1$$=((\!Q&&=(( '&r   c                 j    | j         j        dk    r	| t          v S | j         j        dk    r	| t          v S dS )z
        :return: ``True`` if this IP is link-local address ``False`` otherwise.
            Reference: RFCs 3927 and 4291.

        .. note:: |ipv4_in_ipv6_handling|
        rP   rQ   N)r   rR   IPV4_LINK_LOCALIPV6_LINK_LOCALr   s    r   is_link_localzBaseIP.is_link_local   sB     <1$$?**\!Q&&?** '&r   c                     | j         j        dk    rt          D ]	}| |v r dS 
n!| j         j        dk    rt          D ]	}| |v r dS 
dS )z
        :return: ``True`` if this IP is in IANA reserved range, ``False``
            otherwise. Reference: RFCs 3330 and 3171.

        .. note:: |ipv4_in_ipv6_handling|
        rP   TrQ   F)r   rR   IPV4_RESERVEDIPV6_RESERVED)r   cidrs     r   is_reservedzBaseIP.is_reserved   sx     <1$$%    4<<44    \!Q&&%    4<<44  ur   c                 >    | j         j        dk    o| j        dz	  dk    S )zl
        :return: ``True`` if this IP is IPv4-mapped IPv6 address, ``False``
            otherwise.
        rQ       i  r   rR   r   r   s    r   is_ipv4_mappedzBaseIP.is_ipv4_mapped   s%    
 |#q(JdkR.?F-JJr   c                 >    | j         j        dk    o| j        dz	  dk    S )zp
        :return: ``True`` if this IP is IPv4-compatible IPv6 address, ``False``
            otherwise.
        rQ   r`   r   ra   r   s    r   is_ipv4_compatzBaseIP.is_ipv4_compat   s%    
 |#q(EdkR.?A-EEr   c                 >    ddl m} t           ||                     S )z~
        A record dict containing IANA registration details for this IP address
        if available, None otherwise.
        r   )query)netaddr.ip.ianarf   r   )r   rf   s     r   infozBaseIP.info   s,     	*)))))UU4[[)))r   c                     | j         j        S )z6the IP protocol version represented by this IP object.)r   rR   r   s    r   rR   zBaseIP.version   s     |##r   N)__name__
__module____qualname____doc__	__slots__r   r!   propertyr    r,   r.   r1   r7   r;   r>   rA   rD   rF   rI   rH   rU   rY   r^   rb   rd   rh   rR    r   r   r   r      s         5I  
   H  M  E         
" 
" 
"
" 
" 
"
" 
" 
"
" 
" 
"
" 
" 
"
" 
" 
"' ' '* * *) ) )
+ 
+ 
+  "K K KF F F * * X* $ $ X$ $ $r   r   c                   D    e Zd ZdZdZd* fd	Zd Zd Zd Zd	 Z	d
 Z
d Zd Zd ZeZd Zd Zd Zd Zd Zd Zd Zd+dZed             Zed             Zed             Zed             Zd Zd,dZd+dZd Zd Z d  Z!d! Z"d" Z#d# Z$d$ Z%d% Z&d& Z'd' Z(d( Z)d) Z* xZ+S )-	IPAddressz
    An individual IPv4 or IPv6 address without a net mask or subnet prefix.

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

    rp   Nr   c                 &   t          t          |                                            |t          t          z  t
          z   z  rt          d|          |t
          z  r|t          z  rt          d          t          |t                    r;|||j	        j
        k    rt          d          |j        | _        |j	        | _	        dS |8|dk    rt          | _	        n%|dk    rt          | _	        nt          d|z            t          |t                    r d|v rt          d	| j        j        z            | j	         t          |t"                    r	 d
t#          |          cxk    rt          j        k    r$n n!t#          |          | _        t          | _	        nQt          j        t#          |          cxk     rt          j        k    r#n n t#          |          | _        t          | _	        nU# t          $ r Y nIw xY wt          t          fD ]6}	 |                    ||          | _        || _	         n# t(          $ r Y 3w xY w| j	        t)          d|z            dS t          |t                    rO	 | j	                            ||          | _        dS # t(          $ r t)          d|| j	        j
        fz            w xY wd
t#          |          cxk    r| j	        j        k    rn nt#          |          | _        dS t)          d|          )u  
        Constructor.

        :param addr: an IPv4 or IPv6 address which may be represented in an
            accepted string format, as an unsigned integer or as another
            IPAddress object (copy construction).

        :param version: (optional) optimizes version detection if specified
            and distinguishes between IPv4 and IPv6 for addresses with an
            equivalent integer value.

        :param flags: (optional) decides which rules are applied to the
            interpretation of the addr value if passed as a string.

            Matters only in IPv4 context.

            Allowed flag values:

            * :data:`INET_ATON`. Follows `inet_aton semantics
              <https://www.netmeister.org/blog/inet_aton.html>`_ and allows all kinds of
              weird-looking addresses to be parsed. For example:

              >>> IPAddress('1', flags=INET_ATON)
              IPAddress('0.0.0.1')
              >>> IPAddress('1.0xf', flags=INET_ATON)
              IPAddress('1.0.0.15')
              >>> IPAddress('010.020.030.040', flags=INET_ATON)
              IPAddress('8.16.24.32')

            * ``INET_ATON | ZEROFILL`` or :data:`ZEROFILL` – like ``INET_ATON``, except leading zeros are discarded:

              >>> IPAddress('010', flags=INET_ATON | ZEROFILL)
              IPAddress('0.0.0.10')

            * The default (``0``) or :data:`INET_PTON` – requires four decimal octets:

              >>> IPAddress('10.0.0.1', flags=INET_PTON)
              IPAddress('10.0.0.1')

              Leading zeros may be ignored or rejected, depending on the platform.

            * ``INET_PTON | ZEROFILL`` – like the default :data:`INET_PTON`, except leading
              zeros are discarded:

              >>> IPAddress('010.020.030.040', flags=INET_PTON | ZEROFILL)
              IPAddress('10.20.30.40')

        .. versionchanged:: 1.0.0
            Changed the default IPv4 parsing mode from :data:`INET_ATON` to :data:`INET_PTON`.
        $Unrecognized IPAddress flags value: z.INET_ATON and INET_PTON are mutually exclusiveNz1cannot switch IP versions using copy constructor!rP   rQ   %r is an invalid IP version!/zQ%s() does not support netmasks or subnet prefixes! See documentation for details.r   z+failed to detect a valid IP address from %rzbase address %r is not IPv%dzbad address format: )superrr   r   r   r	   r   
ValueErrorr   r   r   rR   r   rK   rM   str	__class__rj   r   r   
str_to_intr   )r   addrrR   flagsmodulerz   s        r   r   zIPAddress.__init__   s^   f 	i'')))Y)I566 	R*PQQQ9 	O!2 	OMNNNdF## ;	R"w$,2F'F'F !WXXX+DK<DLLL "a<<#(DLL\\#(DLL$%Cg%MNNN$$$  @BF.BYZ  
 |#dC(( "D		::::U]:::::*-d))DK+0DLL"]SYYGGGG%-GGGGG*-d))DK+0DL%    #(, " ""*0*;*;D%*H*HDK ,2DL!E	  / % % %$H% <')*Z]a*abbb (' dC(( R&*l&=&=dE&J&J*   -:dDLDX=YY  
 CII====)======&)$ii-o$$.PQQQs1   BG0 0
G=<G=H55
II6 J )Kc                 (    | j         | j        j        fS )z1:returns: Pickled state of an `IPAddress` object.)r   r   rR   r   s    r   __getstate__zIPAddress.__getstate__e  s    {DL000r   c                     |\  }}|| _         |dk    rt          | _        dS |dk    rt          | _        dS t	          dt          |          z            )zT
        :param state: data used to unpickle a pickled `IPAddress` object.

        rP   rQ   z&unpickling failed for object state: %sN)r   rK   r   rM   rx   ry   )r   stater    rR   s       r   __setstate__zIPAddress.__setstate__i  sV    
 wa<< DLLL\\ DLLLEE

RSSSr   c                 &   |                                  s| j        j        S | j        dk    rdS | j        }d}|dk    r|dz  dk    rn|dz  }|dz  }|dk    | j        j        |z
  }d|cxk    r| j        j        k    sn t	          d|z            |S )z
        @return: If this IP is a valid netmask, the number of non-zero
            bits are returned, otherwise it returns the width in bits for
            the IP address version.
        r      z+Unexpected mask length %d for address type!)
is_netmaskr   widthr   rx   )r   i_valnumbitsmask_lengths       r   netmask_bitszIPAddress.netmask_bitsy  s        	&<%% ;!1aiiqyA~~qLGaKE	 aii l(72K55554<#55555J[XYYYr   c                 .    | j         dz   }||dz
  z  dk    S )zV
        :return: ``True`` if this IP address host mask, ``False`` otherwise.
        r   r   r$   r   int_vals     r   is_hostmaskzIPAddress.is_hostmask  s#     +/'A+&!++r   c                 H    | j         | j        j        z  dz   }||dz
  z  dk    S )zY
        :return: ``True`` if this IP address network mask, ``False`` otherwise.
        r   r   )r   r   r   r   s     r   r   zIPAddress.is_netmask  s.     ;!55:'A+&!++r   c                     t          | j        |z             }d|cxk    r| j        j        k    rn n	|| _        | S t	          d          )z
        Increases the numerical value of this IPAddress by num.

        An IndexError is raised if result exceeds maximum IP address value or
        is less than zero.

        :param num: size of IP address increment.
        r   )result outside valid IP address boundary!r   r   r   r   
IndexErrorr   num	new_values      r   __iadd__zIPAddress.__iadd__  Z     c)**		1111T\111111#DKKDEEEr   c                     t          | j        |z
            }d|cxk    r| j        j        k    rn n	|| _        | S t	          d          )z
        Decreases the numerical value of this IPAddress by num.

        An IndexError is raised if result is less than zero or exceeds maximum
        IP address value.

        :param num: size of IP address decrement.
        r   r   r   r   s      r   __isub__zIPAddress.__isub__  r   r   c                     t          | j        |z             }d|cxk    r| j        j        k    r#n n |                     || j        j                  S t          d          )a  
        Add the numerical value of this IP address to num and provide the
        result as a new IPAddress object.

        :param num: size of IP address increase.

        :return: a new IPAddress object with its numerical value increased by num.
        r   r   r   r   r   r   rz   rR   r   r   s      r   __add__zIPAddress.__add__  g     c)**		1111T\111111>>)T\-ABBBDEEEr   c                     t          | j        |z
            }d|cxk    r| j        j        k    r#n n |                     || j        j                  S t          d          )a  
        Subtract the numerical value of this IP address from num providing
        the result as a new IPAddress object.

        :param num: size of IP address decrease.

        :return: a new IPAddress object with its numerical value decreased by num.
        r   r   r   r   s      r   __sub__zIPAddress.__sub__  r   r   c                     t          || j        z
            }d|cxk    r| j        j        k    r#n n |                     || j        j                  S t          d          )a  
        Subtract num (lvalue) from the numerical value of this IP address
        (rvalue) providing the result as a new IPAddress object.

        :param num: size of IP address decrease.

        :return: a new IPAddress object with its numerical value decreased by num.
        r   r   r   r   s      r   __rsub__zIPAddress.__rsub__  sg     dk)**		1111T\111111>>)T\-ABBBDEEEr   c                 (    | j         j        | j        fS r)   ra   r   s    r   r,   zIPAddress.key  s     |#T[00r   c                 >    | j         j        | j        | j         j        fS )zI:return: A key tuple used to compare and sort this `IPAddress` correctly.)r   rR   r   r   r   s    r   r.   zIPAddress.sort_key  s    |#T[$,2DDDr   c                     | j         S )z<:return: the value of this IP address as an unsigned integerr$   r   s    r   __int__zIPAddress.__int__  s
    {r   c                     | j         S )zG
        :return: return the integer value of this IP address.
        r$   r   s    r   	__index__zIPAddress.__index__   s     {r   c                 R    | j                             | j        j        dz  d          S )zw
        :return: a bytes object equivalent to this IP address. In network
            byte order, big-endian.
           big)r   to_bytesr   r   r   s    r   	__bytes__zIPAddress.__bytes__  s&    
 {##DL$6!$;UCCCr   c                 B    | j                             | j        |          S )z
        :param word_sep: (optional) the separator to insert between words.
            Default: None - use default separator for address type.

        :return: the value of this IP address as a binary digit string.)r   int_to_bitsr   )r   word_seps     r   bitszIPAddress.bits  s     |''X>>>r   c                 @    | j                             | j                  S )z7The value of this IP address as a packed binary string.)r   int_to_packedr   r   s    r   packedzIPAddress.packed  s     |))$+666r   c                 @    | j                             | j                  S )zx
        A list of unsigned integer words (octets for IPv4, hextets for IPv6)
        found in this IP address.
        )r   int_to_wordsr   r   s    r   wordszIPAddress.words  s     |((555r   c                 @    | j                             | j                  S )z
        The value of this IP address in standard Python binary
        representational form (0bxxx). A back port of the format provided by
        the builtin bin() function found in Python 2.6.x and higher.
        )r   
int_to_binr   r   s    r   binzIPAddress.bin"  s     |&&t{333r   c                 @    | j                             | j                  S )z1The reverse DNS lookup record for this IP address)r   int_to_arpar   r   s    r   reverse_dnszIPAddress.reverse_dns+  s     |''444r   c                 j   d}| j         }| j        j        dk    r || j        d          }n| j        j        dk    rwd| j        cxk    rt          j        k    rn n || j        d          }nFt          j        | j        cxk    rdk    rn n || j        dz
  d          }nt          d| z            |S )z
        Raises an `AddrConversionError` if IPv6 address cannot be converted
        to IPv4.

        :return: A numerically equivalent version 4 `IPAddress` object.
        NrP   rQ   r               2IPv6 address %s unsuitable for conversion to IPv4!)rz   r   rR   r   rK   r   r   )r   ipklasss      r   r
   zIPAddress.ipv40  s     <1$$t{A&&BB\!Q&&DK00005=00000U4;**$+?????????U4;7;;)KdR   	r   Fc                 "   d}| j         }| j        j        dk    r>|r*d| j        cxk    rdk    rn n || j        dz
  d          }nI || j        d          }n7| j        j        dk    r' || j        d          }|s |d| j        z   d          }|S )a  
        .. note:: The IPv4-compatible IPv6 address format is now considered             deprecated. See RFC 4291 or later for details.

        :param ipv4_compatible: If ``True`` returns an IPv4-compatible address
            (::x.x.x.x), an IPv4-mapped (::ffff:x.x.x.x) address
            otherwise. Default: False (IPv4-mapped).

        :return: A numerically equivalent version 6 `IPAddress` object.
        NrQ   r   r   rP   )rz   r   rR   r   r   ipv4_compatibler   r   s       r   r   zIPAddress.ipv6G  s     <1$$ +Ndk$S$S$S$S^$S$S$S$S$SU4;7;;U4;**\!Q&&t{A&&B" <U>DK7;;	r   c                     |t          |d          st          d          | j                            | j        |          S )z
        Only relevant for IPv6 addresses. Has no effect for IPv4.

        :param dialect: One of the :ref:`ipv6_formatting_dialects`.

        :return: an alternate string representation for this IP address.
        Nword_fmtz-custom dialects should subclass ipv6_verbose!)dialect)hasattrr   r   
int_to_strr   )r   r   s     r   formatzIPAddress.formatc  sI     7J// Q OPPP|&&t{G&DDDr   c                 l    |                      | j        t          |          z  | j        j                  S )z
        :param other: An `IPAddress` object (or other int-like object).

        :return: bitwise OR (x | y) between the integer value of this IP
            address and ``other``.
        rz   r   r   r   rR   r5   s     r   __or__zIPAddress.__or__p  *     ~~dkCJJ68LMMMr   c                 l    |                      | j        t          |          z  | j        j                  S )z
        :param other: An `IPAddress` object (or other int-like object).

        :return: bitwise AND (x & y) between the integer value of this IP
            address and ``other``.
        r   r5   s     r   __and__zIPAddress.__and__y  r   r   c                 l    |                      | j        t          |          z  | j        j                  S )z
        :param other: An `IPAddress` object (or other int-like object).

        :return: bitwise exclusive OR (x ^ y) between the integer value of
            this IP address and ``other``.
        r   r5   s     r   __xor__zIPAddress.__xor__  r   r   c                 R    |                      | j        |z  | j        j                  S )z
        :param numbits: size of bitwise shift.

        :return: an `IPAddress` object based on this one with its integer
            value left shifted by ``numbits``.
        rz   r   r   rR   r   r   s     r   
__lshift__zIPAddress.__lshift__  $     ~~dkW4dl6JKKKr   c                 R    |                      | j        |z	  | j        j                  S )z
        :param numbits: size of bitwise shift.

        :return: an `IPAddress` object based on this one with its integer
            value right shifted by ``numbits``.
        r   r   s     r   
__rshift__zIPAddress.__rshift__  r   r   c                 *    t          | j                  S )zi:return: ``True`` if the numerical value of this IP address is not             zero, ``False`` otherwise.)boolr   r   s    r   __bool__zIPAddress.__bool__  s     DK   r   c                 @    | j                             | j                  S )z,:return: IP address in presentational format)r   r   r   r   s    r   __str__zIPAddress.__str__  s    |&&t{333r   c                 &    | j         j        d| dS 8:return: Python statement to create an equivalent object('')rz   rj   r   s    r   __repr__zIPAddress.__repr__      !^444ddd;;r   c                 V    |                                  s| S |                                 S )aB  
        Converts the address to IPv4 if it is an IPv4-mapped IPv6 address (`RFC 4291
        Section 2.5.5.2 <https://datatracker.ietf.org/doc/html/rfc4291.html#section-2.5.5.2>`_),
        otherwise returns the address as-is.

        >>> # IPv4-mapped IPv6
        >>> IPAddress('::ffff:10.0.0.1').to_canonical()
        IPAddress('10.0.0.1')
        >>>
        >>> # Everything else
        >>> IPAddress('::1').to_canonical()
        IPAddress('::1')
        >>> IPAddress('10.0.0.1').to_canonical()
        IPAddress('10.0.0.1')

        .. versionadded:: 0.10.0
        )rb   r
   r   s    r   to_canonicalzIPAddress.to_canonical  s+    $ ""$$ 	Kyy{{r   c                       j         j        dk    rt          }t          }nt          }t
          }t           fd|D                        pt           fd|D                       S )a  
        Returns ``True`` if this address is considered globally reachable, ``False`` otherwise.

        An address is considered globally reachable if it's not a special-purpose address
        or it's a special-purpose address listed as globally reachable in the relevant
        registries:

        * |iana_special_ipv4|
        * |iana_special_ipv6|

        Addresses for which the ``Globally Reachable`` value is ``N/A`` are not considered
        globally reachable.

        Address blocks with set termination date are not taken into consideration.

        Whether or not an address can actually be reached in any local or global context will
        depend on the network configuration and may differ from what this method returns.

        Examples:

        >>> IPAddress('1.1.1.1').is_global()
        True
        >>> IPAddress('::1').is_global()
        False

        .. note:: |ipv4_in_ipv6_handling|
        rP   c              3       K   | ]}|v V  	d S r#   rp   .0netr   s     r   	<genexpr>z&IPAddress.is_global.<locals>.<genexpr>  s'      <<sts{<<<<<<r   c              3       K   | ]}|v V  	d S r#   rp   r   s     r   r   z&IPAddress.is_global.<locals>.<genexpr>  s@       D
 D
DCKD
 D
 D
 D
 D
 D
r   )r   rR   IPV4_NOT_GLOBALLY_REACHABLE&IPV4_NOT_GLOBALLY_REACHABLE_EXCEPTIONSIPV6_NOT_GLOBALLY_REACHABLE&IPV6_NOT_GLOBALLY_REACHABLE_EXCEPTIONSany)r   not_reachable
exceptionss   `  r   	is_globalzIPAddress.is_global  s    8 <1$$7M?JJ7M?J<<<<m<<<<<< 
 D
 D
 D
 D
#-D
 D
 D
 A
 A
 	
r   c                 d      j         j        dk    ot           fdt          D                       S )a=  
        Returns ``True`` if this address is an IPv4 private-use address as defined in
        :rfc:`1918`.

        The private-use address blocks:

        * ``10.0.0.0/8``
        * ``172.16.0.0/12``
        * ``192.168.0.0/16``

        .. note:: |ipv4_in_ipv6_handling|

        .. versionadded:: 0.10.0
        rP   c              3       K   | ]}|v V  	d S r#   rp   )r   r]   r   s     r   r   z0IPAddress.is_ipv4_private_use.<locals>.<genexpr>  s'      0[0[$0[0[0[0[0[0[r   )r   rR   r   IPV4_PRIVATE_USEr   s   `r   is_ipv4_private_usezIPAddress.is_ipv4_private_use  s8     |#q([S0[0[0[0[JZ0[0[0[-[-[[r   c                 4    | j         j        dk    o| t          v S )z
        Returns ``True`` if this address is an IPv6 unique local address as defined in
        :rfc:`4193` and listed in |iana_special_ipv6|.

        The IPv6 unique local address block: ``fc00::/7``.

        .. versionadded:: 0.10.0
        rQ   )r   rR   IPV6_UNIQUE_LOCALr   s    r   is_ipv6_unique_localzIPAddress.is_ipv6_unique_local  s     |#q(FT5F-FFr   Nr   r#   F),rj   rk   rl   rm   rn   r   r   r   r   r   r   r   r   r   __radd__r   r   r,   r.   r   r   r   r   ro   r   r   r   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r  __classcell__rz   s   @r   rr   rr      s         IvR vR vR vR vR vRp1 1 1T T T   <, , ,, , ,F F FF F FF F F HF F FF F F1 1 1E E E    D D D? ? ? ? 7 7 X7 6 6 X6 4 4 X4 5 5 X5  .   8E E E EN N NN N NN N NL L LL L L! ! !
4 4 4< < <  ,%
 %
 %
N\ \ \"	G 	G 	G 	G 	G 	G 	Gr   rr   c                   J    e Zd ZdZdZd Zed             Zd Zd Z	d Z
d Zd	S )
IPListMixinzu
    A mixin class providing shared list-like functionality to classes
    representing groups of IP addresses.

    rp   c                     t          | j        | j        j                  }t          | j        | j        j                  }t          ||          S )z
        :return: An iterator providing access to all `IPAddress` objects
            within range represented by this ranged IP object.
        )rr   firstr   rR   lastiter_iprange)r   start_ipend_ips      r   __iter__zIPListMixin.__iter__  s@    
 TZ)=>>49dl&:;;Hf---r   c                 @    t          | j        | j        z
  dz             S )zP
        The total number of IP addresses within this ranged IP object.
        r   )r   r  r
  r   s    r   sizezIPListMixin.size  s     
 49tz)A-...r   c                 l    | j         }|t          j        k    rt          dt          j        z            |S )z
        :return: the number of IP addresses in this ranged IP object. Raises
            an `IndexError` if size > system max int (a Python 2.x
            limitation). Use the .size property for subnets of any size.
        zWrange contains more than %d (sys.maxsize) IP addresses! Use the .size property instead.)r  _sysmaxsizer   )r   r  s     r   __len__zIPListMixin.__len__  sB     y$,DFJlS   r   c                 T   d}t          |d          r| j        j        dk    rt          d          |                    | j                  \  }}}||z   dk     s||k    r/t          t          | j        | j        j                  g          }nt          | j        |z   | j        j                  }||dk     rdndz   }t          | j        |z   | j        j                  }t          |||          }n	 t          |          }| j         |cxk    rdk     r)n n&t          | j        |z   dz   | j        j                  }nJd|cxk    r| j        dz
  k    r&n n#t          | j        |z   | j        j                  }nt          d          n # t          $ r t          d	|z            w xY w|S )
z
        :return: The IP address(es) in this `IPNetwork` object referenced by
            index or slice. As slicing can produce large sequences of objects
            an iterator is returned instead of the more usual `list`.
        NindicesrQ   zIPv6 slices are not supported!r   r   z'index out range for address range size!zunsupported index type %r!)r   r   rR   r   r  r  iterrr   r
  r  r   r  r   rx   )	r   indexitemstartstopstepr  one_before_stopr  s	            r   __getitem__zIPListMixin.__getitem__-  s    5)$$ 	F|#q(( @AAA"'--	":":UD$q  dTkkYtz4<3GHHIJJ$TZ%%79MNN #'taxx!!R"@"4:#?AUVV#Hfd;;FE

YJ5,,,,1,,,,,$TY%6%:DL<PQQDD%2222DIM22222$TZ%%79MNNDD$%NOOO F F F <u DEEEF s   2BF F%c                 0   t          |t                    rq| j        j        |j        j        k    rdS t          |t                    r |j        | j        k    o|j        | j        k    S |j        | j        k    o|j        | j        k    S t	          |          | v S )
        :param other: an `IPAddress` or ranged IP object.

        :return: ``True`` if other falls within the boundary of this one,
            ``False`` otherwise.
        F)r   r   r   rR   rr   r   r
  r  r5   s     r   __contains__zIPListMixin.__contains__U  s     eV$$ 	I|#u}'<<<u%++ P|tz1Oeldi6OO;$*,Hty1HH 4''r   c                     dS )z
        Ranged IP objects always represent a sequence of at least one IP
        address and are therefore always True in the boolean context.
        Trp   r   s    r   r   zIPListMixin.__bool__g  s	    
 tr   N)rj   rk   rl   rm   rn   r  ro   r  r  r   r#  r   rp   r   r   r  r    s          I. . . / / X/   & & &P( ( ($    r   r  Fexpand_partialc                V   t          |t                    rt          |          dk    rt          d| j        z            |\  }}d|cxk    r| j        k    sn t          d| j        z            d|cxk    r| j        k    sn t          d| j        z            nnt          |t                    r9d|v r|                    dd          \  }}n|}d }|r| 	                    |          }t          || j        t                    }|j        }	 t          |          }n# t          $ r || j        }Y nt           $ r t          || j        t                    }	|	                                r| j        |	j                 }n9|	                                r| j        |	j                 }nt          d	|z            Y nw xY wd|cxk    r| j        k    sn t          d
| j        z            nt          dt+          |          z            |t,          z  r| j        |         }
||
z  }||fS )N   zinvalid %s tuple!r   z#invalid address value for %s tuple!zinvalid prefix for %s tuple!rv   r   r}   z!addr %r is not a valid IPNetwork!zinvalid prefix for %s address!zunexpected type %s for addr arg)r   tuplelenr   r   r   r   ry   splitexpand_partial_addressrr   rR   r   r   r   r   rx   r   netmask_to_prefixr   hostmask_to_prefixr   r   prefix_to_netmask)r~   r|   r}   r&  r    	prefixlenval1val2r   masknetmasks              r   parse_ip_networkr6  o  s   $ -Ht99>>!"58J"JKKKyU,,,,fn,,,,!"G&J\"\]]]Y....&,....!"@6CU"UVVV /	D#		 #H $;;C++JD$$DD 	70066DtV^9===		RD		II 	) 	) 	)|"L	 	R 	R 	RT6>CCCD   R"4T[A		!!## R"5dkB		%&ID&PQQQ	R I--------!"BVEW"WXXX . 9DJJFGGGv~  *95)s   D   F=5BF=<F=c                       e Zd ZdZdZd)dd fdZd Zd	 Zd
 Z e	d ed          Z
e	d             Ze	d             Ze	d             Ze	d             Ze	d             Ze	d             Zej        d             Ze	d             Ze	d             Ze	d             Ze	d             Zd Zd Zd Zd Zd Zd Zd*dZd+d!Zd+d"Zd,d#Zd-d$Z d% Z!d& Z"d' Z#d( Z$ xZ%S ).	IPNetworka  
    An IPv4 or IPv6 network or subnet.

    A combination of an IP address and a network mask.

    Accepts CIDR and several related variants :

    a) Standard CIDR::

        x.x.x.x/y -> 192.0.2.0/24
        x::/y -> fe80::/10

    b) Hybrid CIDR format (netmask address instead of prefix), where 'y'        address represent a valid netmask::

        x.x.x.x/y.y.y.y -> 192.0.2.0/255.255.255.0
        x::/y:: -> fe80::/ffc0::

    c) ACL hybrid CIDR format (hostmask address instead of prefix like        Cisco's ACL bitmasks), where 'y' address represent a valid netmask::

        x.x.x.x/y.y.y.y -> 192.0.2.0/0.0.0.255
        x::/y:: -> fe80::/3f:ffff:ffff:ffff:ffff:ffff:ffff:ffff
    
    .. versionchanged:: 1.0.0
        Removed the ``implicit_prefix`` switch that used to enable the abbreviated CIDR
        format support, use :func:`cidr_abbrev_to_verbose` if you need this behavior.

    .. versionchanged:: 1.1.0
        Removed partial IPv4 address support accidentally left when making 1.0.0 release.
        Use :func:`expand_partial_ipv4_address` if you need this behavior.

    .. versionchanged:: 1.3.0
        Added the expand_partial flag, which restores the previous behavior to expand
        partial IPv4 address
    
_prefixlenNr   Fr%  c                >   t          t          |                                            |t           z  rt	          d|          d\  }}}t          |d          r2|j        }|j        }|j        }|t          z  r|j	        |         }||z  }nt          |d          r|j        }|j        }|j
        }n|dk    r#t          t          |||          \  }}t          }n|dk    r!t          t          ||          \  }}t          }n|t	          d	|z            	 t          }t          ||||          \  }}nQ# t          $ rD 	 t          }t          |||          \  }}n# t          $ r Y nw xY w|t          d
|          Y nw xY w|| _        || _        || _        dS )ai  
        Constructor.

        :param addr: an IPv4 or IPv6 address with optional CIDR prefix,
            netmask or hostmask. May be an IP address in presentation
            (string) format, an tuple containing and integer address and a
            network prefix, or another IPAddress/IPNetwork object (copy
            construction).

        :param version: (optional) optimizes version detection if specified
            and distinguishes between IPv4 and IPv6 for addresses with an
            equivalent integer value.

        :param flags: (optional) decides which rules are applied to the
            interpretation of the addr value. Currently only supports the
            :data:`NOHOST` option.

        :param expand_partial: (optional) decides whether partial address is
            expanded. Currently this is only effective for IPv4 address.

            >>> IPNetwork('1.2.3.4/24')
            IPNetwork('1.2.3.4/24')
            >>> IPNetwork('1.2.3.4/24', flags=NOHOST)
            IPNetwork('1.2.3.0/24')
            >>> IPNetwork('10/24', expand_partial=True)
            IPNetwork('10.0.0.0/24')
        rt   )NNNr:  r   rP   r%  rQ   Nru   zinvalid IPNetwork )rw   r8  r   r   rx   r   r   r   r:  r0  r   r6  rK   rM   r   )
r   r|   rR   r}   r&  r    r1  r~   r5  rz   s
            r   r   zIPNetwork.__init__  s   8 	i'')))F7? 	R*PQQQ#3 y&4&& #	LKE\FIv~ ( 29=T8$$ 	LKE\FII\\/tUSabbbE9FF\\/tUCCE9FF" !?'!IJJJL#3D%$ $ $ yy # L L L"F'7e'L'L$E99&   D =)/DD*JKKK !=L #s6   D7 7
FEF
E+(F*E++FFc                 4    | j         | j        | j        j        fS )z0:return: Pickled state of an `IPNetwork` object.)r   r:  r   rR   r   s    r   r   zIPNetwork.__getstate__  s    {DOT\-AAAr   c                     |\  }}}|| _         |dk    rt          | _        n%|dk    rt          | _        nt	          d|          d|cxk    r| j        j        k    rn n	|| _        dS t	          d|          )zT
        :param state: data used to unpickle a pickled `IPNetwork` object.

        rP   rQ   z#unpickling failed for object state r   N)r   rK   r   rM   rx   r   r:  )r   r   r    r1  rR   s        r   r   zIPNetwork.__setstate__  s    
 %*!y'a<< DLL\\ DLL*OPPP	////T\//////'DOOO*OPPPr   c                     t          |t                    st          dt          |          z            d|cxk    r| j        j        k    sn t          d| j        j        z            || _        d S )Nr   r   z!invalid prefix for an %s address!)	r   r   r   r   r   r   r   r   r:  r   s     r   _set_prefixlenzIPNetwork._set_prefixlen4  sw    %%% 	K;d5kkIJJJE////T\/////!"EH`"`aaar   c                     | j         S r#   r9  r   s    r   r%   zIPNetwork.<lambda><  s    T_ r   zCsize of the bitmask used to separate the network from the host bitsr&   c                 @    t          | j        | j        j                  S )z
        The IP address of this `IPNetwork` object. This is may or may not be
        the same as the network IP address which varies according to the value
        of the CIDR subnet prefix.
        )rr   r   r   rR   r   s    r   r   zIPNetwork.ipA  s     dl&:;;;r   c                 P    t          | j        | j        z  | j        j                  S )z/The network address of this `IPNetwork` object.)rr   r   _netmask_intr   rR   r   s    r   networkzIPNetwork.networkJ  s#     t'88$,:NOOOr   c                     | j         j        | j        z
  dk    rdS t          | j        | j        z  | j         j                  S )z1The broadcast address of this `IPNetwork` object.r   N)r   r   r:  rr   r   _hostmask_intrR   r   s    r   	broadcastzIPNetwork.broadcastO  s?     L0Q664T[4+==t|?STTTr   c                 :    | j         | j        j        | j        z  z  S )ze
        The integer value of first IP address found within this `IPNetwork`
        object.
        )r   r   r   rF  r   s    r   r
  zIPNetwork.firstW  s     {dl2T5GGHHr   c                 J    d| j         j        | j        z
  z  dz
  }| j        |z  S )zd
        The integer value of last IP address found within this `IPNetwork`
        object.
        r   )r   r   r:  r   r   hostmasks     r   r  zIPNetwork.last_  s,     $,,t>?1D{X%%r   c                 ^    | j         j        | j        z  }t          || j         j                  S )z+The subnet mask of this `IPNetwork` object.)r   r   rF  rr   rR   )r   r5  s     r   r5  zIPNetwork.netmaskh  s+     ,&);;$,"6777r   c                    t          |          }|j        | j        k    rt          d|d|           |                                st          dt	          |          z            |                                | _        dS )z%Set the prefixlen using a subnet maskzIP version mismatch: z and z!Invalid subnet mask specified: %sN)rr   rR   rx   r   ry   r   r1  )r   r    r   s      r   r5  zIPNetwork.netmaskn  s{     u:%%*TTJKKK}} 	O@3u::MNNN**r   c                 *    | j         j        | j        z  S )z+Same as self.netmask, but in integer format)r   r   rF  r   s    r   rC  zIPNetwork._netmask_int{  s     |#d&888r   c                 j    d| j         j        | j        z
  z  dz
  }t          || j         j                  S )z)The host mask of this `IPNetwork` object.r   )r   r   r:  rr   rR   rJ  s     r   rK  zIPNetwork.hostmask  s4     $,,t>?1D4<#7888r   c                 6    d| j         j        | j        z
  z  dz
  S )z,Same as self.hostmask, but in integer formatr   )r   r   r:  r   s    r   rF  zIPNetwork._hostmask_int  s      dl(4?:;q@@r   c                 `    t          | j        | j        z  | j        f| j        j                  S )z
        The true CIDR address for this `IPNetwork` object which omits any
        host bits to the right of the CIDR subnet prefix.
        rR   )r8  r   rC  r:  r   rR   r   s    r   r]   zIPNetwork.cidr  s6     [4,,do>H\
 
 
 	
r   c                     t          | j                  | j        |z  z   }|| j        dz
  z   | j        j        k    rt          d          |dk     rt          d          || _        | S )aP  
        Increases the value of this `IPNetwork` object by the current size
        multiplied by ``num``.

        An `IndexError` is raised if result exceeds maximum IP address value
        or is less than zero.

        :param num: (optional) number of `IPNetwork` blocks to increment             this IPNetwork's value by.
        r   z#increment exceeds address boundary!r   zincrement is less than zero!)r   rD  r  r   r   r   r   r   s      r   r   zIPNetwork.__iadd__  sl     %%S9	Q'4<+???BCCCq==;<<<r   c                     t          | j                  | j        |z  z
  }|dk     rt          d          || j        dz
  z   | j        j        k    rt          d          || _        | S )aP  
        Decreases the value of this `IPNetwork` object by the current size
        multiplied by ``num``.

        An `IndexError` is raised if result is less than zero or exceeds
        maximum IP address value.

        :param num: (optional) number of `IPNetwork` blocks to decrement             this IPNetwork's value by.
        r   zdecrement is less than zero!r   z#decrement exceeds address boundary!)r   rD  r  r   r   r   r   r   s      r   r   zIPNetwork.__isub__  sl     %%S9	q==;<<<Q'4<+???BCCCr   c                    t          |t                    r| j        j        |j        j        k    rdS | j        j        | j        z
  }| j        |z	  }t          |t                    r)||z  |j        j        k    o|dz   |z  |j	        j        k    S |j        |z	  }t          |t                    r||k    S t          |t                    r||k    o| j        |j        k    S t          |          | v S )r"  Fr   )r   r   r   rR   r   r:  r   IPRange_start_endrr   r8  )r   r6   
shiftwidthself_net	other_nets        r   r#  zIPNetwork.__contains__  s    eV$$ 	U|#u}'<<<u +do=J{j0H%))  !J.5<3FF lz1UZ5FF 
2I%++ - H,,%++ U9,TEDT1TT 4''r   c                 4    | j         j        | j        | j        fS )zR
        :return: A key tuple used to uniquely identify this `IPNetwork`.
        r   rR   r
  r  r   s    r   r,   zIPNetwork.key       |#TZ::r   c                     | j         dz
  }| j        | j        j        | j        z  z  }| j        |z
  }| j        j        |||fS )z[
        :return: A key tuple used to compare and sort this `IPNetwork` correctly.
        r   )r:  r   r   r   rF  rR   )r   net_size_bitsr
  	host_bitss       r   r.   zIPNetwork.sort_key  sI     !+t|3d6HHIK%'	|#UM9DDr   c                    d}| j         }| j        j        dk    r |d| j        | j        fz            }n| j        j        dk    rd| j        cxk    rt          j        k    r5n n2t          j        | j                  } |d|| j        dz
  fz            }nft          j        | j        cxk    rdk    r8n n5t          j        | j        dz
            } |d|| j        dz
  fz            }nt          d	| z            |S )
z
        :return: A numerically equivalent version 4 `IPNetwork` object.             Raises an `AddrConversionError` if IPv6 address cannot be             converted to IPv4.
        NrP   %s/%drQ   r   `   r   r   r   )
rz   r   rR   r   r1  r   rK   r   r   r   )r   r   r   r|   s       r   r
   zIPNetwork.ipv4  s)    <1$$w$'4>!::;;BB\!Q&&DK00005=00000'44U7dDNR,?%@@AA$+?????????'n(DEEU7dDNR,?%@@AA)KdR   	r   c                 p   d}| j         }| j        j        dk    rN|r2d| j        cxk    rdk    r n n || j        dz
  | j        fd          }nh || j        | j        fd          }nN| j        j        dk    r>|r || j        | j        dz   fd          }n |d| j        z   | j        dz   fd          }|S )a  
        .. note:: the IPv4-mapped IPv6 address format is now considered         deprecated. See RFC 4291 or later for details.

        :param ipv4_compatible: If ``True`` returns an IPv4-compatible address
            (::x.x.x.x), an IPv4-mapped (::ffff:x.x.x.x) address
            otherwise. Default: False (IPv4-mapped).

        :return: A numerically equivalent version 6 `IPNetwork` object.
        NrQ   r   r   rR  rP   rd  )rz   r   rR   r   r:  r   s       r   r   zIPNetwork.ipv6  s     <1$$ FNdk$S$S$S$S^$S$S$S$S$SUDK.8$/JTUVVVUDK91EEE\!Q&& \UDK2)=>JJJ UNT[8$/B:NOYZ[[[	r   r   c                 n    |                      d| j        | j        fz  | j        j                  }||z  }|S )z
        :param step: the number of IP subnets between this `IPNetwork` object
            and the expected subnet. Default: 1 (the previous IP subnet).

        :return: The adjacent subnet preceding this `IPNetwork` object.
        rc  rz   rD  r1  r   rR   r   r  ip_copys      r   previouszIPNetwork.previous"  8     ..DL$.+I!I4<K_``4r   c                 n    |                      d| j        | j        fz  | j        j                  }||z  }|S )z
        :param step: the number of IP subnets between this `IPNetwork` object
            and the expected subnet. Default: 1 (the next IP subnet).

        :return: The adjacent subnet succeeding this `IPNetwork` object.
        rc  rg  rh  s      r   nextzIPNetwork.next-  rk  r   c                 (   d|cxk    r| j         j        k    s n t          d|| j         j        fz            g }| j        }||_        |j        | j        k    r:|                    |j                   |xj        dz  c_        |j        | j        k    :|S )ab  
        Provides a list of supernets for this `IPNetwork` object between the
        size of the current prefix and (if specified) an endpoint prefix.

        :param prefixlen: (optional) a CIDR prefix for the maximum supernet.
            Default: 0 - returns all possible supernets.

        :return: a tuple of supernet `IPNetwork` objects.
        r   "CIDR prefix /%d invalid for IPv%d!r   )r   r   rx   rR   r]   r:  append)r   r1  	supernetssupernets       r   rr  zIPNetwork.supernet8  s     I3333!333334	4<CW7XX   	9'!T_44X]+++1$ !T_44 r   c              #     K   d| j         cxk    r| j        j        k    s n t          d|| j        j        fz            | j         |k    sdS | j        j        }d|| j         z
  z  d||z
  z  z  }||}d|cxk    r|k    sn t          d          | j                            | j                  }d}||k     rU|                     d||fz  | j        j                  }|xj        |j	        |z  z  c_        ||_         |dz  }|V  ||k     SdS dS )a  
        A generator that divides up this IPNetwork's subnet into smaller
        subnets based on a specified CIDR prefix.

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

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

        :return: an iterator containing IPNetwork subnet objects.
        r   ro  Nr(  r   z,count outside of current IP subnet boundary!rc  )
r1  r   r   rx   rR   r   r
  rz   r    r  )	r   r1  countfmtr   max_subnetsbase_subnetisubnets	            r   ry  zIPNetwork.subnetP  sT      DN8888dl&888884	4<CW7XX   ~**F "EDN23qUY=N7OO=EE(((([((((KLLLl--dj99%ii^^G{I.F$FH\]]FLLFK!O+LL(FFALLL %iiiiiir   c                     |                                  \  }}t          t          || j        j                  t          || j        j                            S )a  
        A generator that provides all the IP addresses that can be assigned
        to hosts within the range of this IP object's subnet.

        - for IPv4, the network and broadcast addresses are excluded, excepted           when using /31 or /32 subnets as per RFC 3021.

        - for IPv6, only Subnet-Router anycast address (first address in the           network) is excluded as per RFC 4291 section 2.6.1, excepted when using           /127 or /128 subnets as per RFC 6164.

        :return: an IPAddress iterator
        )_usable_ranger  rr   r   rR   r   first_usable_addresslast_usable_addresss      r   
iter_hostszIPNetwork.iter_hostsy  sT     594F4F4H4H11*DL,@AA)4<+?@@
 
 	
r   c                     | j         dk    r0| j        dz   }| j        j        dk    r| j        dz
  }n| j        }||fS | j        | j        fS )NrP   r   )r  r
  r   rR   r  r|  s      r   r{  zIPNetwork._usable_range  s_    9>>#':> |#q((&*i!m## '+i#(*=>>
 J	**r   c                 X    | j                             | j                  }|d| j        S )z&:return: this IPNetwork in CIDR formatrv   )r   r   r   r1  )r   r|   s     r   r   zIPNetwork.__str__  s,    |&&t{33$$//r   c                 &    | j         j        d| dS r   r   r   s    r   r   zIPNetwork.__repr__  r   r   r  r  r   r   )NN)&rj   rk   rl   rm   rn   r   r   r   r?  ro   r1  r   rD  rG  r
  r  r5  setterrC  rK  rF  r]   r   r   r#  r,   r.   r
   r   rj  rm  rr  ry  r  r{  r   r   r  r  s   @r   r8  r8    s       # #J  IJe J J J J J J JXB B BQ Q Q*      $$Q  I < < X< P P XP U U XU I I XI & & X& 8 8 X8
 ^
+ 
+ ^
+ 9 9 X9 9 9 X9
 A A XA 
 
 X
  *  *( ( (>; ; ;E E E  0   :	 	 	 		 	 	 	   0' ' ' 'R
 
 
(+ + +"0 0 0
< < < < < < <r   r8  c                   z    e Zd ZdZdZddZd Zd Zd Ze	d             Z
e	d	             Zd
 Zd Zd Zd Zd ZdS )rV  z
    An arbitrary IPv4 or IPv6 address range.

    Formed from a lower and upper bound IP address. The upper bound IP cannot
    be numerically smaller than the lower bound and the IP version of both
    must match.

    rW  rX  r   c                    t          ||          | _        | j        j        | _        t          || j        j        |          | _        t          | j                  t          | j                  k    rt          d          dS )a  
        Constructor.

        :param start: an IPv4 or IPv6 address that forms the lower
            boundary of this IP range.

        :param end: an IPv4 or IPv6 address that forms the upper
            boundary of this IP range.

        :param flags: (optional) decides which rules are applied to the
            interpretation of the start and end values. Refer to the :meth:`IPAddress.__init__`
            documentation for details.

        r)  z(lower bound IP greater than upper bound!N)rr   rW  r   rR   rX  r   r   )r   r  endr}   s       r   r   zIPRange.__init__  ss      U333{*c4<#7uEEE	t{c$)nn,,!"LMMM -,r   c                 H    | j         j        | j        j        | j        j        fS )z.:return: Pickled state of an `IPRange` object.)rW  r    rX  r   rR   r   s    r   r   zIPRange.__getstate__  s    { $)/4<3GGGr   c                     |\  }}}t          ||          | _        | j        j        | _        t          ||          | _        dS )zQ
        :param state: data used to unpickle a pickled `IPRange` object.
        N)rr   rW  r   rX  )r   r   r  r  rR   s        r   r   zIPRange.__setstate__  sB     $sGw//{*c7++			r   c                 Z   t          |t                    r| j        j        |j        j        k    rdS t          |t                    r*| j        j        |j        k    o| j        j        |j        k    S t          |t                    r4| j        j        |j        j        k    o| j        j        |j        j        k    S t          |t                    rL|j        j
        |j        z
  }|j        |z	  |z  }|d|z  z   dz
  }| j        j        |k    o| j        j        |k    S t	          |          | v S )NFr   )r   r   r   rR   rr   rW  r   rX  rV  r8  r   r:  )r   r6   rY  other_start	other_ends        r   r#  zIPRange.__contains__  s'   eV$$ 	[|#u}'<<<u%++ _{)U\9^di>NRWR^>^^%)) K&%,*== >	(EJ,== %++ ["]053CC
$|z9jH'1
?;a?	{)[8ZTY=MQZ=ZZ 4''r   c                 *    t          | j                  S )z?The integer value of first IP address in this `IPRange` object.)r   rW  r   s    r   r
  zIPRange.first  s     4;r   c                 *    t          | j                  S )z>The integer value of last IP address in this `IPRange` object.)r   rX  r   s    r   r  zIPRange.last  s     49~~r   c                 4    | j         j        | j        | j        fS )zP
        :return: A key tuple used to uniquely identify this `IPRange`.
        r]  r   s    r   r,   zIPRange.key  r^  r   c                     | j         j        | j                                        z
  }| j         j        | j        j        |fS )zY
        :return: A key tuple used to compare and sort this `IPRange` correctly.
        )r   r   r  
bit_lengthrR   rW  r   )r   skeys     r   r.   zIPRange.sort_key  s8     |!DI$8$8$:$::|#T[%7==r   c                 6    t          | j        | j                  S )zx
        The list of CIDR addresses found within the lower and upper bound
        addresses of this `IPRange`.
        )iprange_to_cidrsrW  rX  r   s    r   cidrszIPRange.cidrs  s    
  TY777r   c                 $    | j         d| j        S )z<:return: this `IPRange` in a common representational format.-r  r   s    r   r   zIPRange.__str__
  s    +++tyy11r   c                 @    | j         j        d| j        d| j        dS )r   r   z', 'r   )rz   rj   rW  rX  r   s    r   r   zIPRange.__repr__  s&    #'>#:#:#:DKKKSSr   Nr  )rj   rk   rl   rm   rn   r   r   r   r#  ro   r
  r  r,   r.   r  r   r   rp   r   r   rV  rV    s          #IN N N N*H H H, , ,( ( (*     X    X; ; ;> > >8 8 82 2 2T T T T Tr   rV  c               '   @   K   t          |           D ]}|D ]}|V  dS )z
    :param args: A list of IP addresses and subnets passed in as arguments.

    :return: A generator that flattens out IP subnets, yielding unique
        individual IP addresses (no duplicates).
    N)
cidr_merge)argsr]   r   s      r   iter_unique_ipsr    sH       4     	 	BHHHH	 r   c                    d }t          | t                    rd| v s| dk    r| S 	 t          |           }|d ||          S # t          $ r d| v r^|                     dd          \  }}	 dt          |          cxk    rdk    sn t          d	| d
          n# t          $ r | cY cY S w xY w| }d}|                    d          }t          |          dk    r| cY S t          dt          |          z
            D ]}|                    d           |'	  ||d                   }n# t          $ r | cY cY S w xY wd                    |          d|cY S t          t          f$ r | cY S w xY w)a  
    A function that converts abbreviated IPv4 CIDRs to their more verbose
    equivalent.

    :param abbrev_cidr: an abbreviated CIDR.

    Uses the old-style classful IP address rules to decide on a default
    subnet prefix if one is not explicitly provided.

    Only supports IPv4 addresses.

    Examples ::

        10                  - 10.0.0.0/8
        10/16               - 10.0.0.0/16
        128                 - 128.0.0.0/16
        128/8               - 128.0.0.0/8
        192.168             - 192.168.0.0/16

    :return: A verbose CIDR from an abbreviated CIDR or old-style classful         network address. The original value if it was not recognised as a         supported abbreviation.
    c                     t          |           } d| cxk    rdk    sn t          d| z            d| cxk    rdk    rn ndS d| cxk    rdk    rn ndS d	| cxk    rd
k    rn ndS d| cxk    rdk    rn ndS dS )Nr      zInvalid octet: %r!   r                           rP   r`   )r   r   )octets    r   classful_prefixz/cidr_abbrev_to_verbose.<locals>.classful_prefix:  s    E

E    S    1E9:::1E    S     2E    S     2E    S     1rr   : z.0.0.0/rv   r   r   r`   zprefixlen in address z out of range for IPv4!N.rP   0)r   ry   r   rx   r,  r+  rangerp  joinr   r   )abbrev_cidrr  rx  	part_addrprefixtokenss         r   cidr_abbrev_to_verboser    s.   6   +s## +!2!2% !??1#5#5#566 4 4 4+ + 1 1#q 9 9Iv#CKK----2----$*OZ{{\   .  # # #""""""# $IF%%v;;??q3v;;'' 	 	AMM#>#(33 # # #""""""# ((6****FF3333z"   se   A (E3./BE3B/*E3.B//1E3"9E3D.-E3.D?:E3>D??E3E32E3c                 0   t          | d          st          d          g }| D ]X}t          |t          t          f          r|}nt          |          }|                    |j        |j        |j        |f           Y|	                                 t          |          dz
  }|dk    r||         d         ||dz
           d         k    rs||         d         dz
  ||dz
           d         k    rO||         d         ||         d         t          ||dz
           d         ||         d                   f||dz
  <   ||= |dz  }|dk    g }|D ]}t          |          dk    r[|d         }t          |t                    r(|                    |                                           Z|                    |           p|d         }t          |d         |          }	t          |d         |          }
|                    t          |	|
                     |S )	a  
    A function that accepts an iterable sequence of IP addresses and subnets
    merging them into the smallest possible list of CIDRs. It merges adjacent
    subnets where possible, those contained within others and also removes
    any duplicates.

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

    :return: a summarized list of `IPNetwork` objects.
    r  z#A sequence or iterator is expected!r   r   r(  rP      rR  )r   rx   r   r8  rV  rp  rR   r  r
  sortr+  minextendr  rr   r  )ip_addrsrangesr   r   rx  mergedrange_tupleoriginalrR   range_start
range_stops              r   r  r  t  s%    8Z(( @>???F ? ?b9g.// 	 CCB--Cs{CHci=>>>>
KKMMMFaA
a%%!9Q<6!a%=+++q	!q0@F1q5MRSDT0T0T#AYq\6!9Q<VAE]1=MvVWyYZ|9\9\]F1q5Mq		Q	 a%%
 F E E{q  "1~H(G,, (hnn..////h''''!!nG#KNGDDDK";q>7CCCJMM*;
CCDDDDMr   c                 4    t          | |          \  }}}||z   S )a  
    Removes an exclude IP address or subnet from target IP subnet.

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

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

    :return: list of `IPNetwork` objects remaining after exclusion.
    )cidr_partition)targetexcludeleft_rights        r   cidr_excluder    s#     $FG44ND!U%<r   c                 t   t          |           } t          |          }|j        | j        k     rg g | j        gfS | j        |j        k     r| j        gg g fS | j        |j        k    rg | gg fS g }g }| j        dz   }| j        j        }| j        }|j        }|}|d||z
  z  z   }	|j        |k    r|j        |	k    r)|                    t          ||f|                     |	}
n(|                    t          |	|f|                     |}
|dz  }||k    rn|
}|
d||z
  z  z   }	|j        |k    ||g|ddd         fS )ac  
    Partitions a target IP subnet on an exclude IP address.

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

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

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

    Adding the three lists returns the equivalent of the original subnet.
    r   r(  rR  Nr  )	r8  r  r
  r]   r1  r   r   rR   rp  )r  r  r  r  new_prefixlentarget_module_widthtarget_firstrR   i_loweri_uppermatcheds              r   r  r    s    vF  G|fl"" 2}$$	w}	$	$ }b"$$7,,,F8RDE$q(M ..<LoGGa$7-$GHIG

}
,
,=G##KK	7M":GLLLMMMGGLLG]#;WMMMNNNG...Q#6#FGH 
}
,
,  'E$$B$K''r   c                 6   t          |           }	 t          t          |                    }t          t          |                    }n# t          $ r t	          d          w xY w||k     r|}|}n|}|}|D ]!}t          |          }||k     r|}||k    r|}"|j        |j        k    rt          d          |j        }|j        }	|j	        }
|j
        j        }|	dk    r#||
k    r|	dz  }	|d||	z
  z   z  }|	dk    r||
k    t          ||	f|j                  S )aO  
    Function that accepts a sequence of IP addresses and subnets returning
    a single `IPNetwork` subnet that is large enough to span the lower and
    upper bound IP addresses with a possible overlap on either end.

    :param ip_addrs: sequence of IP addresses and subnets.

    :return: a single spanning `IPNetwork` subnet.
    z-IP sequence must contain at least 2 elements!z.IP sequence cannot contain both IPv4 and IPv6!r   r   rR  )r  r8  rm  StopIterationrx   rR   r   r  r1  r
  r   r   )r  ip_addrs_iter	network_a	network_bmin_networkmax_networkr   rD  ipnumr1  lowest_ipnumr   s               r   spanning_cidrr    su    NNMJd=1122	d=1122		 J J JHIIIJ 9 " "B--[  !K[  !Kk111HIIIE%I$L%E
a--EL00Q	1*+,, a--EL00 eY'1DEEEEs   8A
 
A$r   c              #     K   t          |           } t          |          }| j        |j        k    rt          d          | j        }t          |          }|dk    rt	          d          t          |           } t          |          }d}|dk     rd}| |z
  }	 ||z  }|r	||k    sdS n||k    sdS t          ||          V  +)a  
    A generator that produces IPAddress objects between an arbitrary start
    and stop IP address with intervals of step between them. Sequences
    produce are inclusive of boundary IPs.

    :param start: start IP address.

    :param end: end IP address.

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

    :return: an iterator of one or more `IPAddress` objects.
    z(start and stop IP versions do not match!r   zstep argument cannot be zeroFTN)rr   rR   r   r   rx   )r  r  r  rR   r  negative_stepr  s          r   r  r     s       eE
C..C}##BCCCmGt99Dqyy7888 JJEs88DMaxxDLE( 	D== ! D==w'''''(r   c                    g }t          |           } t          |          }| j        |j        g}t          | |g          }| j        j        }|j        |d         k     rKt          |d         dz
  |f| j                  }t          ||          d         }|                                }|j        |d         k    r;t          |d         dz   |f| j                  }|t          ||          d         z  }n|	                    |           |S )a`  
    A function that accepts an arbitrary start and end IP address or subnet
    and returns a list of CIDR subnets that fit exactly between the boundaries
    of the two with no overlap.

    :param start: the start IP address or subnet.

    :param end: the end IP address or subnet.

    :return: a list of one or more IP addresses and subnets.
    r   r   rR  r(  )
r8  r
  r  r  r   r   rR   r  poprp  )r  r  	cidr_listiprange	cidr_spanr   r  s          r   r  r  N  s    IeE
C..C{CH%G ucl++IME##WQZ!^U3U]KKK"9g66q9	MMOO	~
""WQZ!^U3U]KKK^Iw77::		###r   c                     d}t          |d          st          d|d          t          |           } t          d |D                       D ]}| |v r|}	||j        |vr n|S )ab  
    Matches an IP address or subnet against a given sequence of IP addresses
    and subnets.

    :param ip: a single IP address or subnet.

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

    :return: the smallest (most specific) matching IPAddress or IPNetwork
        object from the provided sequence, None if there was no match.
    Nr  )IP address/subnet sequence expected, not !c                 ,    g | ]}t          |          S rp   r8  r   r]   s     r   
<listcomp>z*smallest_matching_cidr.<locals>.<listcomp>      :::D	$:::r   )r   r   rr   sortedrD  r   r  matchr]   s       r   smallest_matching_cidrr  r  s     E5*%% Si%%%QRRR	2B::E:::;;  ::EE T\%>%>Lr   c                     d}t          |d          st          d|d          t          |           } t          d |D                       D ]
}| |v r|} n|S )ab  
    Matches an IP address or subnet against a given sequence of IP addresses
    and subnets.

    :param ip: a single IP address or subnet.

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

    :return: the largest (least specific) matching IPAddress or IPNetwork
        object from the provided sequence, None if there was no match.
    Nr  r  r  c                 ,    g | ]}t          |          S rp   r  r  s     r   r  z)largest_matching_cidr.<locals>.<listcomp>  r  r   )r   r   rr   r  r  s       r   largest_matching_cidrr    s     E5*%% Si%%%QRRR	2B::E:::;;  ::EE  Lr   c                     g }t          |d          st          d|d          t          |           } t          d |D                       D ]/}| |v r|                    |           |r|j        |d         vr n0|S )aM  
    Matches an IP address or subnet against a given sequence of IP addresses
    and subnets.

    :param ip: a single IP address.

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

    :return: all matching IPAddress and/or IPNetwork objects from the provided
        sequence, an empty list if there was no match.
    r  r  r  c                 ,    g | ]}t          |          S rp   r  r  s     r   r  z&all_matching_cidrs.<locals>.<listcomp>  r  r   r  )r   r   rr   r  rp  rD  )r   r  matchesr]   s       r   all_matching_cidrsr    s     G5*%% Si%%%QRRR	2B::E:::;;  ::NN4     4<wr{::Nr   127.0.0.0/8
10.0.0.0/8172.16.0.0/12192.168.0.0/16169.254.0.0/16z224.0.0.0/4z192.88.99.0/24	0.0.0.0/8192.0.2.0/24240.0.0.0/4198.51.100.0/24203.0.113.0/24z233.252.0.0/24z	234.0.0.0z238.255.255.255z	225.0.0.0z231.255.255.255c                 ,    g | ]}t          |          S rp   r  r   r   s     r   r  r    s.        cNN  r   )r  r  z100.64.0.0/10r  r  r  z192.0.0.0/24z192.0.0.170/31r  r  z198.18.0.0/15r  r   r  z255.255.255.255/32c                 ,    g | ]}t          |          S rp   r  r  s     r   r  r    s+     * * *IcNN* * *r   )z192.0.0.9/32z192.0.0.10/32::1/128fc00::/7	fe80::/10zff00::/8z	ff00::/12z::/8z0100::/8z0200::/7z0400::/6z0800::/5z1000::/4z4000::/3z6000::/3z8000::/3zA000::/3zC000::/3zE000::/4zF000::/5zF800::/6zFE00::/9c                 ,    g | ]}t          |          S rp   r  r  s     r   r  r    s.        cNN  r   )
r  z::/128z::ffff:0:0/96z64:ff9b:1::/48z100::/64z	2001::/23z2001:db8::/32z	2002::/16r  r  c                 ,    g | ]}t          |          S rp   r  r  s     r   r  r  (  s.     
* 
* 
* cNN
* 
* 
*r   )z2001:1::1/128z2001:1::2/128z2001:3::/32z2001:4:112::/48z2001:20::/28z2001:30::/28r  r  )1rm   sysr  netaddr.corer   r   r   r   r   r   r	   netaddr.strategyr
   rK   r   rM   objectr   rr   r  r6  r8  rV  r  r  r  r  r  r  r  r  r  r  r  rS   r   rW   rL   	IPV4_6TO4r[   r   r   rT   r   rX   rN   r\   r   r   rp   r   r   <module>r     s   @ ?                      : 9 9 9 9 9 9 9I$ I$ I$ I$ I$V I$ I$ I$X^G ^G ^G ^G ^G ^G ^G ^GBh h h h h& h h hV5e 5 5 5 5 5p~< ~< ~< ~< ~< ~< ~< ~<BhT hT hT hT hTfk hT hT hTV	 	 	R R Rj0 0 0f  9( 9( 9(x+F +F +F\+( +( +( +(\! ! !H  8  4  > 	-(( IlIoI  ),--=))I&''	 IkInImI  IIGK*++GK*++
 I
    ** *?* * * & 	)$$Ij)) )K((:&& IkIfIjIjIjIjIjIjIjIjIjIjIjIjIjIj!&     
* 
*
* 
* 
* & & &r   