a
    sd_&                     @   s   d Z ddl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	e
 e	j G dd dZG dd deZG d	d
 d
eZe	jeiZdd Zdd Zdd ZdS )zEDNS Options    Nc                   @   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edd ZdS )
OptionType               	   
            c                 C   s   dS )Ni   )clsr   r   */usr/lib/python3/dist-packages/dns/edns.py_maximum1   s    zOptionType._maximumN)__name__
__module____qualname__ZNSIDZDAUZDHUZN3UECSZEXPIREZCOOKIEZ	KEEPALIVEZPADDINGZCHAINclassmethodr   r   r   r   r   r      s   r   c                   @   sn   e Zd ZdZdd ZdddZe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.c                 C   s
   || _ dS )zPInitialize an option.

        *otype*, an ``int``, is the option type.
        Notype)selfr   r   r   r   __init__;   s    zOption.__init__Nc                 C   s   t dS )zUConvert an option to wire format.

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

        NNotImplementedErrorr   filer   r   r   to_wireB   s    zOption.to_wirec                 C   s   t dS )zBuild an EDNS option object from wire format.

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

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

        Returns a ``dns.edns.Option``.
        Nr   r   r   parserr   r   r   from_wire_parserJ   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      )r   )r   otherwireZowirer   r   r   _cmpW   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__d   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__k   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__r   s
    

zOption.__lt__c                 C   s(   t |tr| j|jkrtS | |dkS r-   r.   r*   r   r   r   __le__x   s
    

zOption.__le__c                 C   s(   t |tr| j|jkrtS | |dkS r-   r.   r*   r   r   r   __ge__~   s
    

zOption.__ge__c                 C   s(   t |tr| j|jkrtS | |dkS r-   r.   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   r   r"   r'   r+   r,   r0   r1   r2   r3   r7   r   r   r   r   r   7   s   

r   c                       s>   e Zd ZdZ fddZdddZdd Zed	d
 Z  Z	S )GenericOptionzwGeneric Option Class

    This class is used for EDNS option types for which we have no better
    implementation.
    c                    s   t  | || _d S r4   )superr   data)r   r   r;   	__class__r   r   r      s    zGenericOption.__init__Nc                 C   s   |r| | j n| jS d S r4   )writer;   r   r   r   r   r      s    zGenericOption.to_wirec                 C   s
   d| j  S )Nz
Generic %dr   r6   r   r   r   r5      s    zGenericOption.to_textc                 C   s   | ||  S r4   )Zget_remainingr    r   r   r   r"      s    zGenericOption.from_wire_parser)N)
r   r   r   r8   r   r   r5   r   r"   __classcell__r   r   r<   r   r9      s   
r9   c                       sL   e Zd ZdZd fdd	Zdd Zedd	 Zdd
dZe	dd Z
  ZS )	ECSOptionz!EDNS Client Subnet (ECS, RFC7871)Nr   c           	         s   t  tj tj|}|tjkr8d| _	|du r^d}n&|tj
krVd| _	|du r^d}ntd|| _|| _|| _tj||}tt|d }|d| | _|d }|d	krt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#      zBad ip family       @r   r   Br$      )r:   r   r   r   dnsZinetZaf_for_addresssocketZAF_INET6familyZAF_INET
ValueErroraddresssrclenscopelenZ	inet_ptonintmathceiladdrdatastructpackord)	r   rK   rL   rM   ZafrQ   nbytesZnbitsZlastr<   r   r   r      s.    

zECSOption.__init__c                 C   s   d | j| j| jS )NzECS {}/{} scope/{})formatrK   rL   rM   r6   r   r   r   r5      s    zECSOption.to_textc                 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y   tdd	| Y n0 zt|}W n& ty   td
d| Y n0 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   Nr#   r   rA   zcould not parse ECS from "{}"/zinvalid scope z"{}": scope must be an integerzinvalid srclen z"{}": srclen must be an integer)splitlenrJ   rV   countrN   r@   )textZoptional_prefixtokensZecs_textZ	n_slashesrK   rL   scoper   r   r   	from_text   s<    


zECSOption.from_textc                 C   s4   t d| j| j| j| j }|r,|| n|S d S )N!HBB)rR   rS   rI   rL   rM   rQ   r>   )r   r   valuer   r   r   r     s    zECSOption.to_wirec           
      C   s   | d\}}}tt|d }||}|dkrRd| }tj|d|  }	n.|dkrxd| }tj|d|  }	nt	d| |	||S )	Nr_   rD   r#          rA      zunsupported family)
Z
get_structrN   rO   rP   Z	get_bytesrG   Zipv4Z	inet_ntoaZipv6rJ   )
r   r   r!   rI   srcr]   ZaddrlenprefixZpadZaddrr   r   r   r"     s    
zECSOption.from_wire_parser)Nr   )N)r   r   r   r8   r   r5   staticmethodr^   r   r   r"   r?   r   r   r<   r   r@      s   )
6
r@   c                 C   s   t | }|du 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)_type_to_classgetr9   )r   r   r   r   r   get_option_class,  s    
ri   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``.
    )ri   r   Zmaker"   )r   r!   r   r   r   r   option_from_wire_parser9  s    

rj   c                 C   sF   t j||}|| t| |W  d   S 1 s80    Y  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)rG   r&   ZParserZrestrict_torj   )r   r&   ZcurrentZolenr!   r   r   r   option_from_wireH  s    rk   )r8   rO   rH   rR   Zdns.enumrG   Zdns.inetenumIntEnumr   globalsupdate__members__r   r9   r@   r   rg   ri   rj   rk   r   r   r   r   <module>   s    W 