o
    2c*                     @   s   d Z ddl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
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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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   >/var/www/html/gps/gps/lib/python3.10/site-packages/dns/edns.py_maximum3   s   zOptionType._maximumN)__name__
__module____qualname__NSIDDAUDHUN3UECSEXPIRECOOKIE	KEEPALIVEPADDING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   t || _dS )zPInitialize an option.

        *otype*, an ``int``, is the option type.
        N)r   makeotype)selfr!   r   r   r   __init__<   s   zOption.__init__Nc                 C      t )zUConvert an option to wire format.

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

        NotImplementedErrorr"   filer   r   r   to_wireC   s   zOption.to_wirec                 C   r$   )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``.
        r%   r   r!   parserr   r   r   from_wire_parserK   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wireowirer   r   r   _cmpX   s   zOption._cmpc                 C   s,   t |tsdS | j|jkrdS | |dkS )NFr   
isinstancer   r!   r2   r"   r/   r   r   r   __eq__e   
   
zOption.__eq__c                 C   s,   t |tsdS | j|jkrdS | |dkS )NTr   r3   r5   r   r   r   __ne__l   r7   zOption.__ne__c                 C   s(   t |tr| j|jkrtS | |dk S Nr   r4   r   r!   NotImplementedr2   r5   r   r   r   __lt__s   
   

zOption.__lt__c                 C   s(   t |tr| j|jkrtS | |dkS r9   r:   r5   r   r   r   __le__y   r=   zOption.__le__c                 C   s(   t |tr| j|jkrtS | |dkS r9   r:   r5   r   r   r   __ge__   r=   zOption.__ge__c                 C   s(   t |tr| j|jkrtS | |dkS r9   r:   r5   r   r   r   __gt__   r=   zOption.__gt__c                 C   s   |   S N)to_textr"   r   r   r   __str__   s   zOption.__str__rA   )r   r   r   __doc__r#   r)   r   r,   r2   r6   r8   r<   r>   r?   r@   rD   r   r   r   r   r   8   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  | tjj|d| _d S )NT)superr#   dnsrdataRdata	_as_bytesdata)r"   r!   rL   	__class__r   r   r#      s   zGenericOption.__init__Nc                 C   s   |r
| | j d S | jS rA   )writerL   r'   r   r   r   r)      s   zGenericOption.to_wirec                 C   s
   d| j  S )Nz
Generic %d)r!   rC   r   r   r   rB      s   
zGenericOption.to_textc                 C   s   | ||  S rA   )get_remainingr*   r   r   r   r,      s   zGenericOption.from_wire_parserrA   )
r   r   r   rE   r#   r)   rB   r   r,   __classcell__r   r   rM   r   rF      s    
rF   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           	         sT  t  tj tj|}|tjkr5d| _	|du rd}tj
j|}tj
j|dd}tj
j|dd}n,|tjkr]d| _	|du rCd}tj
j|}tj
j|dd}tj
j|d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 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      r-          zBad address family       @r   Br.      )rG   r#   r   r   rH   inetaf_for_addresssocketAF_INET6familyrI   rJ   _as_ipv6_address_as_intAF_INET_as_ipv4_address
ValueErroraddresssrclenscopelen	inet_ptonintmathceiladdrdatastructpackord)	r"   re   rf   rg   afrl   nbytesnbitslastrM   r   r   r#      s<   

zECSOption.__init__c                 C   s   d | j| j| jS )NzECS {}/{} scope/{})formatre   rf   rg   rC   r   r   r   rB      s   zECSOption.to_textc                 C   s  d}|   }d}t|dkr|d }nt|dkr+|d |kr&td| |d }ntd| |d}|dkrE| d\}}d}n|dkrR| d\}}}ntd| zt|}W n tyo   tdd	| w zt|}W n ty   td
d| w 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   rS   zcould not parse ECS from "{}"/zinvalid scope z"{}": scope must be an integerzinvalid srclen z"{}": srclen must be an integer)splitlenrd   rt   countri   rR   )textoptional_prefixtokensecs_text	n_slashesre   rf   scoper   r   r   	from_text   s@   


zECSOption.from_textc                 C   s2   t d| j| j| j| j }|r|| d S |S )N!HBB)rm   rn   r_   rf   rg   rl   rO   )r"   r(   valuer   r   r   r)     s   zECSOption.to_wirec           
      C   s   | d\}}}tt|d }||}|dkr)d| }tj|d|  }	n|dkr<d| }tj|d|  }	nt	d| |	||S )	Nr   rX   r-          rS      zunsupported family)

get_structri   rj   rk   	get_bytesrH   ipv4	inet_ntoaipv6rd   )
r   r!   r+   r_   srcr~   addrlenprefixpadaddrr   r   r   r,     s   
zECSOption.from_wire_parserr9   rA   )r   r   r   rE   r#   rB   staticmethodr   r)   r   r,   rQ   r   r   rM   r   rR      s    /

6rR   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getrF   )r!   r   r   r   r   get_option_class3  s   
r   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    r,   )r!   r+   r   r   r   r   option_from_wire_parser@  s   

r   c                 C   sF   t j||}|| t| |W  d   S 1 sw   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)rH   r0   Parserrestrict_tor   )r!   r0   currentolenr+   r   r   r   option_from_wireO  s   $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   )implementationr!   r   r   r   register_typea  s   r   )rE   rj   r]   rm   dns.enumrH   dns.inet	dns.rdataenumIntEnumr   r   rF   rR   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s8   W 
