U
    d6                     @   s|  U d Z ddlZddlZddlZddlmZmZmZmZ ddl	Z
ddlZ
ddlZ
ddlZ
G dd de
jjZG dd dZG dd	 d	eZG d
d deZG dd de
jjZG dd deZejeejeiZeeef ed< eedddZeeef dedddZeeef eeeedddZeeddddZ ej!Z!ej"Z"ej#Z#ej$Z$ejZej%Z%ej&Z&ej'Z'ej(Z(ej)Z)ejZdS )zEDNS Options    N)AnyDictOptionalUnionc                   @   sD   e 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d ZdS )
OptionType               	   
               c                 C   s   dS Ni   clsr   r   ,/tmp/pip-unpacked-wheel-pk5slln3/dns/edns.py_maximum7   s    zOptionType._maximumN)__name__
__module____qualname__NSIDDAUDHUN3UECSEXPIRECOOKIE	KEEPALIVEPADDINGCHAINEDEclassmethodr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZeeef dddZdee	 ee
 dddZeed	d d
ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )Optionz%Base class for all EDNS option types.otypec                 C   s   t || _dS )z_Initialize an option.

        *otype*, a ``dns.edns.OptionType``, is the option type.
        N)r   maker)   )selfr)   r   r   r   __init__@   s    zOption.__init__Nfilereturnc                 C   s   t dS )zUConvert an option to wire format.

        Returns a ``bytes`` or ``None``.

        NNotImplementedErrorr+   r.   r   r   r   to_wireG   s    zOption.to_wiredns.wire.Parserr)   parserr/   c                 C   s   t dS )a  Build an EDNS option object from wire format.

        *otype*, a ``dns.edns.OptionType``, is the option type.

        *parser*, a ``dns.wire.Parser``, the parser, which should be
        restructed to the option length.

        Returns a ``dns.edns.Option``.
        Nr0   r   r)   r6   r   r   r   from_wire_parserO   s    zOption.from_wire_parserc                 C   s,   |   }|  }||krdS ||kr(dS dS )zCompare an EDNS option with another option of the same type.

        Returns < 0 if < *other*, 0 if == *other*, and > 0 if > *other*.
        r      )r3   )r+   otherwireZowirer   r   r   _cmp\   s    zOption._cmpc                 C   s,   t |tsdS | j|jkrdS | |dkS )NFr   
isinstancer'   r)   r=   r+   r;   r   r   r   __eq__i   s
    
zOption.__eq__c                 C   s,   t |tsdS | j|jkrdS | |dkS )NTr   r>   r@   r   r   r   __ne__p   s
    
zOption.__ne__c                 C   s(   t |tr| j|jkrtS | |dk S Nr   r?   r'   r)   NotImplementedr=   r@   r   r   r   __lt__w   s    zOption.__lt__c                 C   s(   t |tr| j|jkrtS | |dkS rC   rD   r@   r   r   r   __le__|   s    zOption.__le__c                 C   s(   t |tr| j|jkrtS | |dkS rC   rD   r@   r   r   r   __ge__   s    zOption.__ge__c                 C   s(   t |tr| j|jkrtS | |dkS rC   rD   r@   r   r   r   __gt__   s    zOption.__gt__c                 C   s   |   S N)to_textr+   r   r   r   __str__   s    zOption.__str__)N)r   r   r   __doc__r   r   strr,   r   r   bytesr3   r&   r8   r=   rA   rB   rF   rG   rH   rI   rM   r   r   r   r   r'   <   s   r'   c                       s~   e Zd ZdZeeef eeef d fddZde	e
 e	e dddZed	d
dZeeeef dedddZ  ZS )GenericOptionzwGeneric Option Class

    This class is used for EDNS option types for which we have no better
    implementation.
    )r)   datac                    s"   t  | tjj|d| _d S )NT)superr,   dnsrdataRdataZ	_as_bytesrR   )r+   r)   rR   	__class__r   r   r,      s    zGenericOption.__init__Nr-   c                 C   s   |r| | j d S | jS d S rJ   )writerR   r2   r   r   r   r3      s    zGenericOption.to_wirer/   c                 C   s
   d| j  S )Nz
Generic %dr(   rL   r   r   r   rK      s    zGenericOption.to_textr4   r5   c                 C   s   | ||  S rJ   )get_remainingr7   r   r   r   r8      s    zGenericOption.from_wire_parser)N)r   r   r   rN   r   r   rO   rP   r,   r   r   r3   rK   r&   r'   r8   __classcell__r   r   rW   r   rQ      s   $
 rQ   c                       s   e Zd ZdZdeee ed fddZeddd	Ze	ee
d
ddZdee ee dddZeeeef de
dddZ  ZS )	ECSOptionz!EDNS Client Subnet (ECS, RFC7871)Nr   )addresssrclenscopelenc           	         s^  t  tj tj|}|tjkrjd| _	|dkr6d}tj
j|}tj
j|dd}tj
j|dd}nX|tjkrd| _	|dkrd}tj
j|}tj
j|dd}tj
j|dd}ntd	|dk	st|| _|| _|| _tj||}tt|d
 }|d| | _|d }|dkrZtdt| jdd dd| > @ }| jdd | | _dS )a  *address*, a ``str``, is the client address information.

        *srclen*, an ``int``, the source prefix length, which is the
        leftmost number of bits of the address to be used for the
        lookup.  The default is 24 for IPv4 and 56 for IPv6.

        *scopelen*, an ``int``, the scope prefix length.  This value
        must be 0 in queries, and should be set in responses.
           N8   r      r9          zBad address family       @r   Br:      )rS   r,   r   r   rT   ZinetZaf_for_addresssocketAF_INET6familyrU   rV   Z_as_ipv6_address_as_intAF_INETZ_as_ipv4_address
ValueErrorAssertionErrorr^   r_   r`   	inet_ptonintmathceiladdrdatastructpackord)	r+   r^   r_   r`   afrt   nbytesnbitslastrW   r   r   r,      s8    


&zECSOption.__init__rZ   c                 C   s   d | j| j| jS )NzECS {}/{} scope/{})formatr^   r_   r`   rL   r   r   r   rK      s    zECSOption.to_text)textr/   c           
      C   s(  d}|   }d}t|dkr&|d }n>t|dkrV|d |krLtd| |d }ntd| |d}|dkr| d\}}d}n(|dkr| d\}}}ntd| zt|}W n& tk
r   td	d
| Y nX zt|}	W n( tk
r   tdd| Y nX t||	|S )a  Convert a string into a `dns.edns.ECSOption`

        *text*, a `str`, the text form of the option.

        Returns a `dns.edns.ECSOption`.

        Examples:

        >>> import dns.edns
        >>>
        >>> # basic example
        >>> dns.edns.ECSOption.from_text('1.2.3.4/24')
        >>>
        >>> # also understands scope
        >>> dns.edns.ECSOption.from_text('1.2.3.4/24/32')
        >>>
        >>> # IPv6
        >>> dns.edns.ECSOption.from_text('2001:4b98::1/64/64')
        >>>
        >>> # it understands results from `dns.edns.ECSOption.to_text()`
        >>> dns.edns.ECSOption.from_text('ECS 1.2.3.4/24/32')
        r   Nr9   r   ra   zcould not parse ECS from "{}"/0zinvalid scope z"{}": scope must be an integerzinvalid srclen z"{}": srclen must be an integer)splitlenrn   r|   countrq   r]   )
r}   Zoptional_prefixtokensZecs_textZ	n_slashesr^   ZtsrclenZtscopescoper_   r   r   r   	from_text   s<    




zECSOption.from_textr-   c                 C   s6   t d| j| j| j| j }|r.|| d S |S d S )N!HBB)ru   rv   rk   r_   r`   rt   rY   r+   r.   valuer   r   r   r3     s    
zECSOption.to_wirer4   r5   c           
      C   s   | d\}}}tt|d }||}|dkrRd| }tj|d|  }	n.|dkrxd| }tj|d|  }	nt	d| |	||S )	Nr   rf   r9          ra      zunsupported family)
Z
get_structrq   rr   rs   	get_bytesrT   Zipv4	inet_ntoaZipv6rn   )
r   r)   r6   rk   srcr   Zaddrlenprefixpadaddrr   r   r   r8   $  s    
zECSOption.from_wire_parser)Nr   )N)r   r   r   rN   rO   r   rq   r,   rK   staticmethodr'   r   r   rP   r3   r&   r   r   r8   r\   r   r   rW   r   r]      s   /8

 r]   c                   @   s|   e 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dZdZdZdZdZdZdZdZdZdZedd ZdS )EDECoder   r9   ra   r   r   r   r	   r
   r   r   r   r   r   r      r   r                        rd   c                 C   s   dS r   r   r   r   r   r   r   R  s    zEDECode._maximumN)r   r   r   OTHERZUNSUPPORTED_DNSKEY_ALGORITHMZUNSUPPORTED_DS_DIGEST_TYPEZSTALE_ANSWERZFORGED_ANSWERZDNSSEC_INDETERMINATEZDNSSEC_BOGUSZSIGNATURE_EXPIREDZSIGNATURE_NOT_YET_VALIDZDNSKEY_MISSINGZRRSIGS_MISSINGZNO_ZONE_KEY_BIT_SETZNSEC_MISSINGZCACHED_ERRORZ	NOT_READYZBLOCKEDZCENSOREDZFILTEREDZ
PROHIBITEDZSTALE_NXDOMAIN_ANSWERZNOT_AUTHORITATIVEZNOT_SUPPORTEDZNO_REACHABLE_AUTHORITYZNETWORK_ERRORZINVALID_DATAr&   r   r   r   r   r   r   7  s6   r   c                       s|   e Zd ZdZdeeef ee d fddZedddZ	dee
 ee d	d
dZeeeef dedddZ  ZS )	EDEOptionz!Extended DNS Error (EDE, RFC8914)Ncoder}   c                    s>   t  tj t|| _|dk	r4t|ts4t	d|| _
dS )z*code*, a ``dns.edns.EDECode`` or ``str``, the info code of the
        extended error.

        *text*, a ``str`` or ``None``, specifying additional information about
        the error.
        Nztext must be string or None)rS   r,   r   r%   r   r*   r   r?   rO   rn   r}   )r+   r   r}   rW   r   r   r,   Z  s
    zEDEOption.__init__rZ   c                 C   s*   d| j  }| jd k	r&|d| j 7 }|S )NzEDE z: r   )r+   outputr   r   r   rK   i  s    
zEDEOption.to_textr-   c                 C   sB   t d| j}| jd k	r(|| jd7 }|r:|| d S |S d S )Nz!Hutf8)ru   rv   r   r}   encoderY   r   r   r   r   r3   o  s    

zEDEOption.to_wirer4   r5   c                 C   sL   t | }| }|r>|d dkr2|d d }|d}nd }| ||S )Nr:   r   r   )r   r*   Z
get_uint16r[   decode)r   r)   r6   r   r}   Zbtextr   r   r   r8   z  s    zEDEOption.from_wire_parser)N)N)r   r   r   rN   r   r   rO   r   r,   rK   r   rP   r3   r&   r   r'   r8   r\   r   r   rW   r   r   W  s   "
 r   _type_to_class)r)   r/   c                 C   s   t | }|dkrt}|S )zReturn the class for the specified option type.

    The GenericOption class is used if a more specific class is not
    known.
    N)r   getrQ   )r)   r   r   r   r   get_option_class  s    
r   r4   r5   c                 C   s   t | } t| }|| |S )a  Build an EDNS option object from wire format.

    *otype*, an ``int``, is the option type.

    *parser*, a ``dns.wire.Parser``, the parser, which should be
    restricted to the option length.

    Returns an instance of a subclass of ``dns.edns.Option``.
    )r   r*   r   r8   )r)   r6   r   r   r   r   option_from_wire_parser  s    
r   )r)   r<   currentolenr/   c              
   C   s:   t j||}|| t| |W  5 Q R  S Q R X dS )ar  Build an EDNS option object from wire format.

    *otype*, an ``int``, is the option type.

    *wire*, a ``bytes``, is the wire-format message.

    *current*, an ``int``, is the offset in *wire* of the beginning
    of the rdata.

    *olen*, an ``int``, is the length of the wire-format option data

    Returns an instance of a subclass of ``dns.edns.Option``.
    N)rT   r<   ParserZrestrict_tor   )r)   r<   r   r   r6   r   r   r   option_from_wire  s    r   )implementationr)   r/   c                 C   s   | t |< dS )zRegister the implementation of an option type.

    *implementation*, a ``class``, is a subclass of ``dns.edns.Option``.

    *otype*, an ``int``, is the option type.
    N)r   )r   r)   r   r   r   register_type  s    r   )*rN   rr   ri   ru   typingr   r   r   r   Zdns.enumrT   Zdns.inetZ	dns.rdataZdns.wireenumIntEnumr   r'   rQ   r]   r   r   r   r%   r   __annotations__r   rO   r   rP   rq   r   r   r   r   r   r   r    r!   r"   r#   r$   r   r   r   r   <module>   sV   S  5  
 
   