
    h                        d Z ddl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 ddlmZ ddlmZmZmZ dZd	ee<   d
ZdZdZ G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Zej         eej!        eej"        eej#        eej$        eej%        eej&        eiZ' eeee            eeee           d S )!a-  
    MACControl
    ~~~~~~~~~~

    :author:    Thomas Tannhaeuser, hecke@naberius.de

    :description:

        This module provides Scapy layers for the MACControl protocol messages:
            - Pause
            - Gate
            - Report
            - Register/REQ/ACK
            - Class Based Flow Control

        normative references:
            - IEEE 802.3x


    :NOTES:
        - this is based on the MACControl dissector used by Wireshark
          (https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-maccontrol.c)

    )orb)ETHER_TYPES)Scapy_Exception)IntField	ByteFieldByteEnumField
ShortFieldBitField)Packet)EtherDot1Qbind_layersi  MAC_CONTROL         c                       e Zd ZdZdZdZdZdZdZdZ	dZ
ed	ed
ededede	de
diZ	 dZdZdZdZedededediZd Zd Zd ZdS )
MACControlz01:80:c2:00:00:01r   r      r         i  pausegatereportzregister reqregisterregister_ackzclass based flow control
deregisteracknackc                     	 t          |d                   dz  t          |d                   z   }t          |         S # t          $ r Y nw xY wt          j        | |          S )Nr      r   )r   MAC_CTRL_CLASSESKeyErrorr   guess_payload_class)selfpayloadop_codes      ]/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/scapy/contrib/mac_control.pyr$   zMACControl.guess_payload_classT   sj    	71:!+s71:>G#G,, 	 	 	D	 )$888s   := 
A
	A
c                     | j         }d}|r8t          |t                    r#|dz  }|j         }|rt          |t                    #|rt          |t                    r|dz  }|S )zY
        get the total size of all under layers
        :return: number of bytes
        r   r      )
underlayer
isinstancer   r   )r%   under_layerunder_layers_sizes      r(   _get_underlayers_sizez MACControl._get_underlayers_size^   s     o 	1je<< 	1"%0K  	1je<< 	1  	(:k599 	('      c                 ~    |s7|                                  }t          |          |z   }|dk     r|dd|z
  z  z   S ||z   S )z
        add padding to the frame if required.

        note that padding is only added if pay is None/empty. this allows us to add  # noqa: E501
        any payload after the MACControl* PDU if needed (piggybacking).
        @       )r/   len)r%   pktpayr.   
frame_sizes        r(   
post_buildzMACControl.post_buildr   sV      	9 $ : : < <c((%66JBWZ888Syr0   N)__name__
__module____qualname__DEFAULT_DST_MACOP_CODE_PAUSEOP_CODE_GATEOP_CODE_REPORTOP_CODE_REGISTER_REQOP_CODE_REGISTEROP_CODE_REGISTER_ACK OP_CODE_CLASS_BASED_FLOW_CONTROLOP_CODESFLAG_REGISTERFLAG_DEREGISTERFLAG_ACK	FLAG_NACKREGISTER_FLAGSr$   r/   r8    r0   r(   r   r   0   s        )OMLN!!'-$ 	wfn*n(*DH MOHI 	z%6	N9 9 9! ! !(    r0   r   c                       e Zd ZdS )MACControlInvalidSpeedExceptionN)r9   r:   r;   rJ   r0   r(   rL   rL      s        Dr0   rL   c                   R    e Zd Z edej                   edd          gZefdZdS )MACControlPause_op_code
pause_timer   c                     	 | j         t          dt          dt          di|         z  S # t          $ r t          d          w xY w)a+  
        get pause time for given link speed in seconds

        :param speed: select link speed to get the pause time for, must be ETHER_SPEED_MBIT_[10,100,1000]  # noqa: E501
        :return: pause time in seconds
        :raises MACControlInvalidSpeedException: on invalid speed selector
        gH
?g:0y>g&.>zKInvalid speed selector given. Must be one of ETHER_SPEED_MBIT_[10,100,1000])rP   ETHER_SPEED_MBIT_10ETHER_SPEED_MBIT_100ETHER_SPEED_MBIT_1000r#   rL   )r%   speeds     r(   get_pause_timezMACControlPause.get_pause_time   ss    	c?#o$'7%(=& 	&  
  	c 	c 	c1 3b c c c	cs	   $' AN)	r9   r:   r;   r	   r   r=   fields_descrT   rV   rJ   r0   r(   rN   rN      s[        
:z788
<##K
 $9 c c c c c cr0   rN   c                   H    e Zd Z edej                   edd          gZdS )MACControlGaterO   	timestampr   N)r9   r:   r;   r	   r   r>   r   rW   rJ   r0   r(   rY   rY      s6        
:z677a  KKKr0   rY   c                       e Zd Z edej                   edd           eddej                   e	dd          gZ
dS )MACControlReportrO   rZ   r   flagspending_grantsN)r9   r:   r;   r	   r   r?   r   r   rI   r   rW   rJ   r0   r(   r\   r\      sZ        
:z899a  gq*";<<	"A&&	KKKr0   r\   c            	           e Zd Z edej                   edd           edd           eddej                   edd           e	dd          gZ
dS )	MACControlRegisterReqrO   rZ   r   assigned_portr]   	sync_timeechoed_pending_grantsN)r9   r:   r;   r	   r   r@   r   r   rI   r   rW   rJ   r0   r(   r`   r`      sx        
:z>??a  
?A&&gq*";<<
;""	)1--KKKr0   r`   c                       e Zd Z edej                   edd           eddej                   edd           edd          gZ	dS )MACControlRegisterrO   rZ   r   r]   echoed_assigned_portechoed_sync_timeN)
r9   r:   r;   r	   r   rA   r   r   rI   rW   rJ   r0   r(   re   re      sj        
:z:;;a  gq*";<<
)1--
%q))KKKr0   re   c                       e Zd Z edej                   edd           eddej                   edd           edd          gZ	dS )MACControlRegisterAckrO   rZ   r   r]   rf   rg   N)
r9   r:   r;   r	   r   rB   r   r   rI   rW   rJ   r0   r(   ri   ri      sj        
:z>??a  gq*";<<
)1--
%q))KKKr0   ri   c                      e Zd Z edej                   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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 )MACControlClassBasedFlowControlrO   	_reservedr   
c7_enabledr   
c6_enabled
c5_enabled
c4_enabled
c3_enabled
c2_enabled
c1_enabled
c0_enabledc0_pause_timec1_pause_timec2_pause_timec3_pause_timec4_pause_timec5_pause_timec6_pause_timec7_pause_timeN)	r9   r:   r;   r	   r   rC   r   r
   rW   rJ   r0   r(   rk   rk      s6       
:zJKK	+q!!q!$$q!$$q!$$q!$$q!$$q!$$q!$$q!$$
?A&&
?A&&
?A&&
?A&&
?A&&
?A&&
?A&&
?A&&%KKKr0   rk   )typeN)(__doc__scapy.compatr   
scapy.datar   scapy.errorr   scapy.fieldsr   r   r   r	   r
   scapy.layers.dot11r   scapy.layers.l2r   r   r   MAC_CONTROL_ETHER_TYPErR   rS   rT   r   rL   rN   rY   r\   r`   re   ri   rk   r=   r>   r?   r@   rA   rB   rC   r"   rJ   r0   r(   <module>r      s   2       " " " " " " ' ' ' ' ' ' Q Q Q Q Q Q Q Q Q Q Q Q Q Q % % % % % % 5 5 5 5 5 5 5 5 5 5 &3" #   R R R R R R R Rj	 	 	 	 	o 	 	 	c c c c cj c c c4    Z       z       J              J       j   0 o^/#%:!3#%:/1P  E:$: ; ; ; ; E:$: ; ; ; ; ; ;r0   