a
    kÄ#dä?  ã                   @   sl  d Z ddlmZ ddlZddl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mZmZmZmZmZ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 dd	l 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,m-Z- G dd„ dee	ƒZ.G dd„ deeƒZ/G dd„ deƒZ0G dd„ de0ƒZ1G dd„ de0ƒZ2G dd„ de0ƒZ3G dd„ deƒZ4G dd„ de0ƒZ5G dd„ de0ƒZ6g d ¢Z7G d!d"„ d"e0ƒZ8G d#d$„ d$e0ƒZ9d%d&d'd(d)d*d+d,d-d.d/d0œZ:d1d2gZ;G d3d4„ d4e0ƒZ<G d5d6„ d6e0ƒZ=G d7d8„ d8e0ƒZ>dddddd"d$d4d6d8d9œ
Z?d:d;„ Z@d<d=d>d?d)d@dAdBdCœZAg dD¢ZBG dEd&„ d&eƒZCeeeCdFdG� eeeCdFdH� dS )Ia  
    EIGRP Scapy Extension
    ~~~~~~~~~~~~~~~~~~~~~

    :version:   2009-08-13
    :e-mail:    lobo@c3a.de / jochen.bartl@gmail.com

    :TODO

    - Replace TLV code with a more generic solution
        * http://trac.secdev.org/scapy/ticket/90
    - Write function for calculating authentication data

    :Thanks:

    - TLV code derived from the CDP implementation of scapy. (Thanks to Nicolas Bareil and Arnaud Ebalard)
        http://trac.secdev.org/scapy/ticket/18
    - IOS / EIGRP Version Representation FIX by Dirk Loss
é    )Úabsolute_importN)ÚPacket)ÚStrFieldÚIPFieldÚXShortFieldÚFieldLenFieldÚStrLenFieldÚIntFieldÚByteEnumFieldÚ	ByteFieldÚConditionalFieldÚ
FlagsFieldÚIP6FieldÚPacketListFieldÚShortEnumFieldÚ
ShortFieldÚStrFixedLenFieldÚThreeBytesField)ÚIPÚchecksumÚbind_layers)ÚIPv6)Úchb)Úconf)Ú	inet_atonÚ	inet_ntoa)Ú	inet_ntopÚ	inet_pton)ÚwarningÚScapy_Exception)Ú	RandShortÚ
RandStringc                   @   sX   e Zd ZdZdgZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )ÚEigrpIPFieldzé
    This is a special field type for handling ip addresses of destination networks in internal and
    external route updates.

    EIGRP removes zeros from the host portion of the ip address if the netmask is 8, 16 or 24 bits.
    Úlength_fromNc                 C   s.   t  | ||¡ || _|d ur*|fdd„| _d S )Nc                 S   s   |S ©N© ©ÚpktÚlengthr%   r%   úJ/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/contrib/eigrp.pyÚ<lambda>=   ó    z'EigrpIPField.__init__.<locals>.<lambda>©r   Ú__init__r#   ©ÚselfÚnameÚdefaultr(   r#   r%   r%   r)   r-   9   s    zEigrpIPField.__init__c                 C   s   t  | ||¡S r$   )r   Úh2i©r/   r'   Úxr%   r%   r)   r2   ?   s    zEigrpIPField.h2ic                 C   sV   t |ƒ}|  |¡}|dkr&|d d… S |dkr:|d d… S |dkrN|d d… S |S d S )Né   é   é   é   é   é   )r   r#   ©r/   r'   r4   Útmp_lenr%   r%   r)   Úi2mB   s    
zEigrpIPField.i2mc                 C   sF   |   |¡}|dkr|d7 }n"|dkr.|d7 }n|dkr>|d7 }t|ƒS )Nr5   s      r7   s     r9   ó    )r#   r   r;   r%   r%   r)   Úm2iO   s    


zEigrpIPField.m2ic                 C   s2   |dkrd}n |dkrd}n|dkr*d}nd}|S )Nr5   r6   r7   r8   r9   r:   é   r%   )r/   r<   r%   r%   r)   Úprefixlen_to_bytelen[   s    z!EigrpIPField.prefixlen_to_bytelenc                 C   s   |   |¡}|  |¡}|S r$   ©r#   rA   r;   r%   r%   r)   Úi2leng   s    

zEigrpIPField.i2lenc                 C   s4   |   |¡}|  |¡}||d … |  ||d |… ¡fS r$   ©r#   rA   r?   ©r/   r'   Úsr<   r%   r%   r)   Úgetfieldl   s    

zEigrpIPField.getfieldc                 C   s
   t  | ¡S r$   )r   Úrandval©r/   r%   r%   r)   rH   q   s    zEigrpIPField.randval)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r-   r2   r=   r?   rA   rC   rG   rH   r%   r%   r%   r)   r"   /   s   
r"   c                   @   sh   e Zd ZdZdgZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )ÚEigrpIP6Fieldz…
    This is a special field type for handling ip addresses of destination networks in internal and
    external route updates.

    r#   Nc                 C   s.   t  | ||¡ || _|d ur*|fdd„| _d S )Nc                 S   s   |S r$   r%   r&   r%   r%   r)   r*   ‚   r+   z(EigrpIP6Field.__init__.<locals>.<lambda>r,   r.   r%   r%   r)   r-   ~   s    zEigrpIP6Field.__init__c                 C   s   t  | ||¡S r$   )r   Úany2ir3   r%   r%   r)   rP   „   s    zEigrpIP6Field.any2ic                 C   s   t  | ||¡S r$   )r   Úi2reprr3   r%   r%   r)   rQ   ‡   s    zEigrpIP6Field.i2reprc                 C   s   t  | ||¡S r$   )r   r2   r3   r%   r%   r)   r2   Š   s    zEigrpIP6Field.h2ic                 C   s,   t tj|ƒ}|  |¡}|  |¡}|d |… S r$   )r   ÚsocketÚAF_INET6r#   rA   r;   r%   r%   r)   r=   �   s    

zEigrpIP6Field.i2mc                 C   sF   |   |¡}|  |¡}|dkr&tdƒ ndd|  }||7 }ttj|ƒS )Né€   zJEigrpIP6Field: Prefix length is > 128. Dissection of this packet will failr>   r7   )r#   rA   r   r   rR   rS   )r/   r'   r4   r<   Ú	prefixlenÚpadr%   r%   r)   r?   ”   s    


zEigrpIP6Field.m2ic                 C   s   |d }|dk r|d7 }|S )Nr5   r7   r6   r%   )r/   Úplenr%   r%   r)   rA       s    z"EigrpIP6Field.prefixlen_to_bytelenc                 C   s   |   |¡}|  |¡}|S r$   rB   r;   r%   r%   r)   rC   ¨   s    

zEigrpIP6Field.i2lenc                 C   s4   |   |¡}|  |¡}||d … |  ||d |… ¡fS r$   rD   rE   r%   r%   r)   rG   ­   s    

zEigrpIP6Field.getfieldc                 C   s
   t  | ¡S r$   )r   rH   rI   r%   r%   r)   rH   ²   s    zEigrpIP6Field.randval)NN)rJ   rK   rL   rM   rN   r-   rP   rQ   r2   r=   r?   rA   rC   rG   rH   r%   r%   r%   r)   rO   u   s   
rO   c                   @   sH   e Zd ZdZeddƒedddddd	„ d
�edddd	„ d�gZdd„ ZdS )ÚEIGRPGenericzEIGRP Generic TLVÚtyper   ÚlenNÚvalueú!Hc                 C   s   |d S ©Nr@   r%   ©r'   r4   r%   r%   r)   r*   ¹   r+   zEIGRPGeneric.<lambda>©Úadjustr>   c                 C   s
   | j d S r]   )rZ   ©r'   r%   r%   r)   r*   º   r+   ©r#   c                 C   s   t jS r$   )r   Zpadding_layer)r/   Úpr%   r%   r)   Úguess_payload_class¼   s    z EIGRPGeneric.guess_payload_class)	rJ   rK   rL   r0   r   r   r   Úfields_descrd   r%   r%   r%   r)   rX   ¶   s   þrX   c                   @   s\   e Zd ZdZeddƒeddƒeddƒeddƒed	dƒed
dƒeddƒeddƒeddƒg	ZdS )Ú
EIGRPParamzEIGRP ParametersrY   r6   rZ   é   Zk1Zk2r   Zk3Zk4Zk5ÚreservedZholdtimeé   N)rJ   rK   rL   r0   r   r   r   re   r%   r%   r%   r)   rf   À   s   órf   c                   @   st   e Zd ZdZeddƒedddddd	„ d
�eddddiƒeddƒeddƒe	dddƒe
dedƒdd	„ d�gZdd„ ZdS )ÚEIGRPAuthDatazEIGRP Authentication DatarY   r8   rZ   NÚauthdatar\   c                 C   s   |d S )Nr9   r%   r^   r%   r%   r)   r*   Ö   r+   zEIGRPAuthData.<lambda>r_   ZauthtypeÚMD5ÚkeysizeZkeyidr6   Znullpads               rg   r7   c                 C   s   | j S r$   )rm   ra   r%   r%   r)   r*   Û   r+   rb   c                 C   sT   ||7 }| j d u rPt| jƒ}|d d… t|d? d@ ƒ t|d@ ƒ |dd …  }|S )Né   r5   éÿ   )rm   rZ   rk   r   )r/   rc   Úpayrm   r%   r%   r)   Ú
post_buildÞ   s
    

4zEIGRPAuthData.post_build)rJ   rK   rL   r0   r   r   r   r   r	   r   r   r!   re   rq   r%   r%   r%   r)   rj   Ó   s   
ú	rj   c                   @   sX   e Zd ZdZeddƒeddƒeddƒeedd	ƒd
d„ ƒee	ddƒdd„ ƒgZ
dd„ ZdS )ÚEIGRPSeqzEIGRP SequencerY   r:   rZ   NÚaddrlenr@   Úipaddrú192.168.0.1c                 C   s
   | j dkS r]   ©rs   ra   r%   r%   r)   r*   î   r+   zEIGRPSeq.<lambda>Zip6addrú2001::c                 C   s
   | j dkS )Nr7   rv   ra   r%   r%   r)   r*   ð   r+   c                 C   sV   ||7 }| j d u rRt |ƒ}|d d… t|d? d@ ƒ }|t|d@ ƒ |dd …  }|S ©Nr8   r5   ro   r@   )rZ   r   )r/   rc   rp   r<   Ztmp_pr%   r%   r)   rq   ó   s    
zEIGRPSeq.post_build)rJ   rK   rL   r0   r   r   r   r   r   r   re   rq   r%   r%   r%   r)   rr   è   s   
ÿ
ÿû	rr   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚShortVersionFieldc                 C   s>   z|d@ }|d? d@ }W n t y,   Y dS 0 d||f S d S )Nro   r5   Úunknownzv%s.%s)Ú	TypeError)r/   r'   r4   ÚminorÚmajorr%   r%   r)   rQ   ÿ   s    zShortVersionField.i2reprc                 C   s²   t |tƒrX| d¡rXt|ƒdkrXt| d¡d dd… ƒ}t| d¡d ƒ}|d> |B S t |tƒr~d|  krvdkr~n n|S t| dƒsŒ|S | jdur¦td	|ƒ | jS t	d
ƒ‚dS )zÔThe field accepts string values like v12.1, v1.1 or integer values.
           String values have to start with a "v" followed by a
           floating point number. Valid numbers are between 0 and 255.

        Úvr5   Ú.r   r6   Niÿÿ  r1   z-set value to default. Format of %r is invalidzFormat of value is invalid)
Ú
isinstanceÚstrÚ
startswithrZ   ÚintÚsplitÚhasattrr1   r   r   )r/   r'   r4   r}   r|   r%   r%   r)   r2   	  s     "


zShortVersionField.h2ic                 C   s   t ƒ S r$   )r    rI   r%   r%   r)   rH   !  s    zShortVersionField.randvalN)rJ   rK   rL   rQ   r2   rH   r%   r%   r%   r)   ry   þ   s   
ry   c                   @   s4   e Zd ZdZeddƒeddƒeddƒedd	ƒgZd
S )Ú
EIGRPSwVerzEIGRP Software VersionrY   r@   rZ   r5   Zioszv12.0Zeigrpzv1.2N)rJ   rK   rL   r0   r   r   ry   re   r%   r%   r%   r)   r†   %  s   ýr†   c                   @   s,   e Zd ZdZeddƒeddƒeddƒgZdS )	ÚEIGRPNmszEIGRP Next Multicast SequencerY   é   rZ   r5   Znmsr8   N)rJ   rK   rL   r0   r   r   r	   re   r%   r%   r%   r)   r‡   .  s
   þr‡   )Ú	connectedZstaticÚsummaryzreceive-onlyZredistributedzleak-mapc                   @   s0   e Zd ZdZeddƒeddƒedddeƒgZdS )	Ú	EIGRPStubzEIGRP Stub RouterrY   rn   rZ   Úflagsé   r7   N)	rJ   rK   rL   r0   r   r   r   Ú_EIGRP_STUB_FLAGSre   r%   r%   r%   r)   r‹   ;  s
   þr‹   c                   @   sˆ   e Zd ZdZeddƒedddddd	„ d
�eddƒeddƒeddƒeddƒe	ddƒe	ddƒe	ddƒeddƒe	ddƒe
dddd	„ d�gZdS )ÚEIGRPIntRoutezEIGRP Internal RouterY   é  rZ   NÚdstr\   c                 C   s   |d S )Né   r%   r^   r%   r%   r)   r*   G  r+   zEIGRPIntRoute.<lambda>r_   Únexthopú192.168.0.0Údelayé ô Ú	bandwidthé   ÚmtuéÜ  Úhopcountr   Úreliabilityro   Úloadrh   rU   r9   ú192.168.1.0c                 C   s   | j S r$   ©rU   ra   r%   r%   r)   r*   Q  r+   rb   )rJ   rK   rL   r0   r   r   r   r	   r   r   r"   re   r%   r%   r%   r)   r�   D  s   õr�   ZIGRPÚEIGRPzStatic RouteZRIPZHelloZOSPFzIS-ISZEGPZBGPZIDRPzConnected Link)r6   r8   r:   r@   rˆ   rn   é   r5   é	   é
   é   Zexternalzcandidate-defaultc                   @   sÆ   e Zd ZdZeddƒedddddd	„ d
�eddƒeddƒeddƒeddƒeddƒeddƒe	dde
ƒedddeƒeddƒeddƒeddƒeddƒeddƒed dƒed!dƒed"d#ƒedd$d%d	„ d&�gZdS )'ÚEIGRPExtRoutezEIGRP External RouterY   é  rZ   Nr‘   r\   c                 C   s   |d S )Né-   r%   r^   r%   r%   r)   r*   i  r+   zEIGRPExtRoute.<lambda>r_   r“   r”   Úoriginrouterru   Ú	originasnr   ÚtagÚexternalmetricrh   Úextprotocolidr:   rŒ   r5   r•   r—   r˜   r™   rš   r›   rœ   ro   r�   Ú	reserved2rU   r9   rž   c                 C   s   | j S r$   rŸ   ra   r%   r%   r)   r*   z  r+   rb   )rJ   rK   rL   r0   r   r   r   r	   r   r
   Ú_EIGRP_EXTERNAL_PROTOCOL_IDr   Ú_EIGRP_EXTROUTE_FLAGSr   r   r"   re   r%   r%   r%   r)   r¥   f  s*   
îr¥   c                   @   sˆ   e Zd ZdZeddƒedddddd	„ d
�eddƒeddƒeddƒeddƒe	ddƒe	ddƒe	ddƒeddƒe	ddƒe
dddd	„ d�gZdS )ÚEIGRPv6IntRoutezEIGRP for IPv6 Internal RouterY   é  rZ   Nr‘   r\   c                 C   s   |d S )Né%   r%   r^   r%   r%   r)   r*   �  r+   zEIGRPv6IntRoute.<lambda>r_   r“   ú::r•   r–   r—   é è r™   rš   r›   r6   rœ   ro   r�   r   rh   rU   r7   rw   c                 C   s   | j S r$   rŸ   ra   r%   r%   r)   r*   ‹  r+   rb   )rJ   rK   rL   r0   r   r   r   r	   r   r   rO   re   r%   r%   r%   r)   r°   ~  s   õr°   c                   @   sÆ   e Zd ZdZeddƒedddddd	„ d
�eddƒeddƒeddƒeddƒeddƒe	ddƒe
ddeƒedddeƒeddƒeddƒeddƒeddƒeddƒed dƒed!dƒed"dƒeddd#d	„ d$�gZdS )%ÚEIGRPv6ExtRoutezEIGRP for IPv6 External RouterY   é  rZ   Nr‘   r\   c                 C   s   |d S )Né9   r%   r^   r%   r%   r)   r*   ’  r+   zEIGRPv6ExtRoute.<lambda>r_   r“   r³   r¨   ru   r©   r   rª   r«   rh   r¬   r:   rŒ   r5   r•   r—   r´   r™   rš   r›   r6   rœ   r�   r­   rU   c                 C   s   | j S r$   rŸ   ra   r%   r%   r)   r*   £  r+   rb   )rJ   rK   rL   r0   r   r   r   r   r	   r   r
   r®   r   r¯   r   r   rO   re   r%   r%   r%   r)   rµ   �  s*   
îrµ   )
r6   r8   r:   r@   rˆ   rn   r�   r¦   r±   r¶   c                 K   sP   t j}t| ƒdkr@t d| d d… ¡d }t |d¡}tƒ | }|| fi |¤ŽS )Nr8   r\   r   rX   )r   Z	raw_layerrZ   ÚstructÚunpackÚ_eigrp_tlv_clsÚgetÚglobals)rc   ZkargsÚclsÚtÚclsnamer%   r%   r)   Ú_EIGRPGuessPayloadClassµ  s    
rÀ   ZUpdateÚRequestZQueryZReplayzIPX SAPz	SIA Queryz	SIA Reply)r6   r8   r:   r@   rˆ   rn   r£   r¤   )Úinitz	cond-recvrz   Úupdatec                   @   sl   e Zd Zd Zeddƒeddeƒeddƒeddd	e	ƒe
d
dƒe
ddƒe
ddƒedg eƒgZdd„ Zdd„ ZdS )r    Úverr8   Úopcoderˆ   ÚchksumNrŒ   r   é    ÚseqÚackZasnéd   Ztlvlistc                 C   sR   ||7 }| j d u rNt|ƒ}|d d… t|d? d@ ƒ t|d@ ƒ |dd …  }|S rx   )rÆ   r   r   )r/   rc   rp   Úcr%   r%   r)   rq   Ù  s
    
4zEIGRP.post_buildc                 C   s@   d}| j dkr | jdkr |d7 }| jdkr2|d7 }|  |d ¡S )Nz+EIGRP (AS=%EIGRP.asn% Opcode=%EIGRP.opcode%rˆ   r   z (ACK)z Flags=%EIGRP.flags%ú))rÅ   rÉ   rŒ   Zsprintf)r/   Z
summarystrr%   r%   r)   Ú	mysummaryà  s    
zEIGRP.mysummary)rJ   rK   rL   r0   r   r
   Ú_EIGRP_OPCODESr   r   Ú_EIGRP_FLAGSr	   r   rÀ   re   rq   rÍ   r%   r%   r%   r)   r    Í  s   

ù
éX   )Úproto)Znh)DrM   Ú
__future__r   rR   r¸   Zscapy.packetr   Zscapy.fieldsr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   Zscapy.layers.inetr   r   r   Zscapy.layers.inet6r   Zscapy.compatr   Zscapy.configr   Zscapy.utilsr   r   Zscapy.pton_ntopr   r   Zscapy.errorr   r   Zscapy.volatiler    r!   r"   rO   rX   rf   rj   rr   ry   r†   r‡   rŽ   r‹   r�   r®   r¯   r¥   r°   rµ   rº   rÀ   rÎ   rÏ   r    r%   r%   r%   r)   Ú<module>	   s„   HFA
'	
	õö	ù