
    hc.                     4   d dl 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 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 d	d
dddddddddddddZd Zd Z G d de          Z e	eed            e	eed           i ej        d<    G d  d!e          Z  G d" d#e          Z! G d$ d%e          Z"g d&Z#g d'Z$ G d( d)e          Z% G d* d+e%          Z& G d, d-e%          Z' G d. d/e          Z( G d0 d1e(          Z) G d2 d3e(          Z*dS )4    N)rawScapy_Exception)conf)Packetbind_layers)Ether)UDP)XShortEnumFieldBitEnumField	XBitFieldBitFieldStrFieldPacketListFieldStrFixedLenField
ShortField
FlagsField	ByteField	XIntFieldX3BytesFieldzPTCP-RTSyncPDU-followupzPTCP-RTSyncPDUz
Alarm Highz	Alarm LowzDCP-Hello-ReqzDCP-Get-SetzDCP-Identify-ReqPDUzDCP-Identify-ResPDUzPTCP-AnnouncePDUzPTCP-FollowUpPDUzPTCP-DelayReqPDUzPTCP-DelayResPDU-followupzPTCP-DelayFuResPDUzPTCP-DelayResPDU)           i        i   i   i@  iA  iB  iC  c                     	 t           |          S # t          $ r Y nw xY wd| cxk    rdk     rn nd| z  S d| cxk    rdk     rn nd| z  S d| cxk    rdk     rn nd| z  S d	| cxk    rd
k     rn nd| z  S | S )zx Get representation name of a pnio frame ID

    :param x: a key of the PNIO_FRAME_IDS dictionary
    :returns: str
          zRT_CLASS_3 (%4x)      zRT_CLASS_1 (%4x)   zRT_CLASS_UDP (%4x)  i  zFragmentationFrameID (%4x))PNIO_FRAME_IDSKeyErrorxs    V/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/scapy/contrib/pnio.pyi2s_frameidr*   (   s    a     V!A%%V!A%%V#a''V+a//Hs    
c                      	 ddddd          S # t           $ r Y nw xY w	 t           fdt                                          D                       S # t          $ r Y nw xY w S )z Get pnio frame ID from a representation name

    Performs a reverse look-up in PNIO_FRAME_IDS dictionary

    :param x: a value of PNIO_FRAME_IDS dict
    :returns: integer
    r   r!   r"   r$   )
RT_CLASS_3
RT_CLASS_1RT_CLASS_UDPFragmentationFrameIDc              3   .   K   | ]\  }}|k    |V  d S N ).0keyvaluer(   s      r)   	<genexpr>zs2i_frameid.<locals>.<genexpr>O   s8       # #JCzz !zzz# #    )r&   nextr%   itemsStopIterationr'   s   `r)   s2i_frameidr;   =   s      "$*	
 

  	     # # # #.*>*>*@*@ # # # # # 	#   Hs    
1A 
A A c                   B     e Zd ZdZ eddeef          gZ fdZ xZ	S )
ProfinetIOz Basic PROFINET IO dispatcher frameIDr   c                 "   | j         dv rddlm} |S | j         dk    rddlm} |S | j         dk    rddlm} |S d| j         cxk    rd	k     sn d
| j         cxk    rdk     r
n nt          S t          t          |           	                    |          S )N)r   r   r   r   )ProfinetDCPr   )	Alarm_Lowr   )
Alarm_Highr   r    r!   r#   )
r>   scapy.contrib.pnio_dcpr@   scapy.contrib.pnio_rpcrA   rB   PNIORealTimeCyclicPDUsuperr=   guess_payload_class)selfpayloadr@   rA   rB   	__class__s        r)   rG   zProfinetIO.guess_payload_class`   s    <333::::::\V##888888\V##9999994<0000&00004<0000&00000 )(Z&&::7CCCr7   )
__name__
__module____qualname____doc__r   r*   r;   fields_descrG   __classcell__)rJ   s   @r)   r=   r=   Z   sd        ((	1{K&@AAKD D D D D D D D Dr7   r=   i  )type)dportPNIO_RTCc                       e Zd ZdZdZ edddddg           eddd	g d
           eddd           eddd          gZe	d             Z
e	d             Zd ZdS )PNIORealTime_IOxSz6 IOCS and IOPS packets for PROFINET Real-Time payload zPNIO RTC IOxS	dataState   badgoodinstancer      )subslotslotdevice
controllerreserved   	extensionc                 ^    t          |t          d                     s|j        dk    r| nd }|S Nr   )
isinstancerQ   rb   )cls_pkt_lstp_remainrets         r)   is_extension_setz"PNIORealTime_IOxS.is_extension_set   s1    4::..L!+2B2Bcc
r7   c                 >    t          d | j        D                       S )Nc              3   \   K   | ]'}t          |                              d d          V  (d S rd   )rQ   i2len)r3   flds     r)   r6   z,PNIORealTime_IOxS.get_len.<locals>.<genexpr>   s6      GG499??4++GGGGGGr7   )sumrO   )rf   s    r)   get_lenzPNIORealTime_IOxS.get_len   s!    GGsGGGGGGr7   c                     t           j        S r1   r   padding_layerrH   ri   s     r)   rG   z%PNIORealTime_IOxS.guess_payload_class       !!r7   N)rK   rL   rM   rN   namer   r   r   rO   classmethodrl   rr   rG   r2   r7   r)   rU   rU      s        @@D 	[!Q88ZA@@@	B 	B 		*a##a##
K   [ H H [H" " " " "r7   rU   c                   6    e Zd ZdZ eddd          gZd ZdS ) PNIORealTimeCyclicDefaultRawDataz-PROFINET IO Real Time Cyclic Default Raw Datadata ra   )remainc                     t           j        S r1   rt   )rH   rI   s     r)   rG   z4PNIORealTimeCyclicDefaultRawData.guess_payload_class   rw   r7   N)rK   rL   rM   rx   r   rO   rG   r2   r7   r)   r{   r{      sE        :D 	A&&&K" " " " "r7   r{   c            
           e Zd ZdZddgZdZ edg d            edd	d
            edd           e	dddg d           e
dd          gZd Zd Zd Zed             Zed             ZdS )rE   z PROFINET cyclic real-time _len_layoutzPROFINET Real-Timer|   c                 0    |                      |||          S r1   next_cls_cb)pktlstri   r~   s       r)   <lambda>zPNIORealTimeCyclicPDU.<lambda>   s    COOQ5  5  r7   r   paddingr}   c                 *    |                                  S r1   )get_padding_lengthri   s    r)   r   zPNIORealTimeCyclicPDU.<lambda>   s    q/C/C/E/E r7   length_fromcycleCounterr   
dataStatus5      )primary
redundancy	validData
reserved_1run
no_problem
reserved_2ignoretransferStatusc                 J    t          dt          |                    | _        |S )Ni  )minlenr   )rH   ss     r)   pre_dissectz!PNIORealTimeCyclicPDU.pre_dissect   s    c!ff%%	r7   c                    t          | d          r>| j        t          d |                     d          D                       z
  dz
  dz
  dz
  }n"t	          |                     d                    }d|cxk    rdk    sn J | }t          |t                    s<t          |d	          r,|j        }t          |t                    st          |d	          ,t          |t                    rd|cxk    rd
k    sn J |S )Nr   c              3   N   K   | ] }t          t          |                    V  !d S r1   )r   r   )r3   r   s     r)   r6   z;PNIORealTimeCyclicPDU.get_padding_length.<locals>.<genexpr>   s.      FFcCCMMFFFFFFr7   r|   r[   rW   r   r   (   
underlayer   )hasattrr   rq   getfieldvalr   re   r
   r   )rH   pad_lenqs      r)   r   z(PNIORealTimeCyclicPDU.get_padding_length   s>   4   		7	FFT-=-=f-E-EFFFFFG  	 G $**95566G G!!!!r!!!!!!Q$$ 	L)A)A 	A Q$$ 	L)A)A 	a 	&%%%%2%%%%%%r7   c                 p   t          | d          rMt          | j        t                    r3	 | j                            d          S # t
          $ r d | _        Y d S w xY wd }| }t          |t                    s<t          |d          r,|j        }t          |t                    st          |d          ,t          |t                    r|}d }| }t          |t                    s<t          |d          r,|j        }t          |t                    st          |d          ,t          |t                    r|}t          g| _        ||Wt          |                               |j        |j        |j                  }t          |t          d                     s|| _        | j                            d          S )Nr   r   r   )r   re   r   listpop
IndexErrorr	   r   r=   r{   rQ   get_layout_from_configsrcdstr>   )rH   rh   _prj   ether_layerr   
pnio_layerlayouts           r)   r   z!PNIORealTimeCyclicPDU.next_cls_cb   s   4## 	
4<(F(F 	|''***   #tt Q&& 	71l+C+C 	A Q&& 	71l+C+C 	a 	K
Q
++ 	<0H0H 	A Q
++ 	<0H0H 	a$$ 	J89#
(:$ZZ66"$ $F fd4jj11 &%|"""s   A AAc                     	 t          j        t          j        d         | ||f                   S # t          $ r Y d S w xY w)NrS   )copydeepcopyr   contribsr&   )	ether_src	ether_dstframe_ids      r)   r   z,PNIORealTimeCyclicPDU.get_layout_from_config  sU    	=j)9i*JK    	 	 	44	s   ,/ 
==c           
           t          d                               t          j        fd                               t	          dd           g fdd d          S )NzFixedLenRawPacketLen{}r|   r}   lengthc                     S r1   r2   )_r   s    r)   r   z@PNIORealTimeCyclicPDU.build_fixed_len_raw_type.<locals>.<lambda>  s    V r7   c                     t           j        S r1   rt   rv   s     r)   r   z@PNIORealTimeCyclicPDU.build_fixed_len_raw_type.<locals>.<lambda>  s	    t7I r7   )rx   rO   get_data_lengthrG   )rQ   formatr   	raw_layerr   r   s   `r)   build_fixed_len_raw_typez.PNIORealTimeCyclicPDU.build_fixed_len_raw_type  sp    $++F33^077?? 0F K K KL#3#3#3#3'I'I	 	
 	
 		
r7   N)rK   rL   rM   rN   	__slots__rx   r   r   r   r   r   rO   r   r   r   staticmethodr   r   r2   r7   r)   rE   rE      s$       %%#ID 	B   	
 	
 	
 	B%E%E	G 	G 	G 	
>1%%
<q 	+
 	+
 	+
 		 		 		"A&&-K2  
  * #  #  #D   \ 

 

 \

 

 

r7   rE   )iPar_ENOA_Req	R_cons_nrUse_TO2activate_FVToggle_hChF_Ack	Loopcheck)iPar_OKzDevice_Fault/ChF_Ack_ReqCE_CRC
WD_timeoutFV_activatedToggle_d	cons_nr_Rr`   c                   L    e Zd Zdgej        z   Zd Zd Zd Zed             Z	dS )PROFIsafeCRCSeedr   c                     t           j        S r1   rt   rv   s     r)   rG   z$PROFIsafeCRCSeed.guess_payload_class(  rw   r7   c                      t          d          z> Must be overridden in a subclass to return the correct value z5This method must be overridden in a specific subclassr   rH   s    r)   r   z PROFIsafeCRCSeed.get_data_length+      C
 
 	
r7   c                     dS )N   r2   r   s    r)   get_mandatory_fields_lenz)PROFIsafeCRCSeed.get_mandatory_fields_len1      qr7   c                      dS )N   r2   r2   r7   r)   get_max_data_lengthz$PROFIsafeCRCSeed.get_max_data_length5  	     rr7   N)
rK   rL   rM   r   r   rG   r   r   r   r   r2   r7   r)   r   r   %  sk        6++I" " "
 
 
     \  r7   r   c                   b    e Zd ZdZ eddd            eddde           ed	d          gZd
S )PROFIsafeControlCRCSeedz+PROFISafe Control Message with F_CRC_Seed=1r|   r}   c                 *    |                                  S r1   r   r   s    r)   r   z PROFIsafeControlCRCSeed.<lambda>?      q/@/@/B/B r7   r   controlr   r   crcN)	rK   rL   rM   rx   r   r   profisafe_control_flagsr   rO   r2   r7   r)   r   r   ;  s_        8D%B%B	D 	D 	D
9a$;<<	%	KKKr7   r   c                   b    e Zd ZdZ eddd            eddde           ed	d          gZd
S )PROFIsafeStatusCRCSeedz*PROFISafe Status Message with F_CRC_Seed=1r|   r}   c                 *    |                                  S r1   r   r   s    r)   r   zPROFIsafeStatusCRCSeed.<lambda>I  r   r7   r   statusr   r   r   N)	rK   rL   rM   rx   r   r   profisafe_status_flagsr   rO   r2   r7   r)   r   r   E  s_        7D%B%B	D 	D 	D
8Q#9::	%	KKKr7   r   c                   b    e Zd Zdgej        z   Zd Zd Zd Zed             Z	ed             Z
dS )	PROFIsafer   c                     t           j        S r1   rt   rv   s     r)   rG   zPROFIsafe.guess_payload_classR  rw   r7   c                      t          d          r   r   r   s    r)   r   zPROFIsafe.get_data_lengthU  r   r7   c                     dS )Nra   r2   r   s    r)   r   z"PROFIsafe.get_mandatory_fields_len[  r   r7   c                      dS )Nr   r2   r2   r7   r)   r   zPROFIsafe.get_max_data_length_  r   r7   c                     |                                  k    sJ t          d                    | j                  | fdfdi          S )Nz{}Len{}r   c                     S r1   r2   )r   data_lengths    r)   r   z1PROFIsafe.build_PROFIsafe_class.<locals>.<lambda>k  s    [ r7   )r   rQ   r   rK   )rf   r   s    `r)   build_PROFIsafe_classzPROFIsafe.build_PROFIsafe_classd  s`    &&((K7777S\;77F!#8#8#8#8
 
 	
r7   N)rK   rL   rM   r   r   rG   r   r   r   r   r   r2   r7   r)   r   r   O  s        6++I" " "
 
 
     \ 
 
 \
 
 
r7   r   c                   b    e Zd ZdZ eddd            eddde           ed	d          gZd
S )PROFIsafeControlz+PROFISafe Control Message with F_CRC_Seed=0r|   r}   c                 *    |                                  S r1   r   r   s    r)   r   zPROFIsafeControl.<lambda>t  r   r7   r   r   r   r   r   N)	rK   rL   rM   rx   r   r   r   r   rO   r2   r7   r)   r   r   p  s_        8D%B%B	D 	D 	D
9a$;<<UA	KKKr7   r   c                   b    e Zd ZdZ eddd            eddde           ed	d          gZd
S )PROFIsafeStatusz*PROFISafe Status Message with F_CRC_Seed=0r|   r}   c                 *    |                                  S r1   r   r   s    r)   r   zPROFIsafeStatus.<lambda>~  r   r7   r   r   r   r   r   N)	rK   rL   rM   rx   r   r   r   r   rO   r2   r7   r)   r   r   z  s_        7D%B%B	D 	D 	D
8Q#9::UA	KKKr7   r   )+r   scapy.compatr   scapy.errorr   scapy.configr   scapy.packetr   r   scapy.layers.l2r	   scapy.layers.inetr
   scapy.fieldsr   r   r   r   r   r   r   r   r   r   r   r   r%   r*   r;   r=   r   rU   r{   rE   r   r   r   r   r   r   r   r   r2   r7   r)   <module>r	     s          ' ' ' ' ' '       , , , , , , , , ! ! ! ! ! ! ! ! ! ! ! !                            &!!'  $  *  :D D D D D D D D6 E:F + + + + C6 * * * * j " " " " " " " "8	" 	" 	" 	" 	"v 	" 	" 	"n
 n
 n
 n
 n
F n
 n
 n
d   
       v   ,    .       -   
 
 
 
 
 
 
 
B    y       i     r7   