
    hm0                         d 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          Z& e&            e_'        dS )z2
Routing and network interface handling for IPv6.
    N)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                   v    e Zd Zd Zd Zd Zd Zd Z	 	 ddZd Z	d	 Z
dd
Zd Zd Zd Zddej        fdZdS )Route6c                     g | _         t                      | _        |                                  t          j        r|                                  d S d S N)routessetipv6_ifacesinvalidate_cacher   route6_autoloadresyncselfs    P/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/scapy/route6.py__init__zRoute6.__init__)   sM    55 	KKMMMMM	 	    c                     i | _         d S r"   )cacher)   s    r+   r&   zRoute6.invalidate_cache1   s    


r-   c                     |                                   | j                                         | j                                         d S r"   )r&   r#   clearr%   r)   s    r+   flushzRoute6.flush5   sC         r-   c                    |                                   t                      | _        t                      | _        | j        D ]"}| j                            |d                    #| j        g k    rt          j        d           d S d S )N   zNo IPv6 support in kernel)r&   r   r#   r$   r%   addr   info)r*   routes     r+   r(   zRoute6.resync;   s     	"nn55[ 	+ 	+E  q****;"899999 r-   c           
          g }| j         D ]I\  }}}}}}t          |          j        }|                    d||fz  |||t	          |          f           Jt          |dgd          S )Nz%s/%i)DestinationzNext HopIfacezSrc candidatesMetric   )sortBy)r#   r   descriptionappendstrr   )	r*   rtlstnetmskgwifacecsetmetricif_reprs	            r+   __repr__zRoute6.__repr__G   s    15 	( 	(-Cb%v#E**6GLL'S#J.!f++	' ( ( ( ( 5\]"#% % % 	%r-   Nc                 N   |                     d          dgz   dd         \  }}t          |          }|d}|                     |          \  }}|g}	n-t                      }
fd|
D             }t	          |||          }	| j                                       ||||	dfS )z?Internal function : create a route for 'dst' via 'gw'.
        /128N   ::c              3   4   K   | ]}|d          k    |V  dS )rM   N ).0xdevs     r+   	<genexpr>z$Route6.make_route.<locals>.<genexpr>l   s+      ::aadckkkkkk::r-   r<   )splitintr7   r   r   r%   r5   )r*   dstrD   rS   prefixplen_bplenifaddr_uniqrR   ifaddrlifaddrdevaddrss      `        r+   
make_routezRoute6.make_routeZ   s     ))C..E72BQB76{{:B;"&**R..Ca!]FF#ooG::::7:::H3FD(KKFS!!!b#vq11r-   c                 x    |                                   | j                             | j        |i |           dS )zEx:
        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#   r?   r_   )r*   argskargss      r+   r5   z
Route6.adds   sC     	?4?D:E::;;;;;r-   c                     t          fdt          j        j        D                       s.	 | j                                       dS # t          $ r Y dS w xY wdS )zk
        Remove the network interface 'iface' from the list of interfaces
        supporting IPv6.
        c              3   0   K   | ]}|d          k    V  dS )r4   NrP   )rQ   rrE   s     r+   rT   z+Route6.remove_ipv6_iface.<locals>.<genexpr>   s+      ==Q1Q45=======r-   N)allr   route6r#   r%   removeKeyError)r*   rE   s    `r+   remove_ipv6_ifacezRoute6.remove_ipv6_iface}   s}     ====$+*<===== 	 ''.....   	 	s   A	 	
AAc                 V   dz   }|                     d          dd         \  }t                    t          |          fd| j        D             }r"t                    fd| j        D             }t	          |          dk    rt          d           dS t	          |          d	k    rt          d
           dS | 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/128rK   NrM   c                 ^    g | ])}t          |d                    k    |d         k    '|*S r   r<   r   )rQ   rR   rW   rZ   s     r+   
<listcomp>zRoute6.delt.<locals>.<listcomp>   sA     = = =ad^^s**qtt|| /;||r-   c                 F    g | ]}t          |d                    k    |S )rM   rn   )rQ   rR   rD   s     r+   ro   zRoute6.delt.<locals>.<listcomp>   s-    EEEA1"0D0Da0D0D0Dr-   r   zNo matching route foundr<   z$Found more than one match. Aborting.r4   )	rU   r   rV   r#   lenr   indexr&   rj   )r*   rW   rD   tmprY   to_delirZ   s    ``    @r+   deltzRoute6.delt   s@    FliinnRaR(Vsmm6{{= = = = =T[ = = = 	F"BEEEEEEEFv;;!-.....[[1__:;;;;;!!&),,A!!###""4;q>!#4555Ar-   c                 V   |                     d          dgz   d d         \  }}t          |          }t          t          j        |          }t          |          }t          t          j        t          ||                    }t          | j	                  D ]X\  }	}
|
\  }}}}}}||k    r| j
                            |           |dk    r|||||g|f| j	        |	<   G|||||g|f| j	        |	<   Y|                                  t          j        j                                         d S )NrK   rL   rM   rN   )rU   rV   r   socketAF_INET6r   r   r   	enumerater#   r%   r5   r&   r   netcachein6_neighborr2   )r*   iffaddrthe_addr
the_plen_bthe_plennaddrnmaskthe_netru   r7   rB   rZ   rD   rE   _rG   s                    r+   ifchangezRoute6.ifchange   s.    $

35' 92A2>*z??&/844h''FOWUE-B-BCC!$+.. 
	L 
	LHAu.3+Cr5!V||  '''Tzz")8R
F!SA"%tR
F!KA"((*****r-   c                     g }| j         D ]#}|d         |k    r|                    |           $|                                  || _         |                     |           dS )z6 removes all route entries that uses 'iff' interface. r4   N)r#   r?   r&   rj   )r*   r}   
new_routesrts       r+   ifdelzRoute6.ifdel   so     
+ 	& 	&B!u||!!"%%% s#####r-   c                    |                     d          dgz   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.
        rK   rL   NrM   rN   r<   )rU   r   rV   r   rx   ry   r   r   r   r&   r#   r?   r%   r5   )r*   r}   r~   rY   rZ   r   r   rX   s           r+   ifaddzRoute6.ifadd   s     

35'12A26f~~6{{&/400d##6?GE5,A,ABBFD$dVQ?@@@S!!!!!r-    c           	         |pd}|                     d          d         }|}|                    dd          }|                    d          }|dk    rS||d         dz                       d          }|d|         |||z   d         z   }|                    d          }|dk    S	 t          t          j        |           nG# t          j        $ r5 t	          j        |dt          j                  d         d	         d         }Y nw xY w|}||d
z   |z   }|| j        v r| j        |         S g }| j	        D ]\  }	}
}}}}|||k    rt          ||	|
          r|                    |
||||ff           ?t          |          r?t          |	          r0t          |d                   r|                    |
||||ff           |s8|dk    rt          j        ddfS |rt!          d|           |pt          j        ddfS |                    d            |d         d         |d         d         ffd|D             }g }|D ]U}|d         }t%          ||d                   }|3|                    |d         |d         |d         ||d         ff           V|g k    rt!          d|           t          j        ddfS t'          |          dk    r[g }t)          |          rt+          |          rd |D             }n*t-          |          st          |          rd |D             }|r|}|}||d
z   |z   }|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::/0rK   r   *0-N:z%%z::1rN   z:No route found for IPv6 destination %s (no default route?)c                 $    | d          | d         fS )Nr   r<   rP   )rR   s    r+   <lambda>zRoute6.route.<locals>.<lambda>  s    1Q4%1 r-   )keyr<   c                 <    g | ]}|d          |d         fk    |S rm   rP   )rQ   rR   	best_plens     r+   ro   z Route6.route.<locals>.<listcomp>!  s/    ???qadAaD\Y%>%>%>%>%>r-   rM   zHFound a route for IPv6 destination '%s', but no possible source address.c                 H    g | ]}t          |d          d                   | S )rM   r<   )r   rQ   rR   s     r+   ro   z Route6.route.<locals>.<listcomp><  s-    AAAQ!Q)@)@AqAAAr-   c                 J    g | ] }|d          d         t           j        k    |!S )rM   r   )r   rE   r   s     r+   ro   z Route6.route.<locals>.<listcomp>?  s,    ???Q1aDJ)>)>q)>)>)>r-   )rU   replacefindr   rx   ry   errorgetaddrinfor/   r#   r   r?   r
   r	   r   loopback_namer   sortr   rq   r   r   r   )r*   rW   rS   verbosesavedstidxmkpathsprZ   rD   rE   rF   merespathtmp_csrcaddrrs   r   s                       @r+   r7   zRoute6.route   s      mViinnQkk#s##hhsmmQhhSTTS&&s++Adsd)c#'((m+C((3--C Qhh
	Ofos++++| 	O 	O 	O$WdFODDQGKANCCC	O
 ?d
S A
??:a=  -1K 	< 	<(AtRb5C<<c1d++ <dBb(9:;;;;$$ <a <\$q'=R=R <dBb(9:;;; 	?e||*E488 8 2368 8 81t14>> 	

..
///1Xa[%(1+.	????E??? 	N 	NDGE8eAhGGG"

DGT!WuQx%(.KLMMM"99^`cddd&d33 s88a<<CC   @^C%8%8 @ BA#AAAS!! @\#%6%6 @??#???  ?d
S AAq	
11vays   (C ADD)NNr"   )__name__
__module____qualname__r,   r&   r2   r(   rI   r_   r5   rj   rv   r   r   r   r   verbr7   rP   r-   r+   r    r    '   s            ! ! !
: 
: 
:% % %* 2 2 2 22< < <     4+ + +.	$ 	$ 	$" " "0 di l l l l l lr-   r    )(__doc__rx   scapy.configr   scapy.interfacesr   r   scapy.utils6r   r   r   r	   r
   r   r   r   r   r   r   
scapy.archr   r   scapy.pton_ntopr   r   scapy.errorr   r   scapy.utilsr   typingr   r   r   r   r   r   r   r    rg   rP   r-   r+   <module>r      s           < < < < < < < <' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 3 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 , , , , , , , , # # # # # #                 c c c c c c c cL	 fhhr-   