
    ^Xd                         d Z ddlmZmZmZ ddlmZmZ	 ddl
mZ ddlmZ ddlmZ ddlmZmZmZ  G d d	e      Z G d
 de      Z G d de      Z G d de      Zy)z]
Classes and functions for dealing with MAC addresses, EUI-48, EUI-64, OUI, IAB
identifiers.
    )NotRegisteredErrorAddrFormatErrorDictDotLookup)eui48eui64)	mac_eui48)
eui64_base)	IPAddress)_importlib_resources_is_int_is_strc                   8    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
y	)
BaseIdentifierz$Base class for all IEEE identifiers.)_value__weakref__c                     d | _         y Nr   selfs    6/usr/lib/python3/dist-packages/netaddr/eui/__init__.py__init__zBaseIdentifier.__init__   s	        c                     | j                   S z):return: integer value of this identifierr   r   s    r   __int__zBaseIdentifier.__int__       {{r   c                     | j                   S r   r   r   s    r   __long__zBaseIdentifier.__long__   r   r   c                 @    | j                   dk(  ryd| j                   z  S )z8:return: octal string representation of this identifier.r   0z0%or   r   s    r   __oct__zBaseIdentifier.__oct__"   s"     ;;!t{{""r   c                      d| j                   z  S )z>:return: hexadecimal string representation of this identifier.z0x%xr   r   s    r   __hex__zBaseIdentifier.__hex__)   s     ##r   c                     | j                   S )zx
        :return: return the integer value of this identifier when passed to
            hex(), oct() or bin().
        r   r   s    r   	__index__zBaseIdentifier.__index__.   s     {{r   N)__name__
__module____qualname____doc__	__slots__r   r   r   r"   r$   r&    r   r   r   r      s(    .)I#$
r   r   c                   h     e Zd ZdZdZ fdZd Zd Zd Zd Z	d Z
ed	        Zdd
Zd Zd Z xZS )OUIz
    An individual IEEE OUI (Organisationally Unique Identifier).

    For online details see - http://standards.ieee.org/regauth/oui/

    )recordsc                    t         t        |           ddlm} g | _        t        |t              r"t        |j                  dd      d      | _
        n=t        |      r$d|cxk  rdk  rn n|| _
        nt        d|      t        d|      | j                  |j                  v rt        j                   t"        d	      }|j                  | j                     D ]I  \  }}|j%                  |       |j'                  |      j)                  d
      }| j+                  |||       K |j-                          yt/        d|d      )z
        Constructor

        :param oui: an OUI string ``XX-XX-XX`` or an unsigned integer.             Also accepts and parses full MAC/EUI-48 address strings (but not             MAC/EUI-48 integers)!
        r   ieee-     z OUI int outside expected range: zunexpected OUI format: zoui.txtUTF-8zOUI z not registered!N)superr.   r   netaddr.euir2   r/   
isinstancestrintreplacer   r   
ValueError	TypeError	OUI_INDEXr   open_binary__package__seekreaddecode_parse_datacloser   )r   ouir2   fhoffsetsizedata	__class__s          r   r   zOUI.__init__@   s    	c4!# 	%c3 ckk#r2B7DKS\C#8#! !NOO3@AA ;;$..(%11+yIB"&.."= 5wwt}++G4  vt45 HHJ$%FGGr   c                     t        |t              s	 | j                  |      }| j
                  |j
                  k(  S # t        $ r	 t        cY S w xY wr   r:   r.   rM   	ExceptionNotImplementedr   r   others     r   __eq__z
OUI.__eq__g   K    %%&u- {{ell**  &%%&   < AAc                     t        |t              s	 | j                  |      }| j
                  |j
                  k7  S # t        $ r	 t        cY S w xY wr   rO   rR   s     r   __ne__z
OUI.__ne__o   rU   rV   c                 2    | j                   | j                  fS )z+:returns: Pickled state of an `OUI` object.r   r/   r   s    r   __getstate__zOUI.__getstate__w   s    {{DLL((r   c                 "    |\  | _         | _        y)z;:param state: data used to unpickle a pickled `OUI` object.NrZ   r   states     r   __setstate__zOUI.__setstate__{   s    $)!T\r   c                 D   dddg ||d}|j                  d      D ]h  }|j                         }|sd|v r6| j                  |d<   |j                  dd      d   |d	<   t        |       |d
<   Pd|v rU|d   j	                  |       j | j
                  j	                  |       y)z.Returns a dict record from raw OUI record datar   r4   )idxrH   orgaddressrJ   rK   
(hex)ra   N   rb   rH   	(base 16)rc   )splitstripr   r;   appendr/   )r   rL   rJ   rK   recordlines         r   rF   zOUI._parse_data   s     
 JJt$ 	/D::<D$ $u $

4 3A 6u #D	u$y!((.	/ 	F#r   c                 ,    t        | j                        S )z0Number of registered organisations with this OUI)lenr/   r   s    r   	reg_countzOUI.reg_count   s     4<<  r   c                 2    t        | j                  |         S )a  
        The IEEE registration details for this OUI.

        :param index: the index of record (may contain multiple registrations)
            (Default: 0 - first registration)

        :return: Objectified Python data structure containing registration
            details.
        )r   r/   )r   indexs     r   registrationzOUI.registration   s     T\\%011r   c                 H    | j                   }d|dz	  dz  |dz	  dz  |dz  fz  S )z*:return: string representation of this OUI%02X-%02X-%02Xr5         r   r   int_vals     r   __str__zOUI.__str__   s<    ++B$&A%$#    	 r   c                     d| z  S )@:return: executable Python string to recreate equivalent object.z	OUI('%s')r,   r   s    r   __repr__zOUI.__repr__       T!!r   )r   )r'   r(   r)   r*   r+   r   rT   rX   r[   r_   rF   propertyro   rr   ry   r|   __classcell__rM   s   @r   r.   r.   7   sR     I%HN++)*$6 ! !
2 "r   r.   c                   l     e Zd ZdZ	 dZedd       Zd fd	Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Z xZS )IAB)iP  iU@ )rk   c                     |dz	  | j                   v r|dfS d}d|z  }|dz	  }||z  |z
  }|dz	  | j                   v r"|r|dk7  rt        dt        |      z        ||fS t        dt        |      z        )z
        :param eui_int: a MAC IAB as an unsigned integer.

        :param strict: If True, raises a ValueError if the last 12 bits of
            IAB MAC/EUI-48 address are non-zero, ignores them otherwise.
            (Default: False)
           r   i      z%r is not a strict IAB!z%r is not an IAB address!)IAB_EUI_VALUESr>   hex)clseui_intstrict	user_maskiab_maskiab_bits	user_bitss          r   split_iab_maczIAB.split_iab_mac   s     rMc000A:	9,b=x'83	Ns111)q. !:S^!KLL "" 83w<GHHr   c                    t         t        |           ddlm} dddg ddd| _        t        |t              r:t        |j                  dd      d      }| j                  ||      \  }}|| _        n8t        |      r| j                  ||      \  }}|| _        nt        d|d	      | j                  |j                  v rt        j                   t"        d
      }|j                  | j                     d   \  }}	|| j
                  d<   |	| j
                  d<   |j%                  |       |j'                  |	      j)                  d      }
| j+                  |
||	       |j-                          yt/        d|d      )a  
        Constructor

        :param iab: an IAB string ``00-50-C2-XX-X0-00`` or an unsigned             integer. This address looks like an EUI-48 but it should not             have any non-zero bits in the last 3 bytes.

        :param strict: If True, raises a ValueError if the last 12 bits             of IAB MAC/EUI-48 address are non-zero, ignores them otherwise.             (Default: False)
        r   r1   r4   )ra   iabrb   rc   rJ   rK   r3   r5   )r   zunexpected IAB format: !ziab.txtrJ   rK   r7   zIAB z not unregistered!N)r8   r   r   r9   r2   rk   r:   r;   r<   r=   r   r   r   r?   	IAB_INDEXr   rA   rB   rC   rD   rE   rF   rG   r   )r   r   r   r2   rx   iab_intuser_intrI   rJ   rK   rL   rM   s              r   r   zIAB.__init__   sW    	c4!# 	% 
 c3 #++c2.3G $ 2 276 2 JGX!DKS\ $ 2 23v 2 FGX!DKCABB ;;$..(%11+yIB!^^DKK8;NVT$*DKK!"&DKKGGFO774=''0DT640HHJ$3%HIIr   c                     t        |t              s	 | j                  |      }| j
                  |j
                  k(  S # t        $ r	 t        cY S w xY wr   r:   r   rM   rP   rQ   r   rR   s     r   rT   z
IAB.__eq__  rU   rV   c                     t        |t              s	 | j                  |      }| j
                  |j
                  k7  S # t        $ r	 t        cY S w xY wr   r   rR   s     r   rX   z
IAB.__ne__  rU   rV   c                 2    | j                   | j                  fS )z+:returns: Pickled state of an `IAB` object.r   rk   r   s    r   r[   zIAB.__getstate__   s    {{DKK''r   c                 "    |\  | _         | _        y)z;:param state: data used to unpickle a pickled `IAB` object.Nr   r]   s     r   r_   zIAB.__setstate__$  s    #( T[r   c                 L   |j                  d      D ]  }|j                         }|sd|v rT| j                  | j                  d<   |j                  dd      d   | j                  d<   t	        |       | j                  d<   nd|v rs| j                  d	   j                  |        y)
z.Returns a dict record from raw IAB record datard   re   ra   Nrf   rb   r   rg   rc   )rh   ri   r   rk   r;   rj   )r   rL   rJ   rK   rl   s        r   rF   zIAB._parse_data(  s    JJt$ 	4D::<D$%)[[E"%)ZZa%8%;E"%(YE"$I&--d3	4r   c                 ,    t        | j                        S )z*The IEEE registration details for this IAB)r   rk   r   s    r   rr   zIAB.registration8  s    T[[))r   c                 j    | j                   dz  }d|dz	  dz  |dz	  dz  |dz	  dz  |dz	  dz  |dz  fz  S )z*:return: string representation of this IAB   z%02X-%02X-%02X-%02X-%02X-00    ru      r5   rv   r   rw   s     r   ry   zIAB.__str__<  sY    ++",B$&B$&B$&A%$0    	 r   c                     d| z  S )r{   z	IAB('%s')r,   r   s    r   r|   zIAB.__repr__G  r}   r   )F)r'   r(   r)   r   r+   classmethodr   r   rT   rX   r[   r_   rF   rr   ry   r|   r   r   s   @r   r   r      sU    )N I# #02Jh++()4 *	 "r   r   c                   n    e Zd ZdZdZd( fd	Zd Zd Zd Zd Z	 e
ee	dd	      Zd
 Zd Zd Z e
eedd      Ze
d        Ze
d        Zd Ze
d        Ze
d        Zd Zd 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!d  Z"d! Z#d" Z$d# Z%e
d$        Z&d)d%Z'd& Z(d' Z) xZ*S )*EUIz
    An IEEE EUI (Extended Unique Identifier).

    Both EUI-48 (used for layer 2 MAC addresses) and EUI-64 are supported.

    Input parsing for EUI-48 addresses is flexible, supporting many MAC
    variants.

    )_module_dialectNc                    t         t        |           d| _        t	        |t              rZ|$||j                  j
                  k7  rt        d      |j                  | _        |j                  | _        |j                  | _        y|0|dk(  rt        | _        n]|dk(  rt        | _        nLt        d|z        t        |      r3d|cxk  rdk  rn nt        | _        nd|cxk  rdk  rn nt        | _        || _        || _        y)	a2  
        Constructor.

        :param addr: an EUI-48 (MAC) or EUI-64 address in string format or             an unsigned integer. May also be another EUI object (copy             construction).

        :param version: (optional) the explicit EUI address version, either             48 or 64. Mainly used to distinguish EUI-48 and EUI-64 identifiers             specified as integers which may be numerically equivalent.

        :param dialect: (optional) the mac_* dialect to be used to configure             the formatting of EUI-48 (MAC) addresses.
        Nz2cannot switch EUI versions using copy constructor!0   @   zunsupported EUI version %rr   r   l    )r8   r   r   r   r:   versionr>   r   dialect_eui48_eui64r   value)r   addrr   r   rM   s       r   r   zEUI.__init__X  s     	c4!#dC "w$,,2F2F'F  "( ) )<<DL++DK<<DL"}%B% !=!GHH t}..#)DL#d@.@@#)DL
 r   c                 \    | j                   | j                  j                  | j                  fS )z+:returns: Pickled state of an `EUI` object.)r   r   r   r   r   s    r   r[   zEUI.__getstate__  s!    {{DLL00$,,>>r   c                     |\  }}}|| _         |dk(  rt        | _        || _        y|dk(  rt        | _        || _        yt	        d|      )zN
        :param state: data used to unpickle a pickled `EUI` object.

        r   r   z$unpickling failed for object state: N)r   r   r   r   r>   r   )r   r^   r   r   r   s        r   r_   zEUI.__setstate__  s^    
 #(wb=!DL  ]!DL
    r   c                     | j                   S r   r   r   s    r   
_get_valuezEUI._get_value  s    {{r   c                    | j                   Kt        t        fD ]!  }	 |j                  |      | _        || _          n | j                   t        d|      y t        |      r"	 | j                   j                  |      | _        y dt        |      cxk  r| j                   j                  k  rn nt        |      | _        y t        d|      # t
        $ rP 	 dt        |      cxk  r|j                  k  rn nt        |      | _        || _         Y  n# t        $ r Y nw xY wY w xY w# t
        $ r% t        d|| j                   j                  fz        w xY w)Nr   zfailed to detect EUI version: zaddress %r is not an EUIv%dzbad address format: )r   r   r   
str_to_intr   r   r<   max_intr>   r   r   )r   r   modules      r   
_set_valuezEUI._set_value  sJ   <<!6* "("3"3E":DK#)DL	 ||#%'     $
 u~9"&,,"9"9%"@DK
 E
:dll&:&::"%e*DK)e*MNN1 ' E
<fnn<*-e*DK+1DL!% " ' 9)*G $,,"6"67+8 9 99sA   C$ D+ 	D(8DD(	D!D( D!!D('D(+.EzBa positive integer representing the value of this EUI indentifier.c                     | j                   S r   )r   r   s    r   _get_dialectzEUI._get_dialect  s    }}r   c                     || j                   t        u rt        S t        S t	        |d      rt	        |d      r|S t        d      )N	word_sizeword_fmtz*custom dialects should subclass mac_eui48!)r   r   r	   r   hasattrr?   r   r   s     r   _validate_dialectzEUI._validate_dialect  sC    =||v%    uk*wuj/I LMMr   c                 0    | j                  |      | _        y r   )r   r   r   s     r   _set_dialectzEUI._set_dialect  s    ..u5r   zXa Python class providing support for the interpretation of various MAC
 address formats.c                     | j                   t        k(  rt        | j                  dz	        S | j                   t        k(  rt        | j                  dz	        S y)z:The OUI (Organisationally Unique Identifier) for this EUI.r   (   N)r   r   r.   r   r   r   s    r   rH   zEUI.oui  sI     <<6!tzzR'((\\V#tzzR'(( $r   c                     | j                   t        k(  rdt        | dd       z  S | j                   t        k(  rdt        | dd       z  S y)z*The EI (Extension Identifier) for this EUIrt         z%02X-%02X-%02X-%02X-%02Xrv   N)r   r   tupler   r   s    r   eizEUI.ei  sM     <<6!#eD1I&666\\V#-d1Qi0@@@ $r   c                 @    | j                   dz	  t        j                  v S )z<:return: True if this EUI is an IAB address, False otherwiser   )r   r   r   r   s    r   is_iabz
EUI.is_iab  s    r!c&8&888r   c                 T    | j                         rt        | j                  dz	        S y)zr
        If is_iab() is True, the IAB (Individual Address Block) is returned,
        ``None`` otherwise.
        r   N)r   r   r   r   s    r   r   zEUI.iab  s&     ;;=t{{b()) r   c                 .    | j                   j                  S )z/The EUI version represented by this EUI object.)r   r   r   s    r   r   zEUI.version  s     ||###r   c                     t        |      ro| j                  j                  }| |cxk  r|dz
  k  st        d       t        d      | j                  j                  | j                  | j                        |   S t        |t              ra| j                  j                  | j                  | j                        }t        |j                  t        |             D cg c]  }||   	 c}S t        d|d      c c}w )z
        :return: The integer value of the word referenced by index (both             positive and negative). Raises ``IndexError`` if index is out             of bounds. Also supports Python list slices for accessing             word groups.
           z!index out range for address type!zunsupported type r   )r   r   	num_words
IndexErrorr   int_to_wordsr   r:   slicerangeindicesrn   r?   )r   ra   r   wordsis        r   __getitem__zEUI.__getitem__  s     3<//IJ399q=9 !DEE : !DEE<<,,T[[$--HMMU#LL--dkk4==IE&+S[[U-D&EFE!HFFc;<< Gs   C;c                 >   t        |t              rt        d      t        |      st	        d      d|cxk  r| j
                  j                  dz
  k  sn t        d|fz        t        |      st	        d      d|cxk  r| j
                  j                  k  s&n t        d|| j
                  j                  fz        t        | j                  j                  | j                  | j
                              }|||<   | j                  j                  |      | _        y)	z=Set the value of the word referenced by index in this addressz"settable slices are not supported!zindex not an integer!r   r   z'index %d outside address type boundary!zvalue not an integer!z.value %d outside word size maximum of %d bits!N)r:   r   NotImplementedErrorr   r?   r   r   r   max_wordr   listr   r   r   words_to_int)r   ra   r   r   s       r   __setitem__zEUI.__setitem__  s    c5!%&JKKs|344C8DMM33a78F#OPPu~344E3T]]333M$--1123 4 4 T\\..t{{DMMJKc
ll//6r   c                 D    t        | j                  | j                  f      S )zA:return: hash of this EUI object suitable for dict keys, sets etc)hashr   r   r   s    r   __hash__zEUI.__hash__+  s    T\\4;;/00r   c                     t        |t              s	 | j                  |      }| j
                  | j                  f|j
                  |j                  fk(  S # t        $ r	 t        cY S w xY wzy
        :return: ``True`` if this EUI object is numerically the same as other,             ``False`` otherwise.
        r:   r   rM   rP   rQ   r   r   rR   s     r   rT   z
EUI.__eq__/  _    
 %%&u- dkk*u}}ell.KKK  &%%&   A A&%A&c                     t        |t              s	 | j                  |      }| j
                  | j                  f|j
                  |j                  fk7  S # t        $ r	 t        cY S w xY wr   r   rR   s     r   rX   z
EUI.__ne__;  r   r   c                     t        |t              s	 | j                  |      }| j
                  | j                  f|j
                  |j                  fk  S # t        $ r	 t        cY S w xY w)z
        :return: ``True`` if this EUI object is numerically lower in value than             other, ``False`` otherwise.
        r   rR   s     r   __lt__z
EUI.__lt__G  _    
 %%&u- dkk*emmU\\-JJJ  &%%&r   c                     t        |t              s	 | j                  |      }| j
                  | j                  f|j
                  |j                  fk  S # t        $ r	 t        cY S w xY w)z
        :return: ``True`` if this EUI object is numerically lower or equal in             value to other, ``False`` otherwise.
        r   rR   s     r   __le__z
EUI.__le__S  r   r   c                     t        |t              s	 | j                  |      }| j
                  | j                  f|j
                  |j                  fkD  S # t        $ r	 t        cY S w xY w)z
        :return: ``True`` if this EUI object is numerically greater in value             than other, ``False`` otherwise.
        r   rR   s     r   __gt__z
EUI.__gt___  r   r   c                     t        |t              s	 | j                  |      }| j
                  | j                  f|j
                  |j                  fk\  S # t        $ r	 t        cY S w xY w)z
        :return: ``True`` if this EUI object is numerically greater or equal             in value to other, ``False`` otherwise.
        r   rR   s     r   __ge__z
EUI.__ge__k  r   r   c                 N    | j                   j                  | j                  |      S )z
        :param word_sep: (optional) the separator to insert between words.             Default: None - use default separator for address type.

        :return: human-readable binary digit string of this address.
        )r   int_to_bitsr   )r   word_seps     r   bitszEUI.bitsw  s     ||''X>>r   c                 L    | j                   j                  | j                        S )z8The value of this EUI address as a packed binary string.)r   int_to_packedr   r   s    r   packedz
EUI.packed  s     ||))$++66r   c                 L    | j                   j                  | j                        S )z<A list of unsigned integer octets found in this EUI address.)r   r   r   r   s    r   r   z	EUI.words  s     ||((55r   c                 L    | j                   j                  | j                        S )z
        The value of this EUI adddress 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EUI.bin  s     ||&&t{{33r   c                     | j                   dk(  r*| j                  dz	  }| j                  dz  }|dz  dz  |z  }n| j                  }| j                  |d      S )a2  
        - If this object represents an EUI-48 it is converted to EUI-64             as per the standard.
        - If this object is already an EUI-64, a new, numerically             equivalent object is returned instead.

        :return: The value of this EUI object as a new 64-bit EUI object.
        r   r   r6   r   l      |r   r   )r   r   rM   )r   first_three
last_three	new_values       r   r   z	EUI.eui64  s^     <<2+++Kx/J$*l:ZGI I~~i~44r   c                 P    | j                         }|xj                  dz  c_        |S )z
        - create a new EUI object with a modified EUI-64 as described in RFC 4291 section 2.5.1

        :return: a new and modified 64-bit EUI object.
        l          )r   r   )r   r   s     r   modified_eui64zEUI.modified_eui64  s#     

::r   c                 f    t        |      t        | j                               z   }t        |d      S )a5  
        .. note:: This poses security risks in certain scenarios.             Please read RFC 4941 for details. Reference: RFCs 4291 and 4941.

        :param prefix: ipv6 prefix

        :return: new IPv6 `IPAddress` object based on this `EUI`             using the technique described in RFC 4291.
        r   r   )r<   r  r
   )r   prefixrx   s      r   ipv6zEUI.ipv6  s-     f+D$7$7$9 ::!,,r   c                 $    | j                  d      S )a  
        .. note:: This poses security risks in certain scenarios.             Please read RFC 4941 for details. Reference: RFCs 4291 and 4941.

        :return: new link local IPv6 `IPAddress` object based on this `EUI`             using the technique described in RFC 4291.
        l	                  @ )r  r   s    r   ipv6_link_localzEUI.ipv6_link_local  s     yy;<<r   c                     d| j                   j                         i}| j                         r| j                  j                         |d<   t	        |      S )z
        A record dict containing IEEE registration details for this EUI
        (MAC-48) if available, None otherwise.
        r.   r   )rH   rr   r   r   r   )r   rL   s     r   infozEUI.info  sE     txx,,./;;=((//1DKT""r   c                 p    | j                  |      }| j                  j                  | j                  |      S )a"  
        Format the EUI into the representational format according to the given
        dialect

        :param dialect: the mac_* dialect defining the formatting of EUI-48             (MAC) addresses.

        :return: EUI in representational format according to the given dialect
        )r   r   
int_to_strr   )r   r   validated_dialects      r   formatz
EUI.format  s1     !227;||&&t{{4EFFr   c                 b    | j                   j                  | j                  | j                        S )z':return: EUI in representational format)r   r  r   r   r   s    r   ry   zEUI.__str__  s!    ||&&t{{DMMBBr   c                     d| z  S )r{   z	EUI('%s')r,   r   s    r   r|   zEUI.__repr__  r}   r   )NNr   )+r'   r(   r)   r*   r+   r   r[   r_   r   r   r~   r   r   r   r   r   rH   r   r   r   r   r   r   r   rT   rX   r   r   r   r   r   r   r   r   r   r  r  r  r
  r  ry   r|   r   r   s   @r   r   r   L  sl    (I0d?& OD ZTLNE
N6 |\4	)*G ) ) A A9 * * $ $=&7.1
L
L
K
L
K
L? 7 7 6 6 4 45& -= 	# 	#GC"r   r   N)r*   netaddr.corer   r   r   netaddr.strategyr   r   r   r   netaddr.strategy.eui48r   netaddr.strategy.eui64r	   
netaddr.ipr
   netaddr.compatr   r   r   objectr   r.   r   r   r,   r   r   <module>r     s^   
 L K = , -   A A!V !H~". ~"BQ". Q"h`". `"r   