a
    kÄ#d~  ã                   @   sÎ  d Z ddlmZ ddlmZ ddl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mZmZ dd
lmZmZmZ ddlmZ ddlmZmZmZ ddlm Z  ddl!m"Z"m#Z# g d¢Z$e	e$dƒe_%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-ddddddœZ.G dd„ de/ƒZ0G d d!„ d!e/ƒZ1G d"d#„ d#e/ƒZ2G d$d%„ d%e/ƒZ3G d&d'„ d'e/ƒZ4G d(d)„ d)eƒZ5e5ej%ƒZ6d*d+„ Z7d?d.d/„Z8d0d1„ Z9d2d3„ Z:d4d5„ Z;d6d7„ Z<d8d9„ Z=d:d;„ Z>d@d=d>„Z?dS )Az+
Clone of p0f v3 passive OS fingerprinting
é    )Úabsolute_import)Úprint_functionN)ÚKnowledgeBaseÚselect_path)Úconf)ÚrawÚorb)Ú	NoPayload)ÚIPÚTCPÚ
TCPOptions)ÚHTTPÚHTTPRequestÚHTTPResponse)ÚIPv6)ÚRandByteÚ	RandShortÚ
RandString)Úwarning)Úinteger_typesÚstring_types)z/etc/p0fz/usr/share/p0fz
/opt/localzp0f.fpé(   é<   é#   é   é   é   é   ÚmssÚwsÚsokÚsackÚts)r   r   r   é   é   c                   @   s<   e Zd Zg d¢Zdd„ Zedd„ ƒZedd„ ƒZdd	„ Zd
S )ÚTCP_Signature©ÚolayoutÚquirksÚ
ip_opt_lenÚip_verÚttlr   ÚwinÚwin_typeÚwscaleÚ	pay_classÚts1c                 C   sF   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	|| _
d S ©Nr&   )Úselfr'   r(   r)   r*   r+   r   r,   r-   r.   r/   r0   © r3   úH/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/modules/p0f.pyÚ__init__7   s    zTCP_Signature.__init__c                    sä  |j }tƒ ‰ ‡ fdd„}|dkrŠ|j}|jd d }|jd@ rF|dƒ |jjrV|dƒ |jjrv|dƒ |jrˆ|d	ƒ q´|jd
kr´|dƒ n*|j	}d
}|j
r¢|dƒ |jd@ r´|dƒ |t }|j}|jd@ rÔ|dƒ |jd
kræ|dƒ |jj�r|jd
k�r|dƒ n|j�r|dƒ |jj�r*|dƒ n|j�r:|dƒ |jj�rL|dƒ |j�rXdnd
}d
}	d
}
d
}d}|jd> d }t|ƒ| d… }|�r¼t|d
 ƒ}|d
k�rÜ|dd… }|dt|ƒ 7 }| d¡�r¼|dƒ �q¼|dk�rþ|dd… }|d7 }�qŒzt|d ƒ}W n" t�y0   |dƒ Y �q¼Y n0 |d|… }|tv �r~td
 | d }|dt|  7 }|�r|dt |¡ nd}t|ƒ|k �rš|dƒ �q¼|dk�rÆ|dk �s¸|d k�r||dƒ �q¼n¶||k�rÜ|dƒ �q¼|�rt ||¡}t|ƒdk�r|d
 }|dk�r|}	nh|dk�r6|}
|
d!k�r||d"ƒ nF|d#k�r¬|d
 }|�sV|d$ƒ |d �r¬|jj �r¬|jj�s¬|d%ƒ n.|dk �s |d&k�s |t|ƒk�r¬|dƒ �q¼||d… }�qŒ|dd'… }| |ˆ ||||	|d|
||ƒS )(zi
        Receives a TCP packet (assuming it's valid), and returns
        a TCP_Signature object
        c                    s   ˆ   | ¡ d S r1   )Úadd)Úname©r(   r3   r4   ÚaddqN   s    z'TCP_Signature.from_packet.<locals>.addqr   é   r   Úecnú0+Údfúid+r   úid-ÚflowéÁ   úseq-úack-úack+úurgf+úuptr+úpushf+r   Ú r   Nzeol+%i,ó    úopt+znop,Úbadz%s,r#   é
   é"   é   Úexwsr$   úts1-úts2+r   éÿÿÿÿ)!ÚversionÚsetr+   ZihlÚtosÚflagsZevilZDFÚidÚhlimÚflÚtcr   ÚwindowÚseqÚAÚackÚUÚurgptrÚPÚpayloadZdataofsr   r   ÚlenÚstripÚ
IndexErrorÚtcp_options_p0fr   ÚstructÚcalcsizeÚunpackÚS)ÚclsÚpktr*   r9   r+   r)   Útcpr,   r/   r   r.   r0   r'   ZoptlenÚxZonumÚolenZovalZofmtZoptsizer3   r8   r4   Úfrom_packetE   sÈ    






















"zTCP_Signature.from_packetc                 C   sœ  t |dƒ\}}}}}}}}	| d¡\}}
}|dkr6dnt|ƒ}|d dkr^t|dd… ƒdfn
t|ƒdf\}}t|ƒ}|dkr‚dnt|ƒ}|dkržd	t }}n„|dd
… dkrÆt|dd… ƒt }}n\|d	 dkrêt|dd… ƒt }}n8|dd
… dk�rt|dd… ƒt }}nt|ƒt }}|dk�r0dnt|ƒ}|�rXtdd„ | 	d¡D ƒƒ}ntƒ }|	dk�rldn
t|	dkƒ}| ||||||||||dƒ}||fS )z|
        Parses a TCP sig line and returns a tuple consisting of a
        TCP_Signature object and bad_ttl as bool
        r$   ú,Ú*rR   ú-NTFr   r   r   r   ú%r   Úmtuc                 s   s   | ]
}|V  qd S r1   r3   ©Ú.0Úqr3   r3   r4   Ú	<genexpr>×   ó    z-TCP_Signature.from_raw_sig.<locals>.<genexpr>ú+)
ÚlparseÚ	partitionÚintÚWIN_TYPE_ANYÚWIN_TYPE_MSSÚWIN_TYPE_MODÚWIN_TYPE_MTUÚWIN_TYPE_NORMALÚ	frozensetÚsplit)rk   Úsig_lineÚverr+   ro   r   Zwsizer'   r(   ÚpclassÚ_Úscaler*   Úbad_ttlr)   r,   r-   r.   r/   Úsigr3   r3   r4   Úfrom_raw_sig¾   s,    0zTCP_Signature.from_raw_sigc                 C   sP   d  dd„ | jD ƒ¡}d}|| j| jt| jƒ| j| j| j| j| j	|| j
f
 }|S )Nrq   c                 s   s   | ]
}|V  qd S r1   r3   rv   r3   r3   r4   ry   à   rz   z(TCP_Signature.__str__.<locals>.<genexpr>z%i:%i+%i:%i:%i:%i,%i:%s:%s:%i)Újoinr(   r*   r+   Ú
guess_distr)   r   r,   r.   r'   r/   )r2   r(   ÚfmtÚsr3   r3   r4   Ú__str__ß   s    
þzTCP_Signature.__str__N©	Ú__name__Ú
__module__Ú__qualname__Ú	__slots__r5   Úclassmethodrp   r�   r’   r3   r3   r3   r4   r%   3   s   
x
 r%   c                   @   s<   e Zd Zg d¢Zdd„ Zedd„ ƒZedd„ ƒZdd	„ Zd
S )ÚHTTP_Signature©Úhttp_verÚhdrÚhdr_setÚhabsentÚswc                 C   s"   || _ || _|| _|| _|| _d S r1   rš   )r2   r›   rœ   r�   rž   rŸ   r3   r3   r4   r5   ë   s
    zHTTP_Signature.__init__c                 C   sð   t |t jƒ}d}| |¡}|dkr:|d|t|ƒ … }n|}| ¡ }| dd¡\}}d|v rdd}nd|v rrd}ntd	ƒ‚d
}g }	tƒ }
| d¡D ]D}| 	d¡\}}}|r’| 
¡ }|	 ||f¡ |
 |¡ |dv r’|}q’t|	ƒ}| |||
d|ƒS )zl
        Receives an HTTP packet (assuming it's valid), and returns
        a HTTP_Signature object
        s   

rR   Nz
r   z1.0r   z1.1zHTTP version is not 1.0/1.1rH   ú:)ú
User-AgentÚServer)r   r   rb   Úfindrc   Údecoder…   Ú
ValueErrorrT   r}   rd   Úappendr6   Útuple)rk   rl   Zhttp_payloadZcrlfcrlfZcrlfcrlfIndexÚheadersÚ
first_liner›   rŸ   Zheaders_foundr�   Zheader_liner7   r‰   Úvaluerœ   r3   r3   r4   rp   ò   s4    

zHTTP_Signature.from_packetc                 C   sÊ   t |dƒ\}}}}|dkrdnt|ƒ}g }t d|¡D ]Z}| d¡\}	}
}|	d dkrx| |	dd	… |dd… d
f¡ q6| |	|dd… df¡ q6t|ƒ}tdd„ |D ƒƒ}t| d¡ƒ}| |||||ƒS )zM
        Parses an HTTP sig line and returns a HTTP_Signature object
        r   rr   rR   z,(?![^\[]*\])ú=r   ú?r   NTFc                 s   s   | ]}|d  s|d V  qdS )r   r   Nr3   )rw   Úheaderr3   r3   r4   ry   )  rz   z.HTTP_Signature.from_raw_sig.<locals>.<genexpr>rq   )r|   r~   Úrer…   r}   r¦   r§   r„   )rk   r†   r‡   Zhorderrž   Zexpswr›   Z
new_horderr­   r7   r‰   rª   rœ   r�   r3   r3   r4   r�     s    "zHTTP_Signature.from_raw_sigc                    s8   d‰ d  ‡ fdd„| jD ƒ¡}d}|| j|| jf }|S )N)ÚHostr¡   ÚDatezContent-Typer¢   rq   c                 3   s*   | ]"\}}|ˆ v r|n
d ||f V  qdS )z%s=[%s]Nr3   )rw   ÚnÚv©Zskipvalr3   r4   ry   0  rz   z)HTTP_Signature.__str__.<locals>.<genexpr>z	%i:%s::%s)rŽ   rœ   r›   rŸ   )r2   rœ   r�   r‘   r3   r³   r4   r’   -  s
    zHTTP_Signature.__str__Nr“   r3   r3   r3   r4   r™   è   s   
%
r™   c                   @   s   e Zd ZddgZdd„ ZdS )Ú
MTU_RecordÚlabel_idru   c                 C   s   || _ t|ƒ| _d S r1   )rµ   r~   ru   ©r2   rµ   r†   r3   r3   r4   r5   :  s    zMTU_Record.__init__N©r”   r•   r–   r—   r5   r3   r3   r3   r4   r´   7  s   r´   c                   @   s   e Zd Zg d¢Zdd„ ZdS )Ú
TCP_Record)rµ   r‹   rŒ   c                 C   s$   || _ t |¡\}}|| _|| _d S r1   )rµ   r%   r�   r‹   rŒ   )r2   rµ   r†   rŒ   r‹   r3   r3   r4   r5   B  s    zTCP_Record.__init__Nr·   r3   r3   r3   r4   r¸   ?  s   r¸   c                   @   s   e Zd ZddgZdd„ ZdS )ÚHTTP_Recordrµ   rŒ   c                 C   s   || _ t |¡| _d S r1   )rµ   r™   r�   rŒ   r¶   r3   r3   r4   r5   L  s    zHTTP_Record.__init__Nr·   r3   r3   r3   r4   r¹   I  s   r¹   c                   @   sB   e Zd ZdZdd„ Zdd„ Zddd„Zd	d
„ Zdd„ Zdd„ Z	dS )Úp0fKnowledgeBasezÅ
    self.base = {
        "mtu" (str): [sig(tuple), ...]
        "tcp"/"http" (str): {
            direction (str): [sig(tuple), ...]
            }
    }
    self.labels = (label(tuple), ...)
    c                 C   s^   zt | jƒ}W n  ty.   td| jƒ Y d S 0 i | _g | _|  |¡ t| jƒ| _| ¡  d S )NzCan't open base %s)	ÚopenÚfilenameÚ	Exceptionr   ÚbaseÚlabelsÚ_parse_filer§   Úclose)r2   Úfr3   r3   r4   Ú	lazy_init[  s    
zp0fKnowledgeBase.lazy_initc                 C   s’  d}|D �]‚}|d dv rq|  ¡ }|d dkrªt|dd… dƒ\}}|dkrdg | j|< | j| }nD|| jvr~|g i| j|< n|| j| vršg | j| |< | j| | }q| d¡\}}}	|  ¡ }|d	k�r|dkrÚt}
n|d
krèt}
n|dkrôt}
| |
||	ƒ¡ q|dk�rX|d7 }|dk�r0| j |	¡ qt|	dƒ\}}}}| j ||||f¡ q|dkrt	dd„ |	 
d¡D ƒƒ}| j|  |f7  < qdS )zS
        Parses p0f.fp file and stores the data with described structures.
        rR   r   )ú;Ú
ú[r   r   ru   z = rŒ   rm   ÚhttpÚlabelr   Úsysc                 s   s   | ]
}|V  qd S r1   r3   ©rw   r7   r3   r3   r4   ry   •  rz   z/p0fKnowledgeBase._parse_file.<locals>.<genexpr>rq   N)rd   r|   r¾   r}   r´   r¸   r¹   r¦   r¿   r§   r…   )r2   Úfilerµ   ÚlineÚsectionÚ	directionZcurr_recordsÚparamr‰   ÚvalZrecord_classÚtÚcr7   ÚflavorZ	sys_namesr3   r3   r4   rÀ   h  sF    





zp0fKnowledgeBase._parse_fileNc           	      C   sl   g }| j d | D ]T}| j|j }|d |d  }}|r||kr|rZ||v rf| |j¡ q| |j¡ q|S )a{  Get TCP signatures that match an OS genre and details (if specified).
        If osdetails isn't specified, then we pick all signatures
        that match osgenre.

        Examples:
            >>> p0fdb.get_sigs_by_os("request", "Linux", "2.6")
            >>> p0fdb.get_sigs_by_os("response", "Windows", "8")
            >>> p0fdb.get_sigs_by_os("request", "FreeBSD")
        rm   r   r   )r¾   r¿   rµ   r¦   rŒ   )	r2   rÎ   ÚosgenreÚ	osdetailsÚsigsÚ
tcp_recordrÈ   r7   rÓ   r3   r3   r4   Úget_sigs_by_os˜  s    
zp0fKnowledgeBase.get_sigs_by_osc                 C   s(  t |ƒ\}}d}d}| jd | D �]ê}|j}d}	|j}
|j|jkrFq"|jdkrl|
|jdkrbdhnh d£8 }
|
|jkr¶|
|jA |
@ }|
|jA |j@ }|s"|dd	h s"|d
dh r²q"d}	|j|jkrÄq"|jrÚ|j|jk rúq"n |j|jk sö|j|j t	krúd}	|j
dk�r|j
|j
ks"|jdk�r*|j|jks"|jdk�rF|j|jk�rFq"|jtk�rd|j|jk�rÀq"n\|jtk�r‚|j|j �rÀq"n>|jtk�r¢|s"|j|k�rÀq"n|jtk�rÀ|r"|j|k�rÀq"| j|j }||j|j |	f}|	�s|d dk�rú|  S |�s|}q"|s"|}q"|�r|S |�r$|S dS )a;  
        Finds the best match for the given signature and direction.
        If a match is found, returns a tuple consisting of:
        - label: the matched label
        - dist: guessed distance from the packet source
        - fuzzy: whether the match is fuzzy
        Returns None if no match was found
        Nrm   FrR   r   r@   >   r=   r?   r>   r=   r>   r?   r;   Tr   r‘   )Údetect_win_multir¾   rŒ   r(   r'   r*   r)   r‹   r+   ÚMAX_DISTr   r.   r/   r-   rƒ   r,   r�   r€   r‚   r¿   rµ   )r2   r"   rÎ   Z	win_multiÚuse_mtuÚgmatchZfmatchr×   ÚrsZfuzzyZ
ref_quirksZdeletedÚaddedrÈ   Úmatchr3   r3   r4   Útcp_find_match®  sx    	

ÿ
ÿþ
þzp0fKnowledgeBase.tcp_find_matchc           	         sÊ   d}| j d | D ]ª}|j‰ ˆ jdkr4ˆ jˆjkr4qˆjˆ j@ ˆ jksHqtˆ jˆj@ ƒdkr^q‡ ‡fdd„}|ƒ stq| j|j }ˆ jo–ˆjo–ˆ jˆjv}||f}|d dkr´|  S |s|}q|rÆ|S dS )a  
        Finds the best match for the given signature and direction.
        If a match is found, returns a tuple consisting of:
        - label: the matched label
        - dishonest: whether the software was detected as dishonest
        Returns None if no match was found
        NrÇ   rR   r   c                     s®   d} t ˆjƒ}ˆ jD ]”}| }| |k rD|d ˆj|  d krD| d7 } q| |kr„|d sZ dS ˆjD ]}|d |d kr`  dS q`|} q|d ˆj|  d vr  dS | d7 } qdS )Nr   r   r   FT)rc   rœ   )ÚphiZhdr_lenZkhZorig_phiÚph©rÝ   r"   r3   r4   Úheaders_correl  s(    

ÿ



z8p0fKnowledgeBase.http_find_match.<locals>.headers_correlr‘   )	r¾   rŒ   r›   r�   rc   rž   r¿   rµ   rŸ   )	r2   r"   rÎ   rÜ   Zhttp_recordrä   rÈ   Z	dishonestrß   r3   rã   r4   Úhttp_find_matchû  s(    z p0fKnowledgeBase.http_find_matchc                 C   s.   | j d D ]}||jkr
| j|j   S q
dS )z”
        Finds a match for the given MTU.
        If a match is found, returns the label string.
        Returns None if no match was found
        ru   N)r¾   ru   r¿   rµ   )r2   ru   Z
mtu_recordr3   r3   r4   Úmtu_find_match<  s    
zp0fKnowledgeBase.mtu_find_match)N)
r”   r•   r–   Ú__doc__rÃ   rÀ   rØ   rà   rå   ræ   r3   r3   r3   r4   rº   Q  s   	0
MArº   c                 C   s"   dD ]}| |kr||    S qd S )N)é    é@   é€   éÿ   r3   )r+   Zottlr3   r3   r4   r�   K  s    r�   r    rH   c                 c   sB   |   |¡d|… }|D ]
}|V  qt|t|ƒ ƒD ]
}|V  q2dS )z&
    Parsing of 'a:b:c:d:e' lines
    N)r…   Úrangerc   )rÌ   r±   Ú	delimiterÚdefaultÚaÚeltr‰   r3   r3   r4   r|   Q  s
    r|   c                 C   s6   |   ¡ } |  t¡o$|  t¡p$|  t¡}|s2tdƒ‚| S )z�
    Validate that the packet is an IPv4/IPv6 and TCP packet.
    If the packet is valid, a copy is returned. If not, TypeError is raised.
    zNot a TCP/IP packet)ÚcopyZhaslayerr   r
   r   Ú	TypeError)rl   Zvalidr3   r3   r4   Úvalidate_packet\  s
    ró   c                 C   sÐ   | j }| j}|r|dk rdS |dfdt dfdt d df|t dfdg}| jrb| |d df¡ | jdkr¦| dt df¡ | dt d df¡ | |t df¡ |D ] \}}|| sª|| |f  S qªdS )	z�
    Figure out if window size is a multiplier of MSS or MTU.
    Receives a TCP signature and returns the multiplier and
    whether mtu should be used
    éd   )rR   FFéÜ  é   T)rõ   Té   )r   r,   ÚMIN_TCP4r0   r¦   r*   ÚMIN_TCP6)r"   r   r,   ÚoptionsÚdivrÛ   r3   r3   r4   rÙ   h  s(    

û
rÙ   c                 C   s¤   t | ƒ} |  t| ƒ¡} | t jjrD| t jjr4d}nd}t | ¡}nX| t j	r”t
ƒ  t| t j	ƒ¡}|tkrrd}n|tkr€d}ntdƒ‚t | ¡}ntdƒ‚||fS )zz
    Returns a p0f signature of the packet, and the direction.
    Raises TypeError if the packet isn't valid for p0f
    ÚresponseÚrequestzNot an HTTP payloadz"Not a SYN, SYN/ACK, or HTTP packet)ró   Ú	__class__r   r   rV   rj   r]   r%   rp   rb   r   Zguess_payload_classr   r   rò   r™   )rl   rÎ   rŒ   rˆ   r3   r3   r4   Ú
packet2p0f‡  s"    
rÿ   c                 C   sj   t | ƒ} d}| jjD ]\}}|dkr|}q|s2dS | jdkrD|t n|t }t ¡ s`tdƒ dS t 	|¡S )zŸ
    Fingerprints the MTU based on the maximum segment size specified
    in TCP options.
    If a match was found, returns the label. If not returns None
    r   ÚMSSNr   úp0f base empty.)
ró   rb   rú   rS   rø   rù   Úp0fdbÚget_baser   ræ   )rl   r   r7   rª   ru   r3   r3   r4   Úfingerprint_mtu¥  s    r  c                 C   sF   t | ƒ\}}t ¡ s tdƒ d S t|tƒr6t ||¡S t ||¡S d S )Nr  )rÿ   r  r  r   Ú
isinstancer%   rà   rå   )rl   rŒ   rÎ   r3   r3   r4   Úp0f½  s    
r  c                    sb  zt | ƒ}W n ty    Y dS 0 t| ƒ\}}t|tƒ}|dk}|rR|rLdnd}n|rZdnd}|  d| d ¡}g ‰ ‡ fd	d
„}|rˆdnd}	||	|  d¡ƒ |�r|d }
|
d dkrºdnd}|||
d d |
d  ƒ t|
ƒdk�r|dd dd„ |
d D ƒ¡ƒ |�r2|d|d ƒ n|�r$dnd}||dƒ |dt|ƒƒ |d ˆ ¡7 }|d 7 }t	|ƒ dS )!z+Calls p0f and prints a user-friendly outputNrý   ZSYNzSYN+ACKzHTTP RequestzHTTP Responsez2.-[ %IP.src%:%TCP.sport% -> %IP.dst%:%TCP.dport% (z) ]-
|
c                    s   ˆ   d| |f ¡ d S )Nz| %-8s = %s
)r¦   )r7   rª   ©Úfieldsr3   r4   Ú	add_fieldÜ  s    zprnp0f.<locals>.add_fieldZClientr¢   z%IP.src%:%TCP.sport%r   r   ú!ZAppZOSr   ú r   r#   ZSysz, c                 s   s   | ]
}|V  qd S r1   r3   rÊ   r3   r3   r4   ry   ç  rz   zprnp0f.<locals>.<genexpr>r   ZDistanceÚUNKNOWNzRaw sigrH   z`____
)
r  r½   rÿ   r  r%   Zsprintfrc   rŽ   ÚstrÚprint)rl   ÚrrŒ   rÎ   Z
is_tcp_sigZ	to_serverZpkt_typeÚresr	  Z
cli_or_svrrÈ   Z	app_or_osr3   r  r4   Úprnp0fÉ  s:    

r  rõ   c              	      s  t ˆƒ‰|s|stdƒ‚ˆt }|jd@ }|rRt|tƒrHt |¡\}	}
q¦tdƒ‚nTt	 
¡ s`g }n|dkrldnd}t	 |||¡}‡fdd„|D ƒ}|sœtd	ƒ‚t |¡}	|	jd
krÄˆj|	jkrÄtdƒ‚|	j}ˆjdk�r¾|	j| ˆ_|	jdkrötdƒ ng ˆ_d|v �rBˆ jdO  _d|v �r:ˆjdk�r@t dd¡ˆ_ndˆ_n:ˆ jdM  _d|v �rbdˆ_nˆjdk�r|t dd¡ˆ_d|v �rœˆ jt dd¡O  _d|v �r°ˆjdB nˆjd@ ˆ_nD|	j| ˆ_d|v �rât dd¡ˆ_d|v �rˆ jt dd¡O  _dd„ ‰ t|jƒ}ˆ | d¡ƒ}ˆ | d¡ƒ}‡ fdd„| d d!¡D ƒ}g }|	j d"¡D �]Þ}|d#k�rð|	jt k�r‚d|	j! }nd}|	j"d
k�rÜ|�rÄd|  k�r°|k�rÄn n| #d|f¡ n| #dt d$|¡f¡ n| #d|	j"f¡ �nB|d%k�rº|	j$d
k�r¦d&}d'|v �rb|�rFd(|  k �r2|k �rFn n| #d|f¡ n| #dt d)|d ¡f¡ nB|�r”d|  k�r€|k �r”n n| #d|f¡ n| #dt%ƒ f¡ n| #d|	j$f¡ �nx|d*k�rz|\}}d+|v �rÜd}n@|d,u�rì|}n0|d,u �sd|  k �rd-k �sn t d.d/¡}d0|v �rb|dk�rb|d,u �sTd|  k �rRd-k �sfn t dd1¡}nd}| #d ||ff¡ n¸|d2k�r�| #d3¡ n¢|d4k�r¦| #d5¡ nŒ|d,d… d6k�rÖ| #d7¡ d8|v �r2td9ƒ n\|d:k�r(t g d;¢¡d }d<|d  }t&t' (|¡ƒ )¡ }| #d=t' *||¡f¡ n
td>|ƒ ||_�qZ|	jt+k�rR|	j!|_,nž|	jt k�r�d?d„ |D ƒ}|�sztd@ƒ‚|d d |	j! |_,n`|	jt-k�r¸|	j!t dd|	j! ¡ |_,n8|	jt.k�rÒ||	j! |_,n|	jt/k�rèt0ƒ |_,ntdAƒ dB|v �rd|_1n|j1dk�rt dd1¡|_1dC|v �rP| jdDM  _|j2dk�rnt dd1¡|_2ndE|v �rn| jdFO  _d|_2dG|v �r¢| jdHM  _|j3dk�rºt dd¡|_3ndI|v �rº| jdJO  _dK|v �rÎ|jdLB n|jdM@ |_|	j4�r|j5�sˆt6j7t&t ddN¡ƒdO� ‰nt8ƒ |_5ˆS )Pa¥  Modifies pkt so that p0f will think it has been sent by a
    specific OS. Either osgenre or signature is required to impersonate.
    If signature is specified (as a raw string), we use the signature.
    signature format:
        "ip_ver:ttl:ip_opt_len:mss:window,wscale:opt_layout:quirks:pay_class"

    If osgenre is specified, we randomly pick a signature with a label
    that matches osgenre (and osdetails, if specified).
    Note: osgenre is case sensitive ("linux" -> "Linux" etc.), and osdetails
    is a substring of a label flavor ("7", "8" and "7 or 8" will
    all match the label "s:win:Windows:7 or 8")

    For now, only TCP SYN/SYN+ACK packets are supported.z0osgenre or signature is required to impersonate!é   zUnsupported signature typer   rý   rü   c                    s&   g | ]}|j d ks|j ˆ jkr|‘qS )rR   )r*   rS   )rw   r‘   )rl   r3   r4   Ú
<listcomp>  rz   z#p0f_impersonate.<locals>.<listcomp>zNo match in the p0f databaserR   z#Can't convert between IPv4 and IPv6r   r   zUnhandled IPv4 option fieldr=   r>   r   iÿÿ  éýÿÿÿr?   r;   r   r<   éûÿÿÿr@   iÿÿ c                 S   s   t | tƒr| S d S r1   )r  r   )rÐ   r3   r3   r4   Úint_onlyD  s    z!p0f_impersonate.<locals>.int_onlyr   ZWScalec                    s   g | ]}ˆ |ƒ‘qS r3   r3   )rw   Úo)r  r3   r4   r  I  rz   Ú	Timestamp)NNrq   r   rô   r   é   rO   rN   é   r"   rP   Nl        éx   l    ðw rQ   l   ÿÿ Znop)ÚNOPNr    )ZSAckOKrH   Úeol)ZEOLNrJ   zUnhandled opt+ quirkr!   )rL   r  é   rM   z!%iIZSAckzUnhandled TCP option %sc                 S   s   g | ]}|d  dkr|‘qS )r   r   r3   )rw   rn   r3   r3   r4   r  ”  rz   z5TCP window value requires MSS, and MSS option not setz#Unhandled window size specificationrB   rD   iïÿÿÿrC   é   rF   ißÿÿÿrE   rè   rG   r$   i÷ÿÿÿrL   )Úload)9ró   r¥   r   rV   r  r   r%   r�   rò   r  r  rØ   ÚrandomÚchoicer*   rS   r(   r+   r)   r   rú   rW   ÚrandintrU   rX   rY   rZ   ÚdictÚgetr'   r…   r-   r€   r,   r   r¦   r.   r   r   rg   rh   Ú_fixri   rƒ   r[   r�   r‚   r   r   r\   r^   r`   r/   rb   r   Z	raw_layerr	   )rl   rÔ   rÕ   Ú	signatureZ	extrahopsru   Zuptimerm   Ztcp_typerŒ   r‰   rÖ   rÎ   r(   Z	orig_optsZmss_hintZws_hintZts_hintrú   ÚoptZmaxmssZmaxwsr0   Zts2Zsack_lenZ	optstructZrand_valr   r3   )r  rl   r4   Úp0f_impersonateõ  s   









"



"

""


$$














 r)  )r    rH   )NNNr   rõ   N)@rç   Ú
__future__r   r   r®   rg   r!  Z
scapy.datar   r   Zscapy.configr   Zscapy.compatr   r   Zscapy.packetr	   Zscapy.layers.inetr
   r   r   Zscapy.layers.httpr   r   r   Zscapy.layers.inet6r   Zscapy.volatiler   r   r   Zscapy.errorr   Zscapy.libs.sixr   r   Z	_p0fpathsZp0f_baserø   rù   rÚ   rƒ   r   r�   r€   r‚   rf   Úobjectr%   r™   r´   r¸   r¹   rº   r  r�   r|   ró   rÙ   rÿ   r  r  r  r)  r3   r3   r3   r4   Ú<module>   sf   û
 6O
 x

,  ÿ