a
    kÄ#dcQ  ã                €   @   sÂ  d Z ddlT ddlT ddlT ddlmZ ddlmZ ddlm	Z	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mZ d	ZdZeZd
ZeZedediZ dZ!d
Z"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5d Z6d!Z7d"Z8d#Z9d$Z:d%Z;d&Z<d'Z=d(Z>d)Z?d*Z@d+ZAd,ZBd-ZCd.ZDd/ZEd0ZFd1ZGd2ZHd3ZId4ZJd5ZKd6ZLd7ZMd8ZNd9ZOd:ZPd;ZQd<ZRd=ZSd>ZTd?ZUd@ZVdAZWdBZXdCZYdDZZdEZ[dFZ\dGZ]dHZ^dIZ_dJZ`e!dKe"dLe#dMe$dNe%dOe&dPe'dQe(dRe)dSe*dTe+dUe,dVe-dWe.dXe/dYe0dZe1d[e2d\e3d]e4d^e5d_e6d`e7dae8dbe9dce:dde;dee<dfe=dge>dhe?die@djeAdkeBdleCdmeDdneEdoeFdpeGdqeHdreIdseJdteKdueLdveMdweNdxeOdyePdzeQd{eRd|eSd}eTd~eUdeVd€eWd�eXd‚eYdƒeZd„e[d…e\d†e]d‡e^dˆe_d‰e`dŠi@ZadZbd
ZcdZddZedZfd‹dŒ„ ZgG d�dŽ„ dŽeƒZhG d�d�„ d�ehƒZiG d‘d’„ d’ehƒZjd“d”„ Zkd•d–„ ZlG d—d˜„ d˜eƒZmG d™dš„ dše
ƒZnG d›dœ„ dœehƒZoG d�dž„ džeoƒZpG dŸd „ d eoƒZqebejrecepedeqeeejefeiiZsd¡d¢„ Ztd£d¤„ Zud¥d¦„ Zvd§d¨„ Zwd©dª„ Zxeeehed«� eeehed¬� d­S )®a>  
    IEC 60870-5-104
    ~~~~~~~~~~~~~~~

    :description:

        This module provides the IEC 60870-5-104 (common short name: iec104)
        layer, the information objects and related information element
        definitions.

        normative references:
            - IEC 60870-5-4:1994 (atomic base types / data format)
            - IEC 60870-5-101:2003 (information elements (sec. 7.2.6) and
              ASDU definition (sec. 7.3))
            - IEC 60870-5-104:2006 (information element TSC (sec. 8.8, p. 44))

    :TODO:
        - add allowed direction to IO attributes
          (but this could be derived from the name easily <--> )
        - information elements / objects need more testing
          (e.g. on live traffic w comparison against tshark)

    :NOTES:
        - bit and octet numbering is used as in the related standards
          (they usually start with index one instead of zero)
        - some of the information objects are only valid for IEC 60870-5-101 -
          so usually they should never appear on the network as iec101 uses
          serial connections. I added them if decoding of those messages is
          needed cause one goes to implement a iec101<-->iec104 gateway or
          hits such a gateway that acts not standard conform (e.g. by
          forwarding 101 messages to a 104 network)
é    )Ú*)Úorb)Úconf)ÚwarningÚScapy_Exception)	Ú	ByteFieldÚBitFieldÚByteEnumFieldÚPacketListFieldÚBitEnumFieldÚ
XByteFieldÚFieldLenFieldÚLEShortFieldÚBitFieldLenField)ÚTCP)ÚRawÚPacketÚbind_layersid	  é   z"monitor direction (sub -> central)z"control direction (central -> sub)é   é   é   é   é   é   é   é	   é
   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é    é!   é"   é#   é$   é%   é&   é'   é(   é)   é*   é+   é,   é-   é.   é/   é0   é1   é2   é3   é4   é5   é6   é7   é8   é9   é:   é;   é<   é=   é>   é?   Ú	undefinedzcyclic (per/cyc)zbackground (back)zspontaneous (spont)zinitialized (init)zrequest (req)zactivation (act)zactivation confirmed (actcon)zactivation canceled (deact)z,activation cancellation confirmed (deactcon)zactivation finished (actterm)z*feedback caused by remote command (retrem)z)feedback caused by local command (retloc)zfile transfer (file)Zreserved_14Zreserved_15Zreserved_16Zreserved_17Zreserved_18Zreserved_19zqueried by station (inrogen)z#queried by query to group 1 (inro1)z#queried by query to group 2 (inro2)z#queried by query to group 3 (inro3)z#queried by query to group 4 (inro4)z#queried by query to group 5 (inro5)z#queried by query to group 6 (inro6)z#queried by query to group 7 (inro7)z#queried by query to group 8 (inro8)z#queried by query to group 9 (inro9)z%queried by query to group 10 (inro10)z%queried by query to group 11 (inro11)z%queried by query to group 12 (inro12)z%queried by query to group 13 (inro13)z%queried by query to group 14 (inro14)z%queried by query to group 15 (inro15)z%queried by query to group 16 (inro16)z3queried by counter general interrogation (reqcogen)z,queried by query to counter group 1 (reqco1)z,queried by query to counter group 2 (reqco2)z,queried by query to counter group 3 (reqco3)z,queried by query to counter group 4 (reqco4)Zreserved_42Zreserved_43zunknown type codezunknown transmit reasonzunknown common address of ASDUz%unknown address of information objectZ
private_48Z
private_49Z
private_50Z
private_51Z
private_52Z
private_53Z
private_54Z
private_55Z
private_56Z
private_57Z
private_58Z
private_59Z
private_60Z
private_61Z
private_62Z
private_63c                 C   s¬   t | d ƒ}t | d ƒ}t|d@ ƒ}t|d@ ƒ}t|d@ ƒ}|du r||du r|t| ƒdk r\tS t | d ƒd@ dk}|rxtS tS |r”|du r”|du r”tS |r¨|r¨|du r¨tS tS )aI  
    the type of the message is encoded in octet 1..4

                 oct 1, bit 1   2       oct 3, bit 1
    I Message               0  1|0                 0
    S Message               1   0                  0
    U Message               1   1                  0


    see EN 60870-5-104:2006, sec. 5 (p. 13, fig. 6,7,8)
    r   r   r   Fr   r   é€   )r   ÚboolÚlenÚIEC104_APDU_TYPE_UNKNOWNÚIEC104_APDU_TYPE_I_SEQ_IOAÚIEC104_APDU_TYPE_I_SINGLE_IOAÚIEC104_APDU_TYPE_SÚIEC104_APDU_TYPE_U)ÚdataZoct_1Zoct_3Zoct_1_bit_1Zoct_1_bit_2Zoct_3_bit_1Z
is_seq_ioa© r]   úZ/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/contrib/scada/iec104/__init__.pyÚ_iec104_apci_type_from_packetÓ   s"    r_   c                   @   s&   e Zd ZdZdd„ Zeddd„ƒZdS )ÚIEC104_APDUzP
    basic Application Protocol Data Unit definition used by S/U/I messages
    c                 C   s€   t |ƒ}|dk r|  |¡S t|d ƒdkr4|  |¡ dt|d ƒ }||k rftd ||¡ƒ |  |¡S t|ƒ}t ||  |¡¡S )Nr   r   éh   r   r   z4invalid len of APDU. given len: {} available len: {})rV   Zdefault_payload_classr   r   Úformatr_   ÚIEC104_APDU_CLASSESÚget)ÚselfÚpayloadZpayload_lenÚapdu_lengthZ	apdu_typer]   r]   r^   Úguess_payload_class   s"    

ÿÿ
ÿzIEC104_APDU.guess_payload_classNc                 O   s4   t |ƒrtS t|ƒrtS t|ƒr$tS t|ƒr0tS tS )z÷
        detect type of the message by checking packet data
        :param _pkt: raw bytes of the packet layer data to be checked
        :param args: unused
        :param kargs: unused
        :return: class of the detected message type
        )	Ú_iec104_is_i_apdu_seq_ioaÚIEC104_I_Message_SeqIOAÚ_iec104_is_i_apdu_single_ioaÚIEC104_I_Message_SingleIOAÚ_iec104_is_u_apduÚIEC104_U_MessageÚ_iec104_is_s_apduÚIEC104_S_Messager   )ÚclsÚ_pktÚargsZkargsr]   r]   r^   Údispatch_hook  s    
zIEC104_APDU.dispatch_hook)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rh   Úclassmethodrt   r]   r]   r]   r^   r`   û   s   r`   c                   @   s@   e Zd ZdZdZeddƒeddƒeddƒed	d
ƒedd
ƒgZdS )rp   z5
    message used for ack of received I-messages
    zIEC-104 S APDUÚstartra   rg   r   Zoctet_1r   Úoctet_2r   Ú
rx_seq_numN)	ru   rv   rw   rx   Únamer   r   ÚIEC104SequenceNumberÚfields_descr]   r]   r]   r^   rp   2  s   ùrp   c                   @   s†   e Zd ZdZdZeddƒeddƒeddd	ƒed
dd	ƒeddd	ƒeddd	ƒeddd	ƒeddd	ƒedddƒeddƒeddƒeddƒgZdS )rn   zT
    message used for connection tx control (start/stop)  and monitoring (test)
    zIEC-104 U APDUrz   ra   rg   r   Z
testfr_conr   r   Z
testfr_actZ
stopdt_conZ
stopdt_actZstartdt_conZstartdt_actZoctet_1_1_2r   r   r{   Zoctet_3Zoctet_4N)	ru   rv   rw   rx   r}   r   r   r   r   r]   r]   r]   r^   rn   C  s   






ñrn   c                 C   s   t  | jtj¡}||ƒS )z?
    get the type id and return the matching ASDU instance
    )ZIEC104_IO_CLASSESrd   Útype_idr   Ú	raw_layer©ÚpktZnext_layer_dataZnext_layer_class_typer]   r]   r^   Ú_i_msg_io_dispatcher_sequence\  s    r„   c                 C   s   t  | jtj¡}||ƒS )z‰
    get the type id and return the matching ASDU instance
    (information object address + regular ASDU information object fields)
    )ZIEC104_IO_WITH_IOA_CLASSESrd   r€   r   r�   r‚   r]   r]   r^   Ú_i_msg_io_dispatcher_singlee  s    ÿr…   c                   @   s   e Zd ZdZdd„ ZdS )ÚIEC104ASDUPacketListFieldzC
    used to add a list of information objects to an I-message
    c                 C   s   |   ||¡S )zã
        add calling layer instance to the cls()-signature
        :param pkt: calling layer instance
        :param m: raw data forming the next layer
        :return: instance of the class representing the next layer
        )rq   )re   rƒ   Úmr]   r]   r^   Úm2it  s    zIEC104ASDUPacketListField.m2iN)ru   rv   rw   rx   rˆ   r]   r]   r]   r^   r†   p  s   r†   c                   @   s   e Zd ZdZdS )Ú#IEC104_I_Message_StructureExceptionzG
    Exception raised if payload is not of type Information Object
    N)ru   rv   rw   rx   r]   r]   r]   r^   r‰   ~  s   r‰   c                       sr   e Zd ZdZdZdZdZdZedediZdZ	dZ
e	de
d	iZdZdZed
ediZg Zd‡ fdd„	Zdd„ Z‡  ZS )ÚIEC104_I_Messagea2  
    message used for transmitting data (APDU - Application Protocol Data Unit)

    APDU: MAGIC + APCI + ASDU
    MAGIC: 0x68
    APCI : Control Information (rx/tx seq/ack numbers)
    ASDU : Application Service Data Unit - information object related data

    see EN 60870-5-104:2006, sec. 5 (p. 12)
    zIEC-104 I APDUra   r   r   ÚsingleÚsequenceÚdisabledÚenabledZpositiveÚnegativeó    Nc                    sB   t t| ƒjf ||||dœ|¤Ž d|v r>|d r>|  |d ¡ d S )N)rr   Úpost_transformÚ	_internalÚ_underlayerÚio)ÚsuperrŠ   Ú__init__Ú_information_object_update)re   rr   r‘   r’   r“   Úfields©Ú	__class__r]   r^   r–   ®  s    ýüzIEC104_I_Message.__init__c                 C   sn   t |tƒs|g}|d }|j}t|tƒs0tdƒ‚| ¡ | _|dd… D ]"}|j|krFtd |j	|j	¡ƒ‚qFdS )zµ
        set the type_id in the ASDU header based on the given information
        object (io) and check for valid structure
        :param io_instances: information object
        r   zAinformation object payload must be a subclass of IEC104_IO_Packetr   Nzeeach information object within the ASDU must be of the same class type (first io: {}, current io: {}))
Ú
isinstanceÚlistrš   Ú
issubclassZIEC104_IO_Packetr‰   Ziec104_io_type_idr€   rb   Ú_name)re   Zio_instancesZfirst_ioZfirst_io_classZio_instr]   r]   r^   r—   º  s"    

ÿ

ýÿz+IEC104_I_Message._information_object_update)r�   Nr   N)ru   rv   rw   rx   r}   ÚIEC_104_MAGICÚSQ_FLAG_SINGLEÚSQ_FLAG_SEQUENCEÚSQ_FLAGSZTEST_DISABLEDZTEST_ENABLEDÚ
TEST_FLAGSZACK_POSITIVEZACK_NEGATIVEÚ	ACK_FLAGSr   r–   r—   Ú__classcell__r]   r]   r™   r^   rŠ   …  s.   
þþþ  ÿrŠ   c                   @   sÌ   e Zd ZdZdZedejƒedddddd	„ d
�e	ddƒe	ddƒe
ddeƒedejdejƒeddddd�edddejƒedddejƒedddeƒeddƒeddƒeddƒede ¡ edd	„ d�gZdd„ ZdS )rj   zŠ
    all information objects share a base information object address field

    sq = 1, see EN 60870-5-101:2003, sec. 7.2.2.1 (p. 33)
    zIEC-104 I APDU (Seq IOA)rz   rg   Nú!Br”   c                 C   s   |d S ©Nr    r]   ©rƒ   Úxr]   r]   r^   Ú<lambda>ä  r�   z IEC104_I_Message_SeqIOA.<lambda>©ÚfmtZ	length_ofÚadjustÚ
tx_seq_numr   r|   r€   Úsqr   Únum_ior   ©Zcount_ofÚtestÚackÚcotr   Úorigin_addressÚcommon_asdu_addressZinformation_object_addressc                 C   s
   | j d S r§   ©rg   ©rƒ   r]   r]   r^   rª   ý  r�   ©Zlength_fromc                 C   s$   | j tkr t| dtƒ g| j ƒ |S )Nr”   )r€   ZIEC104_IO_ID_C_RD_NA_1ÚsetattrZIEC104_IO_C_RD_NA_1r°   )re   Úsr]   r]   r^   Úpost_dissect   s    
z$IEC104_I_Message_SeqIOA.post_dissect)ru   rv   rw   rx   r}   r   rŠ   rŸ   r   r~   r	   ÚIEC104_IO_NAMESr   r¡   r¢   r   r£   r¤   ÚCAUSE_OF_TRANSMISSIONSr   r   ZLEThreeBytesFieldr†   r   r�   r„   r   r¼   r]   r]   r]   r^   rj   Ø  s4   

ÿ

ÿýæ rj   c                   @   s¼   e Zd ZdZdZedejƒedddddd	„ d
�e	ddƒe	ddƒe
ddeƒedejdejƒeddddd�edddejƒedddejƒedddeƒeddƒeddƒede ¡ edd	„ d�gZdS )rl   z™
    every information object contains an individual information object
    address field

    sq = 0, see EN 60870-5-101:2003, sec. 7.2.2.1 (p. 33)
    zIEC-104 I APDU (single IOA)rz   rg   Nr¦   r”   c                 C   s   |d S ©Nr   r]   r¨   r]   r]   r^   rª     r�   z#IEC104_I_Message_SingleIOA.<lambda>r«   r®   r   r|   r€   r¯   r   r°   r   r±   r²   r³   r´   r   rµ   r¶   c                 C   s
   | j d S r¿   r·   r¸   r]   r]   r^   rª   0  r�   r¹   )ru   rv   rw   rx   r}   r   rŠ   rŸ   r   r~   r	   r½   r   r    r¢   r   r£   r¤   r¾   r   r   r†   r   r�   r…   r   r]   r]   r]   r^   rl     s0   

ÿ

ÿýèrl   c                 C   sP   t | ƒ}|dk rdS t| d ƒdks@t| d ƒd |ks@|dk rDdS tt| ƒkS ©Nr   Fr   ra   r   r   r   )rV   r   rX   r_   ©rf   Zlen_payloadr]   r]   r^   ri   =  s    ÿÿri   c                 C   sP   t | ƒ}|dk rdS t| d ƒdks@t| d ƒd |ks@|dk rDdS tt| ƒkS rÀ   )rV   r   rY   r_   rÁ   r]   r]   r^   rk   I  s    ÿÿÿrk   c                 C   s@   t | ƒdk rdS t| d ƒdks0t| d ƒdkr4dS tt| ƒkS ©Nr   Fr   ra   r   r   )rV   r   r[   r_   ©rf   r]   r]   r^   rm   V  s
     rm   c                 C   s@   t | ƒdk rdS t| d ƒdks0t| d ƒdkr4dS tt| ƒkS rÂ   )rV   r   rZ   r_   rÃ   r]   r]   r^   ro   `  s
     ro   c                 C   sN   t | ƒrt| ƒS t| ƒr t| ƒS t| ƒr0t| ƒS t| ƒr@t| ƒS t 	| ¡S dS )zÆ
    can be used to dissect payload of a TCP connection
    :param payload: the application layer data (IEC104-APDU(s))
    :return: iec104 (I/U/S) message instance, conf.raw_layer() if unknown
    N)
ri   rj   rk   rl   ro   rp   rm   rn   r   r�   rÃ   r]   r]   r^   Úiec104_decodej  s    rÄ   )Zsport)ÚdportN)yrx   Z(scapy.contrib.scada.iec104.iec104_fieldsZ6scapy.contrib.scada.iec104.iec104_information_elementsZ5scapy.contrib.scada.iec104.iec104_information_objectsZscapy.compatr   Zscapy.configr   Zscapy.errorr   r   Zscapy.fieldsr   r   r	   r
   r   r   r   r   r   Zscapy.layers.inetr   Zscapy.packetr   r   r   ZIEC_104_IANA_PORTZIEC104_CONTROL_DIRECTIONZIEC104_CENTRAL_2_SUB_DIRZIEC104_MONITOR_DIRECTIONZIEC104_SUB_2_CENTRAL_DIRZIEC104_DIRECTIONSZIEC104_COT_UNDEFINEDZIEC104_COT_CYCZIEC104_COT_BACKZIEC104_COT_SPONTZIEC104_COT_INITZIEC104_COT_REQZIEC104_COT_ACTZIEC104_COT_ACTCONZIEC104_COT_DEACTZIEC104_COT_DEACTCONZIEC104_COT_ACTTERMZIEC104_COT_RETREMZIEC104_COT_RETLOCZIEC104_COT_FILEZIEC104_COT_RESERVED_14ZIEC104_COT_RESERVED_15ZIEC104_COT_RESERVED_16ZIEC104_COT_RESERVED_17ZIEC104_COT_RESERVED_18ZIEC104_COT_RESERVED_19ZIEC104_COT_INROGENZIEC104_COT_INRO1ZIEC104_COT_INRO2ZIEC104_COT_INRO3ZIEC104_COT_INRO4ZIEC104_COT_INRO5ZIEC104_COT_INRO6ZIEC104_COT_INRO7ZIEC104_COT_INRO8ZIEC104_COT_INRO9ZIEC104_COT_INRO10ZIEC104_COT_INRO11ZIEC104_COT_INRO12ZIEC104_COT_INRO13ZIEC104_COT_INRO14ZIEC104_COT_INRO15ZIEC104_COT_INRO16ZIEC104_COT_REQCOGENZIEC104_COT_REQCO1ZIEC104_COT_REQCO2ZIEC104_COT_REQCO3ZIEC104_COT_REQCO4ZIEC104_COT_RESERVED_42ZIEC104_COT_RESERVED_43ZIEC104_COT_UNKNOWN_TYPE_CODEZ"IEC104_COT_UNKNOWN_TRANSMIT_REASONZ)IEC104_COT_UNKNOWN_COMMON_ADDRESS_OF_ASDUZ0IEC104_COT_UNKNOWN_ADDRESS_OF_INFORMATION_OBJECTZIEC104_COT_PRIVATE_48ZIEC104_COT_PRIVATE_49ZIEC104_COT_PRIVATE_50ZIEC104_COT_PRIVATE_51ZIEC104_COT_PRIVATE_52ZIEC104_COT_PRIVATE_53ZIEC104_COT_PRIVATE_54ZIEC104_COT_PRIVATE_55ZIEC104_COT_PRIVATE_56ZIEC104_COT_PRIVATE_57ZIEC104_COT_PRIVATE_58ZIEC104_COT_PRIVATE_59ZIEC104_COT_PRIVATE_60ZIEC104_COT_PRIVATE_61ZIEC104_COT_PRIVATE_62ZIEC104_COT_PRIVATE_63r¾   rW   rX   rY   r[   rZ   r_   r`   rp   rn   r„   r…   r†   r‰   rŠ   rj   rl   r�   rc   ri   rk   rm   ro   rÄ   r]   r]   r]   r^   Ú<module>	   sb  !,þ¾E(7	S4)û	

