a
    kÄ#d,5  ã                   @   sâ   d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
mZmZmZmZmZmZmZmZmZmZ ddlmZmZ ddlmZmZ dd	lmZmZ dd
lmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' G dd„ dƒZ(e(ƒ e_)dS )z2
Routing and network interface handling for IPv6.
é    )Úabsolute_importN)Úconf)Úresolve_ifaceÚNetworkInterface)Úin6_ptopÚin6_cidr2maskÚin6_andÚin6_islladdrÚin6_ismlladdrÚin6_isincludedÚin6_isgladdrÚin6_isaddr6to4Úin6_ismaddrÚconstruct_source_candidate_setÚ"get_source_addr_from_candidate_set)Úread_routes6Úin6_getifaddr)Ú	inet_ptonÚ	inet_ntop)ÚwarningÚlog_loading)Úpretty_list)ÚAnyÚDictÚListÚOptionalÚSetÚTupleÚUnionc                   @   s‚   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zddd„Zdd„ Z	dd„ Z
ddd„Zdd„ Zdd„ Zdd„ Zddejfdd„ZdS )ÚRoute6c                 C   s   |   ¡  |  ¡  d S ©N)ÚresyncÚinvalidate_cache©Úself© r%   úC/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/route6.pyÚ__init__*   s    zRoute6.__init__c                 C   s
   i | _ d S r    )Úcacher#   r%   r%   r&   r"   /   s    zRoute6.invalidate_cachec                 C   s   |   ¡  tƒ | _g | _d S r    )r"   ÚsetÚipv6_ifacesÚroutesr#   r%   r%   r&   Úflush3   s    zRoute6.flushc                 C   sL   |   ¡  tƒ | _tƒ | _| jD ]}| j |d ¡ q| jg krHt d¡ d S )Né   zNo IPv6 support in kernel)r"   r   r+   r)   r*   Úaddr   Úinfo)r$   Úrouter%   r%   r&   r!   9   s    

zRoute6.resyncc           	   	   C   sV   g }| j D ]:\}}}}}}t|ƒj}| d||f |||t|ƒf¡ q
t|dgdd�S )Nz%s/%i)ZDestinationzNext HopZIfacezSrc candidatesZMetricé   )ZsortBy)r+   r   ÚdescriptionÚappendÚstrr   )	r$   ZrtlstÚnetZmskÚgwÚifaceÚcsetÚmetricZif_reprr%   r%   r&   Ú__repr__E   s    
üþzRoute6.__repr__Nc                    s�   |  d¡dg dd… \}}t|ƒ}|du r0d}ˆ du rP|  |¡\‰ }}|g}	n$tƒ }
‡ fdd„|
D ƒ}t|||ƒ}	| j ˆ ¡ |||ˆ |	dfS )	z?Internal function : create a route for 'dst' via 'gw'.
        ú/Ú128Né   ú::c                 3   s   | ]}|d  ˆ kr|V  qdS )r=   Nr%   ©Ú.0Úx©Údevr%   r&   Ú	<genexpr>j   ó    z$Route6.make_route.<locals>.<genexpr>r1   )ÚsplitÚintr0   r   r   r*   r.   )r$   Údstr6   rC   ÚprefixÚplen_bÚplenZifaddr_uniqrA   ZifaddrZlifaddrZdevaddrsr%   rB   r&   Ú
make_routeX   s    zRoute6.make_routec                 O   s$   |   ¡  | j | j|i |¤Ž¡ dS )zÇEx:
        add(dst="2001:db8:cafe:f000::/56")
        add(dst="2001:db8:cafe:f000::/56", gw="2001:db8:cafe::1")
        add(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1", dev="eth0")
        N)r"   r+   r3   rL   )r$   ÚargsZkargsr%   r%   r&   r.   q   s    z
Route6.addc                    sB   t ‡ fdd„tjjD ƒƒs>z| j ˆ ¡ W n ty<   Y n0 dS )zk
        Remove the network interface 'iface' from the list of interfaces
        supporting IPv6.
        c                 3   s   | ]}|d  ˆ kV  qdS )r-   Nr%   )r@   Úr©r7   r%   r&   rD   ‚   rE   z+Route6.remove_ipv6_iface.<locals>.<genexpr>N)Úallr   Úroute6r+   r*   ÚremoveÚKeyError)r$   r7   r%   rO   r&   Úremove_ipv6_iface{   s
    zRoute6.remove_ipv6_ifacec                    sÈ   ˆ d }|  d¡dd… \‰ }tˆ ƒ‰ t|ƒ‰‡ ‡fdd„| jD ƒ}ˆrdtˆƒ‰‡fdd„| jD ƒ}t|ƒdkrztd	ƒ nJt|ƒd
kr�tdƒ n4| j |d ¡}|  ¡  |  | j| d ¡ | j|= dS )z• Ex:
        delt(dst="::/0")
        delt(dst="2001:db8:cafe:f000::/56")
        delt(dst="2001:db8:cafe:f000::/56", gw="2001:db8:deca::1")
        z/128r;   Nr=   c                    s,   g | ]$}t |d  ƒˆ kr|d ˆkr|‘qS ©r   r1   ©r   r?   )rH   rK   r%   r&   Ú
<listcomp>“   s   ÿzRoute6.delt.<locals>.<listcomp>c                    s    g | ]}t |d  ƒˆ kr|‘qS )r=   rV   r?   )r6   r%   r&   rW   —   rE   r   zNo matching route foundr1   z$Found more than one match. Aborting.r-   )	rF   r   rG   r+   Úlenr   Úindexr"   rT   )r$   rH   r6   ÚtmprJ   Zto_delÚir%   )rH   r6   rK   r&   Údeltˆ   s     

zRoute6.deltc                 C   sÖ   |  d¡dg d d… \}}t|ƒ}ttj|ƒ}t|ƒ}ttjt||ƒƒ}t| j	ƒD ]h\}	}
|
\}}}}}}||krvqT| j
 |¡ |dkr¤|||||g|f| j	|	< qT|||||g|f| j	|	< qT|  ¡  tjj ¡  d S )Nr;   r<   r=   r>   )rF   rG   r   ÚsocketÚAF_INET6r   r   r   Ú	enumerater+   r*   r.   r"   r   ZnetcacheZin6_neighborr,   )r$   ÚiffÚaddrZthe_addrZ
the_plen_bZthe_plenÚnaddrÚnmaskZthe_netr[   r0   r5   rK   r6   r7   Ú_r9   r%   r%   r&   Úifchange¢   s    zRoute6.ifchangec                 C   sB   g }| j D ]}|d |kr
| |¡ q
|  ¡  || _ |  |¡ dS )z6 removes all route entries that uses 'iff' interface. r-   N)r+   r3   r"   rT   )r$   r`   Z
new_routesÚrtr%   r%   r&   Úifdel¹   s    
zRoute6.ifdelc                 C   s„   |  d¡dg dd… \}}t|ƒ}t|ƒ}ttj|ƒ}t|ƒ}ttjt||ƒƒ}|  	¡  | j
 ||d||gdf¡ | j |¡ dS )aÝ  
        Add an interface 'iff' with provided address into routing table.

        Ex: ifadd('eth0', '2001:bd8:cafe:1::1/64') will add following entry into  # noqa: E501
            Scapy6 internal routing table:

            Destination           Next Hop  iface  Def src @           Metric
            2001:bd8:cafe:1::/64  ::        eth0   2001:bd8:cafe:1::1  1

            prefix length value can be omitted. In that case, a value of 128
            will be used.
        r;   r<   Nr=   r>   r1   )rF   r   rG   r   r]   r^   r   r   r   r"   r+   r3   r*   r.   )r$   r`   ra   rJ   rK   rb   rc   rI   r%   r%   r&   ÚifaddÄ   s    zRoute6.ifaddÚ c              	      s   |pd}|  d¡d }|}| dd¡}| d¡}|dkrv||d… d  d¡}|d|… ||| d…  }| d¡}q0zttj|ƒ W n0 tjy¶   t |dtj¡d d	 d }Y n0 |du �rZt|ƒsÔt	|ƒ�rZt
j}|| jv�rZ| j�rZd
d„ | jD ƒ}dd„ |D ƒ}dd„ |D ƒ}	|�r.|d d }n|	�rB|	d d }nt
j}tdt
j|f ƒ |}
|du�rt|d | }
|
| jv �rŠ| j|
 S g }| jD ]ˆ\}}}}}}|du�r¼||k�r¼�q”t|||ƒ�râ| |||||ff¡ n8t	|ƒ�r”t|ƒ�r”t|d ƒ�r”| |||||ff¡ �q”|�sV|dk�r:t
jddfS |�rJtd|ƒ t
jddfS |jdd„ d� |d d |d d f‰ ‡ fdd„|D ƒ}g }|D ]L}|d }t||d ƒ}|du�r˜| |d |d |d ||d ff¡ �q˜|g k�rtd|ƒ t
jddfS t|ƒdk�rhg }t|ƒ�r<t|ƒ�r<dd„ |D ƒ}n"t|ƒ�sPt|ƒ�r^dd„ |D ƒ}|�rh|}|}
|du�r‚|d | }
|d d | j|
< |d d S )a:  
        Provide best route to IPv6 destination address, based on Scapy
        internal routing table content.

        When a set of address is passed (e.g. ``2001:db8:cafe:*::1-5``) an
        address of the set is used. Be aware of that behavior when using
        wildcards in upper parts of addresses !

        If 'dst' parameter is a FQDN, name resolution is performed and result
        is used.

        if optional 'dev' parameter is provided a specific interface, filtering
        is performed to limit search to route associated to that interface.
        z::/0r;   r   Ú*Ú0ú-Nú:éÿÿÿÿc                 S   s   g | ]}|d  t jkr|‘qS )r-   ©r   r7   ©r@   r0   r%   r%   r&   rW     s   ÿz Route6.route.<locals>.<listcomp>c                 S   s$   g | ]}|d  |d fdkr|‘qS )r   r1   )r>   r   r%   rp   r%   r%   r&   rW     s   ÿc                 S   s$   g | ]}|d  |d fdkr|‘qS )r   r1   )zfe80::é@   r%   rp   r%   r%   r&   rW   
  s   ÿr-   zRThe conf.iface interface (%s) does not support IPv6! Using %s instead for routing!z%%z::1r>   z:No route found for IPv6 destination %s (no default route?)c                 S   s   | d  | d fS )Nr   r1   r%   )rA   r%   r%   r&   Ú<lambda>9  rE   zRoute6.route.<locals>.<lambda>)Úkeyr1   c                    s$   g | ]}|d  |d fˆ kr|‘qS rU   r%   r?   ©Z	best_plenr%   r&   rW   <  rE   r=   zHFound a route for IPv6 destination '%s', but no possible source address.c                 S   s    g | ]}t |d  d ƒr|‘qS )r=   r1   )r   r?   r%   r%   r&   rW   W  rE   c                 S   s"   g | ]}|d  d t jkr|‘qS )r=   r   ro   r?   r%   r%   r&   rW   Z  rE   )rF   ÚreplaceÚfindr   r]   r^   ÚerrorÚgetaddrinfor	   r
   r   r7   r*   r+   Zloopback_namer   r(   r   r3   Úsortr   rX   r   r   r   )r$   rH   rC   ÚverboseZsavedstÚidxÚmZ
tmp_routesZdefault_routesZ	ll_routesÚkÚpathsÚprK   r6   r7   r8   ÚmeÚresÚpathZtmp_cZsrcaddrrZ   r%   rt   r&   r0   Ü   s’    
"ÿ

"
ÿ
*


zRoute6.route)NN)N)Ú__name__Ú
__module__Ú__qualname__r'   r"   r,   r!   r:   rL   r.   rT   r\   re   rg   rh   r   Úverbr0   r%   r%   r%   r&   r   (   s     ý


r   )*Ú__doc__Ú
__future__r   r]   Zscapy.configr   Zscapy.interfacesr   r   Zscapy.utils6r   r   r   r	   r
   r   r   r   r   r   r   Z
scapy.archr   r   Zscapy.pton_ntopr   r   Zscapy.errorr   r   Zscapy.utilsr   Zscapy.compatr   r   r   r   r   r   r   r   rQ   r%   r%   r%   r&   Ú<module>   s   4$  B