a
    kÄ#d4  ã                   @   sÐ   d Z ddlmZ ddlZddl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 dd	lmZmZmZmZmZmZmZmZ G d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )z0
Sessions: decode flow of packets when sniffing
é    )ÚdefaultdictN)ÚrawÚorb)Úconf)Ú	NoPayloadÚPacket)Ú
PacketList)Ú	inet_pton)ÚAnyÚCallableÚDefaultDictÚDictÚListÚOptionalÚTupleÚcastc                   @   sj   e Zd ZdZddd„Zedd„ ƒZejdd„ ƒZed	d
„ ƒZejdd
„ ƒZedd„ ƒZ	dd„ Z
dd„ ZdS )ÚDefaultSessionz#Default session: no stream decodingNFc                 O   sH   || _ || _g | _d| _|| _| jrD| j | j_| j| j_d| _d | _ d S )Nr   F)Ú_DefaultSession__prnÚ_DefaultSession__storeÚlstÚ_DefaultSession__countÚ_supersessionÚprnÚstore)Úselfr   r   ZsupersessionÚargsZkarg© r   úE/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/sessions.pyÚ__init__#   s    	

zDefaultSession.__init__c                 C   s   | j S ©N)r   ©r   r   r   r   r   7   s    zDefaultSession.storec                 C   s   | j r|| j _n|| _d S r   )r   r   r   )r   Úvalr   r   r   r   <   s    
c                 C   s   | j S r   )r   r    r   r   r   r   D   s    zDefaultSession.prnc                 C   s   | j r|| j _n|| _d S r   )r   r   r   )r   Úfr   r   r   r   I   s    
c                 C   s   | j r| j jS | jS d S r   )r   Úcountr   r    r   r   r   r#   Q   s    zDefaultSession.countc                 C   s$   | j rt| j jdƒS t| jdƒS d S )NZSniffed)r   r   r   r    r   r   r   ÚtoPacketListY   s    zDefaultSession.toPacketListc                 C   s^   |sdS t |tƒstdƒ‚|  jd7  _| jr:| j |¡ | jrZ|  |¡}|durZt|ƒ dS )zpDEV: entry point. Will be called by sniff() for each
        received packet (that passes the filters).
        NzOnly provide a Packet.é   )	Ú
isinstancer   Ú	TypeErrorr   r   r   Úappendr   Úprint)r   ÚpktÚresultr   r   r   Úon_packet_received`   s    

z!DefaultSession.on_packet_received)NFN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr   Úsetterr   r#   r$   r,   r   r   r   r   r       s"      ü





r   c                       s0   e Zd ZdZdd„ Zdd„ Z‡ fdd„Z‡  ZS )Ú	IPSessionzVDefragment IP packets 'on-the-flow'.

    Usage:
    >>> sniff(session=IPSession)
    c                 O   s&   t j| g|¢R i |¤Ž ttƒ| _d S r   )r   r   r   ÚlistÚ	fragments)r   r   Úkwargsr   r   r   r   y   s    zIPSession.__init__c                 C   sâ   ddl m}m} ||vr|S || }d|_|jdks<|jjrÚ|j|j|j	|j
f}| j|  |¡ |jjsÖzb| j| d jdkrÀg }|| j| |g ƒ |d }| t|ƒ¡}|j|_|W | j|= S W | j|= n
| j|= 0 d S |S d S )Nr   )Ú_defrag_listÚIP)Úscapy.layers.inetr7   r8   Z_defrag_posÚfragÚflagsZMFÚidÚsrcÚdstÚprotor5   r(   Ú	__class__r   Útime)r   Úpacketr7   r8   ÚipZuniqÚdefragZdefragmented_packetr   r   r   Ú_ip_process_packet~   s0    ÿþzIPSession._ip_process_packetc                    s"   |sd S t t| ƒ |  |¡¡ d S r   )Úsuperr3   r,   rE   ©r   r*   ©r@   r   r   r,   š   s    zIPSession.on_packet_received)r-   r.   r/   r0   r   rE   r,   Ú__classcell__r   r   rH   r   r3   r   s   r3   c                   @   sT   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZeZ	dd„ Z
dd„ Zdd„ ZdS )ÚStringBufferaW  StringBuffer is an object used to re-order data received during
    a TCP transmission.

    Each TCP fragment contains a sequence number, which marks
    (relatively to the first sequence number) the index of the data contained
    in the fragment.

    If a TCP fragment is missed, this class will fill the missing space with
    zeros.
    c                 C   s   t dƒ| _d| _g | _d S )Nó    r   )Ú	bytearrayÚcontentÚcontent_lenÚ
incompleter    r   r   r   r   ­   s    
zStringBuffer.__init__c                 C   s„   t |ƒ}|d }|| | jkrj|  jd|| j |  7  _| j | j|f¡ || | _t | jƒ| jksjJ ‚|t| jƒ||| …< d S )Nr%   ó    )ÚlenrN   rM   rO   r(   Ú
memoryview)r   ÚdataÚseqÚdata_lenr   r   r   r(   ³   s    
zStringBuffer.appendc                 C   s   dS )NTr   r    r   r   r   ÚfullÃ   s    zStringBuffer.fullc                 C   s   |   ¡  d S r   )r   r    r   r   r   ÚclearÉ   s    zStringBuffer.clearc                 C   s
   t | jƒS r   )ÚboolrN   r    r   r   r   Ú__bool__Í   s    zStringBuffer.__bool__c                 C   s   | j S r   )rN   r    r   r   r   Ú__len__Ò   s    zStringBuffer.__len__c                 C   s
   t | jƒS r   )ÚbytesrM   r    r   r   r   Ú	__bytes__Ö   s    zStringBuffer.__bytes__c                 C   s   t t|  ¡ ƒS r   )r   Ústrr\   r    r   r   r   Ú__str__Ú   s    zStringBuffer.__str__N)r-   r.   r/   r0   r   r(   rV   rW   rY   Ú__nonzero__rZ   r\   r^   r   r   r   r   rJ   ¡   s   rJ   c                       s<   e Zd ZdZd‡ fdd„	Zddd„Zdd„ Zd	d
„ Z‡  ZS )Ú
TCPSessionaã  A Session that matches seq/ack packets together to dissect
    special protocols, such as HTTP.

    DEV: implement a class-function `tcp_reassemble` in your Packet class::

        @classmethod
        def tcp_reassemble(cls, data, metadata, session):
            # data = the reassembled data from the same request/flow
            # metadata = empty dictionary, that can be used to store data
            #            during TCP reassembly
            # session = a dictionary proper to the bidirectional TCP session,
            #           that can be used to store anything
            [...]
            # If the packet is available, return it. Otherwise don't.
            # Whenever you return a packet, the buffer will be discarded.
            return pkt
            # Otherwise, maybe store stuff in metadata, and return None,
            # as you need additional data.
            return None

    For more details and a real example, see:
    https://scapy.readthedocs.io/en/latest/usage.html#how-to-use-tcpsession-to-defragment-tcp-packets

    :param app: Whether the socket is on application layer = has no TCP
                layer. This is used for instance if you are using a native
                TCP socket. Default to False
    Fc                    sP   t t| ƒj|i |¤Ž || _|r4d| _i | _i | _ntdd„ ƒ| _tt	ƒ| _
d S )NrK   c                   S   s
   t ƒ i fS r   )rJ   r   r   r   r   Ú<lambda>  rK   z%TCPSession.__init__.<locals>.<lambda>)rF   r`   r   ÚapprS   ÚmetadataÚsessionr   Ú	tcp_fragsÚdictÚtcp_sessions)r   rb   r   r6   rH   r   r   r   ü   s    ÿÿzTCPSession.__init__c                 C   sŒ   |d j }d|v rtjntj}|r.t||jƒp0d}|rBt||jƒpDd}|rndd„ }t d|||ƒ|j	|j
A ¡S || t d|j	|j
¡ S d S )NÚTCPZIPv6rK   c                 S   s   t dd„ t| |ƒD ƒƒS )Nc                 s   s"   | ]\}}t |ƒt |ƒA V  qd S r   )r   )Ú.0ÚaÚbr   r   r   Ú	<genexpr>  rK   z5TCPSession._get_ident.<locals>.xor.<locals>.<genexpr>)r[   Úzip)ÚxÚyr   r   r   Úxor  s    z"TCPSession._get_ident.<locals>.xorz!4sHz!HH)Ú
underlayerÚsocketÚAF_INET6ÚAF_INETr	   r=   r>   ÚstructÚpackÚdportZsport)r   r*   rd   rq   Úafr=   r>   rp   r   r   r   Ú
_get_ident  s    
zTCPSession._get_identc                 C   s(  | j rX|j}t|dƒs|S |  jt|ƒ7  _| | j| j| j¡}|rTd| _i | _|S dS ddlm	}m
} |rt||vrx|S || j}t|ttjfƒr–|S |j}|| j}|  |¡}| j| \}	}
| j|  |d¡ }d|
v�r|j}t|dƒrò|j}n|S ||
d< ||
d< n|
d }d|
v�r"||
d< |
 d	d¡}|du �rH|d
  }|
d	< || }|	 ||¡ || jj�sx|| jj�r€d|
d< || jj�r–d|
d< d}|	 ¡ �r´|t|	ƒ|
|ƒ}|�r$d|
v �rÒ|
d || _|	 ¡  |
 ¡  | j|= |j ¡  ||v �rd|| _d|| _ || }d|_!|S dS )zzProcess each packet: matches the TCP seq/ack numbers
        to follow the TCP streams, and orders the fragments.
        Útcp_reassemblerK   Nr   )r8   rh   TÚ	pay_classrT   Úrelative_seqr%   Ztcp_endZtcp_psh)"rb   r@   ÚhasattrrS   r[   rz   rc   rd   r9   r8   rh   Úpayloadr&   r   r   Zpadding_layerÚoriginalrT   ry   re   rg   Úgetr(   r;   ÚFÚRÚPrV   rW   rq   Zremove_payloadrQ   ÚchksumZwirelen)r   r*   r{   r8   rh   ZpayZnew_datarT   ÚidentrS   rc   Ztcp_sessionrz   r|   rB   r   r   r   Ú_process_packet  st    














zTCPSession._process_packetc                 C   s4   |sdS |   |¡}|sdS |  |¡}t | |¡ dS )z—Hook to the Sessions API: entry point of the dissection.
        This will defragment IP if necessary, then process to
        TCP reassembly.
        N)rE   r†   r   r,   rG   r   r   r   r,   v  s    

zTCPSession.on_packet_received)F)F)	r-   r.   r/   r0   r   ry   r†   r,   rI   r   r   rH   r   r`   ß   s
   
Xr`   )r0   Úcollectionsr   rr   ru   Zscapy.compatr   r   Zscapy.configr   Zscapy.packetr   r   Zscapy.plistr   Zscapy.pton_ntopr	   r
   r   r   r   r   r   r   r   Úobjectr   r3   rJ   r`   r   r   r   r   Ú<module>   s   (R/>