a
    kÄ#d'  ã                    @   sÜ  d Z ddl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mZmZ ddlmZ ddlmZmZ dd	d
œZdddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*œZd+d,d-d.d/d0d1d2d3œZG d4d5„ d5eƒZG d6d7„ d7eƒZG d8d9„ d9eƒZG d:d;„ d;eƒZG d<d=„ d=eƒZG d>d?„ d?eƒZG d@dA„ dAeƒZG dBdC„ dCeƒZ G dDdE„ dEe
ƒZ!G dFdG„ dGe ƒZ"G dHdI„ dIe ƒZ#eeedJdK� eeedJdL� eeedMdN� eee"dOdN� eeedMdN� eee#dOdN� dS )PzÙ
PCOM

PCOM is a protocol to communicate with Unitronics PLCs either by serial
or TCP. Two modes are available, ASCII and Binary.

https://unitronicsplc.com/Download/SoftwareUtilities/Unitronics%20PCOM%20Protocol.pdf
é    N)ÚPacketÚbind_layers)ÚTCP)	ÚXShortFieldÚByteEnumFieldÚ
XByteFieldÚStrFixedLenFieldÚStrLenFieldÚLEShortFieldÚLEFieldLenFieldÚLEX3BytesFieldÚXLEShortField)Ú	RandShort)Úbytes_encodeÚorbÚasciiÚbinary)ée   éf   zSend Identification CommandzSend Start CommandzSend Stop CommandzSend Reset CommandzSend Init CommandzReply of Admin Commands (CC*)z
Get UnitIDz
Set UnitIDzGet RTCzSet RTCzRead InputszRead OutputszRead System BitszRead System IntegerszRead System LongszRead System Double WordszRead Memory BitszRead Memory IntegerszRead Memory LongszRead Memory Double WordszRead Longs / Double WordszWrite OutputszWrite System BitszWrite System IntegerszWrite System LongszWrite System Double WordszWrite Memory BitszWrite Memory IntegerszWrite Memory LongszWrite Memory Double WordszWrite Longs / Double Words)ZIDZCCRZCCSZCCEZCCIÚCCZUGZUSÚRCZSCZREZRAZGSZGFZRNHZRNJZRBZRWZRNLZRNDZRNZSAZSSZSFZSNHZSNJZSBZSWZSNLZSNDZSNzGet PLC Name RequestzGet PLC Name ReplyzRead Operands RequestzRead Operands ReplyzRead Data Table RequestzRead Data Table ReplyzWrite Data Table RequestzWrite Data Table Reply)é   éŒ   éM   éÍ   é   é„   éD   éÄ   c                   @   s<   e Zd Zedeƒ ƒeddeƒeddƒeddƒgZ	dd	„ Z
dS )
ÚPCOMZtransIdÚmoder   Úreservedr   ÚlenNc                 C   s2   | j d u r*|r*|d d… t dt |ƒ¡ }|| S )Nr   ÚH)r"   ÚstructÚpack)ÚselfÚpktÚpay© r)   úO/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/contrib/scada/pcom.pyÚ
post_buildT   s    zPCOM.post_build)Ú__name__Ú
__module__Ú__qualname__r   r   r   Ú_protocol_modesr   r
   Úfields_descr+   r)   r)   r)   r*   r   L   s   

ür   c                   @   s   e Zd ZdZdS )ÚPCOMRequestzPCOM/TCP RequestN©r,   r-   r.   Únamer)   r)   r)   r*   r1   Z   s   r1   c                   @   s   e Zd ZdZdS )ÚPCOMResponsezPCOM/TCP ResponseNr2   r)   r)   r)   r*   r4   ^   s   r4   c                   @   s   e Zd Zedd„ ƒZdS )Ú	PCOMAsciic                 C   sR   d}t | ƒ} t| ƒD ]\}}|t|ƒ7 }qtttt|d ƒdd …  d¡ ¡ ƒƒS )Nr   é   é   )	r   Ú	enumerater   ÚlistÚmapÚordÚhexÚzfillÚupper)ÚcommandÚnÚ_Úcr)   r)   r*   Úpcom_ascii_checksumc   s
    zPCOMAscii.pcom_ascii_checksumN)r,   r-   r.   ÚstaticmethodrC   r)   r)   r)   r*   r5   b   s   r5   c                       s   e Zd Z‡ fdd„Z‡  ZS )ÚPCOMAsciiCommandFieldc                    s^   t t| ƒ ||¡}|dd… }|tv r6t| d | S |dd… }|tv rZt| d | S |S )Né   r   ú é   )ÚsuperrE   Úi2reprÚ_ascii_command_codes)r&   r'   ÚxÚsÚcode©Ú	__class__r)   r*   rJ   m   s    zPCOMAsciiCommandField.i2repr©r,   r-   r.   rJ   Ú__classcell__r)   r)   rO   r*   rE   l   s   rE   c                   @   sP   e Zd ZdZedddƒedddƒedd	d
d„ d�eddƒeddƒgZdd„ Z	dS )ÚPCOMAsciiRequestzPCOM/ASCII RequestÚstxú/rF   ÚunitIdÚ00r7   r?   Ú c                 C   s   | j jd S )Né   ©Z
underlayerr"   ©r'   r)   r)   r*   Ú<lambda>~   ó    zPCOMAsciiRequest.<lambda>©Zlength_fromÚchksumNÚetxé   c                 C   sR   | j d u rJt |dd… ¡}|d d… t d|d |d ¡ |dd …  }|| S )NrF   éýÿÿÿÚ2Br   éÿÿÿÿ©r_   r5   rC   r$   r%   ©r&   r'   r(   r_   r)   r)   r*   r+   ƒ   s    
.zPCOMAsciiRequest.post_build©
r,   r-   r.   r3   r   rE   r   r   r0   r+   r)   r)   r)   r*   rS   x   s   


ÿú	rS   c                   @   sP   e Zd ZdZedddƒedddƒeddd	d
„ d�eddƒeddƒgZdd„ Z	dS )ÚPCOMAsciiResponsezPCOM/ASCII ResponserT   z/Ar7   rV   rW   r?   rX   c                 C   s   | j jd S )Né   rZ   r[   r)   r)   r*   r\   �   r]   zPCOMAsciiResponse.<lambda>r^   r_   Nr`   ra   c                 C   sR   | j d u rJt |dd… ¡}|d d… t d|d |d ¡ |dd …  }|| S )Nr7   rb   rc   r   rF   rd   re   rf   r)   r)   r*   r+   •   s    
.zPCOMAsciiResponse.post_buildrg   r)   r)   r)   r*   rh   Š   s   


ÿú	rh   c                   @   s    e Zd Zedd„ ƒZdd„ ZdS )Ú
PCOMBinaryc                 C   s’   d}t | ƒ} t| ƒD ]&\}}t|tƒr*|nt|ƒ}||7 }q|dkrLddgS td|d  ƒdd …  d¡}t|d d… dƒt|dd … dƒgS d S )Nr   i   r7   r   é   )r   r8   Ú
isinstanceÚintr;   r<   r=   )r?   r@   rA   rB   Ztwo_complementr)   r)   r*   Úpcom_binary_checksum�   s    
zPCOMBinary.pcom_binary_checksumc                 C   sœ   | j d u rJt |d d… ¡}|d d… t d|d |d ¡ |dd …  }| jd u r”t |dd… ¡}|d d… t d|d |d ¡ |dd …  }|| S )	Né   é   rc   rF   r   é   rb   rd   )ÚheaderChksumÚPCOMBinaryRequestrn   r$   r%   ÚfooterChksumrf   r)   r)   r*   r+   ª   s    
.
.zPCOMBinary.post_buildN)r,   r-   r.   rD   rn   r+   r)   r)   r)   r*   rj   œ   s   
rj   c                       s   e Zd Z‡ fdd„Z‡  ZS )ÚPCOMBinaryCommandFieldc                    s2   t t| ƒ ||¡}|tv r*t| d | S |S d S )Nz - )rI   ru   rJ   Ú_binary_command_codes)r&   r'   rL   rM   rO   r)   r*   rJ   µ   s    zPCOMBinaryCommandField.i2reprrQ   r)   r)   rO   r*   ru   ´   s   ru   c                   @   sŒ   e Zd ZdZedddƒeddƒeddƒed	d
ƒeddƒeddƒeddƒedddƒedddd�e	ddƒe
dddd„ d�e	ddƒeddƒgZdS )rs   zPCOM/Binary RequestrT   ú/_OPLCrY   Úidr   Ú	reserved1éþ   Ú	reserved2rF   Ú	reserved3r?   NÚ	reserved4ÚcommandSpecificrX   r"   Údata©Z	length_ofrr   c                 C   s   | j S ©N©r"   r[   r)   r)   r*   r\   Ê   r]   zPCOMBinaryRequest.<lambda>r^   rt   r`   é\   ©r,   r-   r.   r3   r   r   r   ru   r   r   r	   r0   r)   r)   r)   r*   rs   ½   s   

órs   c                   @   sŒ   e Zd ZdZedddƒeddƒeddƒed	d
ƒeddƒeddƒeddƒedddƒedddd�e	ddƒe
dddd„ d�e	ddƒeddƒgZdS )ÚPCOMBinaryResponsezPCOM/Binary ResponserT   rw   rY   ry   rz   rx   r   r{   rF   r|   r?   Nr}   r~   rX   r"   r   r€   rr   c                 C   s   | j S r�   r‚   r[   r)   r)   r*   r\   Ý   r]   zPCOMBinaryResponse.<lambda>r^   rt   r`   rƒ   r„   r)   r)   r)   r*   r…   Ð   s   

ór…   i O  )Údport)Zsportr   )r    r   )$Ú__doc__r$   Zscapy.packetr   r   Zscapy.layers.inetr   Zscapy.fieldsr   r   r   r   r	   r
   r   r   r   Zscapy.volatiler   Zscapy.compatr   r   r/   rK   rv   r   r1   r4   r5   rE   rS   rh   rj   ru   rs   r…   r)   r)   r)   r*   Ú<module>	   s‚   	,
á#ø
	