a
    kÄ#d*'  ã                   @   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mZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZmZ dd	l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 G dd„ deƒZG dd„ deƒZ dd„ Z!dd„ Z"dS )a’  
Native Microsoft Windows sockets (L3 only)

## Notice: ICMP packets

DISCLAIMER: Please use Npcap/Winpcap to send/receive ICMP. It is going to work.
Below is some additional information, mainly implemented in a testing purpose.

When in native mode, everything goes through the Windows kernel.
This firstly requires that the Firewall is open. Be sure it allows ICMPv4/6
packets in and out.
Windows may drop packets that it finds wrong. for instance, answers to
ICMP packets with id=0 or seq=0 may be dropped. It means that sent packets
should (most of the time) be perfectly built.

A perfectly built ICMP req packet on Windows means that its id is 1, its
checksum (IP and ICMP) are correctly built, but also that its seq number is
in the "allowed range".
    In fact, every time an ICMP packet is sent on Windows, a global sequence
number is increased, which is only reset at boot time. The seq number of the
received ICMP packet must be in the range [current, current + 3] to be valid,
and received by the socket. The current number is quite hard to get, thus we
provide in this module the get_actual_icmp_seq() function.

Example:
    >>> conf.use_pcap = False
    >>> a = conf.L3socket()
    # This will (most likely) work:
    >>> current = get_current_icmp_seq()
    >>> a.sr(IP(dst="www.google.com", ttl=128)/ICMP(id=1, seq=current))
    # This won't:
    >>> a.sr(IP(dst="www.google.com", ttl=128)/ICMP())

PS: on computers where the firewall isn't open, Windows temporarily opens it
when using the `ping` util from cmd.exe. One can first call a ping on cmd,
then do custom calls through the socket using get_current_icmp_seq(). See
the tests (windows.uts) for an example.
é    N©Úselect_objects©ÚGetIcmpStatistics)Úraw)Úconf)ÚMTU)ÚScapy_ExceptionÚwarning)ÚPacket)Úresolve_ifaceÚ_GlobInterfaceType)ÚSuperSocket)ÚAnyÚListÚOptionalÚTupleÚTypec                       st   e Zd ZdZdZdZg d¢Zdejdddfdd„Z	d	d
„ Z
efdd„Zefdd„Z‡ fdd„Zeddd„ƒZ‡  ZS )ÚL3WinSocketz0a native Layer 3 (IPv4) raw socket under WindowsT)ÚpromiscÚclsÚipv6ÚprotoNé€   Fc              
   K   sÆ  ddl m} ddlm} |D ]}	td|	 ƒ q|r:t|ƒp>tj| _|rLtj	ntj
}
|| _|rŠddlm} |tjƒptd| _|tjkrŠtj| _|| _|r˜|n|| _|d u r¬tj}|| _z,t |
tj| j¡| _t |
tjtj¡| _W n< t�y } z"|jdk�rtdƒ‚‚ W Y d }~n
d }~0 0 | j tjtjd	¡ | j tjtjd	¡ | j tjtjd
¡ | j tjtjd
¡ | j tjtj d	¡ | j tjtj d	¡ | j tjtj!|¡ | j tjtj!|¡ | jj"�rÎ| jj"nt #¡ }| j $|df¡ | j %d¡ |�rBz,| j tj&tj'd	¡ | j tj&tj(d	¡ W n ttj)f�y>   Y n0 nhz| j tjtj*d	¡ W n ttj)f�yt   Y n0 z| j tjtj+d	¡ W n ttj)f�y¨   Y n0 |�rÂ| j ,tj-tj.¡ d S )Nr   ©ÚIP©ÚIPv6zDropping unsupported option: %s)Úget_if_addr6z::1i'  zfWindows native L3 Raw sockets are only usable as administrator ! Install Winpcap/Npcap to workaround !é   i   @F)/Úscapy.layers.inetr   Úscapy.layers.inet6r   r
   r   r   ÚifaceÚsocketÚAF_INET6ÚAF_INETr   Z
scapy.archr   Úhost_ip6Ú
IPPROTO_IPÚIPPROTO_UDPr   r   Zsniff_promiscr   ÚSOCK_RAWÚinsÚIPPROTO_RAWÚoutsÚOSErrorÚerrnoÚ
setsockoptÚ
SOL_SOCKETÚSO_REUSEADDRÚ	SO_RCVBUFÚ	SO_SNDBUFÚ
IP_HDRINCLÚIP_TTLÚipÚgethostnameÚbindÚsetblockingÚIPPROTO_IPV6ÚIPV6_RECVTCLASSÚIPV6_HOPLIMITÚerrorZIP_RECVDSTADDRZ
IP_RECVTTLÚioctlÚ
SIO_RCVALLZ	RCVALL_ON)Úselfr"   r   Úttlr   r   Úkwargsr   r   ÚkwargÚafr   ÚeÚhost© rG   úP/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/arch/windows/native.pyÚ__init__N   s†    	
þþ

ÿ
ÿ
ÿýzL3WinSocket.__init__c                 C   sJ   t |ƒ}| j|vrtdƒ‚| js(tdƒ‚t|| j jƒ}| j ||df¡S )NzNL3WinSocket can only send IP/IPv6 packets ! Install Npcap/Winpcap to send morezSocket not createdr   )r   r   r	   r,   ÚstrÚdstÚsendto)r@   ÚxÚdataZdst_iprG   rG   rH   Úsend§   s    
zL3WinSocket.sendc                 C   s$   z
|   ¡ W S  ty   Y d S 0 d S ©N)ÚrecvÚIOError)r@   rM   rG   rG   rH   Únonblock_recv²   s    
zL3WinSocket.nonblock_recvc           
      C   s˜   z| j  |¡\}}W n tjy*   Y dS 0 ddlm} ddlm} | jr†|\}}}}t	||| j
|| jt|ƒd�ƒ}	||	| t ¡ fS ||t ¡ fS d S )N)NNNr   r   r   )ÚsrcrK   ÚflZnhÚplen)r*   ÚrecvfromÚioÚBlockingIOErrorr    r   r!   r   r   r   r&   r   ÚlenÚtime)
r@   rM   rN   Úaddressr   r   rF   Ú_ÚflowinfoÚheaderrG   rG   rH   Úrecv_rawÂ   s     üzL3WinSocket.recv_rawc                    s0   | j s| jr| j tjtj¡ tt| ƒ 	¡  d S rP   )
Úclosedr   r*   r>   r#   r?   Z
RCVALL_OFFÚsuperr   Úclose)r@   ©Ú	__class__rG   rH   rc   ×   s    zL3WinSocket.closec                 C   s
   t | |ƒS rP   r   )ÚsocketsZremainrG   rG   rH   ÚselectÝ   s    zL3WinSocket.select)N)Ú__name__Ú
__module__Ú__qualname__ÚdescZnonblocking_socketZ__selectable_force_select__Ú	__slots__r#   r'   rI   rO   r   rS   r`   rc   Ústaticmethodrg   Ú__classcell__rG   rG   rd   rH   r   H   s    û
Yr   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚL3WinSocket6z0a native Layer 3 (IPv6) raw socket under Windowsc                    s   t t| ƒjf ddi|¤Ž d S )Nr   T)rb   ro   rI   )r@   rB   rd   rG   rH   rI   æ   s    zL3WinSocket6.__init__)rh   ri   rj   rk   rI   rn   rG   rG   rd   rH   ro   ã   s   ro   c                 C   sJ   t tjdƒ�*}tjd|  d||d� ¡ W  d  ƒ S 1 s<0    Y  dS )zyTemporarily open the ICMP firewall. Tricks Windows into allowing
    ICMP packets for a short period of time (~ 1 minute)Úwbzping -4 -w 1 -n 1 %sT)ÚshellÚstdoutÚstderrN)ÚopenÚosÚdevnullÚ
subprocessÚPopenÚwait)rF   ÚDEVNULLrG   rG   rH   Úopen_icmp_firewallë   s    
ýr{   c                   C   s   t ƒ d d d S )zbSee help(scapy.arch.windows.native) for more information.
    Returns the current ICMP seq number.ÚstatsZicmpOutStatsZdwEchosr   rG   rG   rG   rH   Úget_current_icmp_seq÷   s    r}   )#Ú__doc__rX   ru   r#   rw   r[   Zscapy.automatonr   Zscapy.arch.windows.structuresr   Zscapy.compatr   Zscapy.configr   Z
scapy.datar   Zscapy.errorr	   r
   Zscapy.packetr   Zscapy.interfacesr   r   Zscapy.supersocketr   r   r   r   r   r   r   ro   r{   r}   rG   rG   rG   rH   Ú<module>   s(   & 