
    hM                        d Z ddl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mZ ddlmZmZmZmZ ddlmZ dddd	d
ddddddddddZdddZddddddddd Zd!d"d#d$d%d&Zd'd(d)d*d+d,d-Zd.d/d0d.d1d2d3Z d4d5d6d7d8d9d:d;d<Z!d=d>d?Z"i d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmZ# G dn doe          Z$ G dp dqe          Z% G dr dse          Z& G dt due          Z' G dv dwe          Z( G dx dye          Z) G dz d{e          Z* G d| d}e          Z+ G d~ de          Z, G d de          Z- G d de          Z. G d de          Z/ G d de          Z0 G d de          Z1 G d de          Z2 G d de          Z3 G d de          Z4 G d de          Z5 G d de          Z6 G d de          Z7 G d de          Z8 G d de          Z9 G d de          Z: G d de          Z; G d de          Z< G d de          Z= G d de          Z> G d de          Z? eee?d            eee?d            eee?dd            ee?e1d            ee?e2d            ee?e3d            ee?e4d            ee?e5d            ee?e6d            ee?e7d            ee?e8d            ee?e:d            ee?e9d            ee?e;d            ee?e<d            ee?e=d            ee?e>d            ee&e            ee'e            ee(e            ee)e            ee*e            ee+e            ee,e            ee-e            ee.e            ee/e            ee0e            ee1e            ee2e            ee3e            ee4e            ee5e            ee6e            ee7e            ee8e            ee9e            ee:e            ee;e            ee<e            ee=e            ee>e           dS )a  
KNXNet/IP

This module provides Scapy layers for KNXNet/IP communications over UDP
according to KNX specifications v2.1 / ISO-IEC 14543-3.
Specifications can be downloaded for free here :
https://my.knx.org/en/shop/knx-specifications

Currently, the module (partially) supports the following services :
* SEARCH REQUEST/RESPONSE
* DESCRIPTION REQUEST/RESPONSE
* CONNECT, DISCONNECT, CONNECTION_STATE REQUEST/RESPONSE
* CONFIGURATION REQUEST/RESPONSE
* TUNNELING REQUEST/RESPONSE
    N)PacketFieldMultipleTypeField	ByteField
XByteFieldShortEnumField
ShortFieldByteEnumFieldIPFieldStrFixedLenFieldMACField	XBitFieldPacketListFieldFieldLenFieldStrLenFieldBitEnumFieldBitFieldConditionalField)Packetbind_layersbind_bottom_upPadding)UDPSEARCH_REQUESTSEARCH_RESPONSEDESCRIPTION_REQUESTDESCRIPTION_RESPONSECONNECT_REQUESTCONNECT_RESPONSECONNECTIONSTATE_REQUESTCONNECTIONSTATE_RESPONSEDISCONNECT_REQUESTDISCONNECT_RESPONSECONFIGURATION_REQUESTCONFIGURATION_ACKTUNNELING_REQUESTTUNNELING_ACK)                	  
         !  IPV4_UDPIPV4_TCP)      DEVICE_INFOSUPP_SVC_FAMILIES	IP_CONFIGIP_CUR_CONFIGKNX_ADDRESSESReservedMFR_DATAznot used)r7   r8                     DEVICE_MANAGEMENT_CONNECTIONTUNNEL_CONNECTIONREMLOG_CONNECTIONREMCONF_CONNECTIONOBJSVR_CONNECTION)r@   rA   rC         z
L_Data.reqz
L_Data.conzM_PropRead.reqzM_PropRead.conzM_PropWrite.reqzM_PropWrite.con)   .               reservedTP1PL110RFzKNX IP)r7   r8   rA   rL          GroupValueReadGroupValueRespGroupValueWriteIndAddrWriteIndAddrReadIndAddrRespAdcReadAdcResp)r   r7   r8   r@   rA   rB   rC   rK   DEVICEzIP PARAMETER_OBJECT)r         PID_MANUFACTURER_ID3   PID_PROJECT_INSTALLATION_ID4   PID_KNX_INDIVIDUAL_ADDRESS5   #PID_ADDITIONAL_INDIVIDUAL_ADDRESSES6    PID_CURRENT_IP_ASSIGNMENT_METHOD7   PID_IP_ASSIGNMENT_METHOD8   PID_IP_CAPABILITIES9   PID_CURRENT_IP_ADDRESS:   PID_CURRENT_SUBNET_MASK;   PID_CURRENT_DEFAULT_GATEWAY<   PID_IP_ADDRESS=   PID_SUBNET_MASK>   PID_DEFAULT_GATEWAY?   PID_DHCP_BOOTP_SERVER@   PID_MAC_ADDRESSA   "PID_SYSTEM_SETUP_MULTICAST_ADDRESSB   PID_ROUTING_MULTICAST_ADDRESSPID_TTL PID_KNXNETIP_DEVICE_CAPABILITIESPID_KNXNETIP_DEVICE_STATE!PID_KNXNETIP_ROUTING_CAPABILITIESPID_PRIORITY_FIFO_ENABLEDPID_QUEUE_OVERFLOW_TO_IPPID_QUEUE_OVERFLOW_TO_KNXPID_MSG_TRANSMIT_TO_IPPID_MSG_TRANSMIT_TO_KNXPID_FRIENDLY_NAMEPID_ROUTING_BUSY_WAIT_TIME)C   D   E   F   G   H   I   J   K   L   N   c                       e Zd Zd Zd ZdS )KNXAddressFieldc                 8    |d S d|dz	  dz  |dz	  dz  |dz  fz  S )Nz%d.%d.%drc      rL   rE    selfpktxs      U/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/scapy/contrib/knx.pyi2reprzKNXAddressField.i2repr   s2    94!r'S16S.1t8 MMM    c                 
   t          |t                    rY	 t          t          |                    d                    \  }}}|dz  |dz  z  |z  }n# t
          $ r t          |          w xY wt          j        | ||          S )N.rc   rL   
isinstancestrmapintsplit
ValueErrorr   any2ir   r   r   abcs         r   r   zKNXAddressField.any2i       a 	$$c1773<<001a"Wa(1, $ $ $ mm#$c1---   :A A,N__name__
__module____qualname__r   r   r   r   r   r   r      s5        N N N. . . . .r   r   c                       e Zd Zd Zd ZdS )KNXGroupFieldc                 0    d|dz	  dz  |dz	  dz  |dz  fz  S )Nz%d/%d/%drb      rL   rK   rE   r   r   s      r   r   zKNXGroupField.i2repr   s)    a2g-Q#~DJJJr   c                 
   t          |t                    rY	 t          t          |                    d                    \  }}}|dz  |dz  z  |z  }n# t
          $ r t          |          w xY wt          j        | ||          S )N/rb   rL   r   r   s         r   r   zKNXGroupField.any2i   r   r   Nr   r   r   r   r   r      s5        K K K. . . . .r   r   c                   v    e Zd Zd Z edd           edde           edd           edd          gZ	d Z
dS )HPAIstructure_lengthNhost_protocolr7   
ip_addressportc                 t    | j         -t          j        dt          |                    |dd          z   }||z   S N!Br7   r   structpacklenr   ppays      r   
post_buildzHPAI.post_build   8     (D#a&&))AabbE1A3wr   )r   r   r   namer   r	   HOST_PROTOCOL_CODESr
   r   fields_descr   r   r   r   r   r      so        D	$d++ot-@AAd##
64  	K    r   r   c                   B    e Zd ZdZ edd           edd          gZdS )ServiceFamilyzService FamilyidNversionr   r   r   r   r   r   r   r   r   r   r      s8        D	$	)T""KKKr   r   c                       e Zd ZdZ edd           edde           edde           edd           ed	d           e	d
d           e
ddd           edd           edd           eddd          g
Zd ZdS )DIBDeviceInfozDIB: DEVICE_INFOr   Ndescription_typer7   
knx_mediumr8   device_statusknx_addressproject_installation_identifierdevice_serial_number0   device_multicast_addressdevice_mac_addressdevice_friendly_name   c                 t    | j         -t          j        dt          |                    |dd          z   }||z   S r   r   r   s      r   r   zDIBDeviceInfo.post_build   r   r   )r   r   r   r   r   r	   DESCRIPTION_TYPE_CODESKNX_MEDIUM_CODESr   r   r   r
   r   r   r   r   r   r   r   r   r      s        D	$d++($0FGGlD*:;;	/4((t,,
4d;;	($33*D11%t,,/r::K    r   r   c            
           e Zd ZdZ edd           edde           e ed e	            e	d           d           gZ
d	 Zd
S )DIBSuppSvcFamilieszDIB: SUPP_SVC_FAMILIESr   r8   r   service_familyc                     | j         dz
  S Nr8   r   r   s    r   <lambda>zDIBSuppSvcFamilies.<lambda>   s    047 r   length_fromc                     | j         dk    S r   r   r   s    r   r   zDIBSuppSvcFamilies.<lambda>   s    ,t3 r   c                 t    | j         -t          j        dt          |                    |dd          z   }||z   S r   r   r   s      r   r   zDIBSuppSvcFamilies.post_build   r   r   N)r   r   r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r      s        #D	$d++($0FGGO,)MOO))8 )89 9 9
 43	5 	5
K    r   r   c                   B    e Zd ZdZ edd           edd          gZdS )TunnelingConnectionzTunneling Connection	knx_layerr8   rS   Nr   r   r   r   r   r     s8        !D	+t$$	*d##KKKr   r   c                   ,    e Zd ZdZ edd          gZdS )CRDTunnelingConnectionzCRD Tunneling Connectionknx_individual_addressN)r   r   r   r   r   r   r   r   r   r   r     s*        %D0$77KKKr   r   c            	           e Zd ZdZ edd           edde           e ed e	            e	          d           gZ
d Zd	S )
CRIz$CRI (Connection Request Information)r   r8   connection_typer@   connection_datac                     | j         dk    S NrA   r   r   s    r   r   zCRI.<lambda>      S%8D%@ r   c                 t    | j         -t          j        dt          |                    |dd          z   }||z   S r   r   r   s      r   r   zCRI.post_build  r   r   N)r   r   r   r   r   r	   CONNECTION_TYPE_CODESr   r   r   r   r   r   r   r   r   r     s        1D	$d++'/DEE%6%8%8%:%:%8: : A@	B 	BK    r   r   c            	           e Zd ZdZ edd           edde           e ed e	            e	          d           gZ
d Zd	S )
CRDzCRD (Connection Response Data)r   r   r   r@   r   c                     | j         dk    S r  r  r   s    r   r   zCRD.<lambda>,  r  r   c                 t    | j         -t          j        dt          |                    |dd          z   }||z   S r   r   r   s      r   r   zCRD.post_build/  r   r   N)r   r   r   r   r   r	   r  r   r   r   r   r   r   r   r   r  r  $  s        +D	$d++'/DEE%6%;%;%=%=%;= = A@	B 	BK    r   r  c                   $   e Zd ZdZ edddd           eddd 	           ed
ddddi           eddd           eddd           edddddi           edddddi           eddd           eddd           edddddi           eddd           eddd           edd           e	dd           ed ddd!           ed"dddd!i           ed#dddd$i           ed%dd           ed&dde
           ed!dd          gZdS )'LcEMIL_cEMIadditional_information_lengthr   Badditional_information)fmt	length_ofNc                     | j         S )N)r  r   s    r   r   zLcEMI.<lambda>=  s	    C,M r   r   
frame_typer7   standard
reserved_1repeat_on_errorbroadcast_typedomainpriorityr@   r8   lowack_requestconfirmation_erroraddress_typegroup	hop_countrC   extended_frame_formatrA   source_addressdestination_addressz1/2/3npdu_lengthdatapacket_typesequence_type
unnumbered
reserved_2acpi)r   r   r   r   r   r   r   r   r   r   KNX_ACPI_CODESr   r   r   r   r  r  7  s       D5qc 8	: 	: 	:,d M M	O 	O 	O 	\1az*
 	 	 	q!$$"Aq))%q!x.
 	 	 	ZAu(
 	 	 	1%%%q!,,^Qw,
 	 	 	a##(!Q//($//+W55mTsfEEE]Aqv+
 	 	 	_a|-
 	 	 	q!$$VQ>22AK'KKKr   r  c            	           e Zd ZdZ edd           edd           edd           eddd           ed	dd
          gZdS )DPcEMIDP_cEMIobject_typeNobject_instancer7   property_idnumber_of_elementsrA   start_indexrc   )r   r   r   r   r   r   r   r   r   r   r   r-  r-  c  sm        D 	
=$''	#Q''	-&&%q!,,b))KKKr   r-  c                   ~   e Zd Zd Z edde           e ed e            e          d f ed e            e          d f ed e	            e	          d f ed e	            e	          d f ed e	            e	          d f ed e	            e	          d	 fg ed e            e                    gZ
dS )
CEMImessage_codeN	cemi_datac                     | j         dk    S )NrM   r6  r   s    r   r   zCEMI.<lambda>v      S-5 r   c                     | j         dk    S )NrN   r9  r   s    r   r   zCEMI.<lambda>x  r:  r   c                     | j         dk    S )NrO   r9  r   s    r   r   zCEMI.<lambda>z  r:  r   c                     | j         dk    S )NrP   r9  r   s    r   r   zCEMI.<lambda>|  r:  r   c                     | j         dk    S )NrQ   r9  r   s    r   r   zCEMI.<lambda>~  r:  r   c                     | j         dk    S )NrR   r9  r   s    r   r   zCEMI.<lambda>  r:  r   )r   r   r   r   r	   MESSAGE_CODESr   r   r  r-  r   r   r   r   r5  r5  o  s%       DndM::[%%''599557[%%''599557[&&((F;;557[&&((F;;557[&&((F;;557[&&((F;;557 KUUWWe44	
 	
KKKr   r5  c                   >    e Zd ZdZ ed e            e          gZdS )KNXSearchRequest)r   discovery_endpointNr   r   r   r   r   r   r   r   r   r   rB  rB    s2        D($$&&$77KKKr   rB  c                       e Zd ZdZ ed e            e           ed e            e           ed e            e          gZdS )KNXSearchResponse)r   control_endpointdevice_infosupported_service_familiesN)	r   r   r   r   r   r   r   r   r   r   r   r   rF  rF    sj        D&55M==??MBB02D2D2F2F&	( 	(KKKr   rF  c                   >    e Zd ZdZ ed e            e          gZdS )KNXDescriptionRequestr   rG  NrD  r   r   r   rK  rK    s2         D&55KKKr   rK  c                   f    e Zd ZdZ ed e            e           ed e            e          gZdS )KNXDescriptionResponser   rH  rI  N)r   r   r   r   r   r   r   r   r   r   r   rM  rM    sR        !DM==??MBB02D2D2F2F&	( 	(KKKr   rM  c                       e Zd ZdZ ed e            e           ed e            e           ed e            e          gZdS )KNXConnectRequestr   rG  data_endpointconnection_request_informationN)r   r   r   r   r   r   r   r   r   r   r   rO  rO    sa        D&55OTTVVT224cceeSAAKKKr   rO  c                       e Zd ZdZ edd           edd           ed e            e           ed e            e          gZdS )KNXConnectResponser   communication_channel_idNstatusrP  connection_response_data_block)	r   r   r   r   r   r   r   r  r   r   r   r   rS  rS    sh        D	,d33	(D!!OTTVVT224cceeSAA	KKKr   rS  c                   j    e Zd ZdZ edd           edd           ed e            e          gZdS )KNXConnectionstateRequestr   rT  NrS   rG  r   r   r   r   r   r   r   r   r   r   r   rX  rX    sQ        $D	,d33	*d##&55KKKr   rX  c                   B    e Zd ZdZ edd           edd          gZdS )KNXConnectionstateResponser    rT  NrU  r   r   r   r   r   r[  r[    s9        %D	,d33	(D!!KKKr   r[  c                   j    e Zd ZdZ edd           edd           ed e            e          gZdS )KNXDisconnectRequestr!   rT  r7   rS   NrG  rY  r   r   r   r]  r]    sQ        D	,d33	*d##&55KKKr   r]  c                   B    e Zd ZdZ edd           edd          gZdS )KNXDisconnectResponser"   rT  NrU  r   r   r   r   r   r_  r_    s9         D	,d33	(D!!KKKr   r_  c            	           e Zd ZdZ edd           edd           edd           edd           ed	 e            e          gZd
 ZdS )KNXConfigurationRequestr#   r   rA   rT  r7   sequence_counterNrS   cemic                     | j         5t          j        dt          |d d                             |dd          z   }||z   S Nr   rA   r7   r   r   s      r   r   z"KNXConfigurationRequest.post_build  @     (D#ae**--!""5A3wr   	r   r   r   r   r   r   r5  r   r   r   r   r   ra  ra    s        "D	$d++	,d33	$d++	*d##FDDFFD))K    r   ra  c                   t    e Zd ZdZ edd           edd           edd           edd          gZd ZdS )	KNXConfigurationACKr$   r   NrT  r7   rb  rU  c                 t    | j         -t          j        dt          |                    |dd          z   }||z   S r   r   r   s      r   r   zKNXConfigurationACK.post_build  r   r   r   r   r   r   r   r   r   r   r   r   ri  ri    sn        D	$d++	,d33	$d++	(D!!	K    r   ri  c            	           e Zd ZdZ edd           edd           edd           edd           ed	 e            e          gZd
 ZdS )KNXTunnelingRequestr%   r   rA   rT  r7   rb  NrS   rc  c                     | j         5t          j        dt          |d d                             |dd          z   }||z   S re  r   r   s      r   r   zKNXTunnelingRequest.post_build  rf  r   rg  r   r   r   rm  rm    s        D	$d++	,d33	$d++	*d##FDDFFD))K    r   rm  c                   t    e Zd ZdZ edd           edd           edd           edd          gZd ZdS )	KNXTunnelingACKr&   r   NrT  r7   rb  rU  c                 t    | j         -t          j        dt          |                    |dd          z   }||z   S r   r   r   s      r   r   zKNXTunnelingACK.post_build(  r   r   rk  r   r   r   rp  rp    sn        D	$d++	,d33	$d++	(D!!	K    r   rp  c                   v    e Zd ZdZ edd           edd           edde           edd          gZ	d Z
dS )	KNXz	KNXnet/IPheader_lengthNprotocol_versionrW   service_identifiertotal_lengthc                     | j         -t          j        dt          |                    |dd          z   }| j        =|d d         t          j        dt          |          t          |          z             z   }||z   S )Nr   r7   z!H)rt  r   r   r   rw  r   s      r   r   zKNX.post_build=  sp    %D#a&&))AabbE1A$#2#T3q66CHH+<===A3wr   )r   r   r   r   r   r   r   SERVICE_IDENTIFIER_CODESr   r   r   r   r   r   rs  rs  4  sp        D	/4((
%t,,+T3KLL
>4((	K    r   rs  iW  )dport)sport)r|  r{  r'   )rv  r(   r)   r*   r+   r,   r-   r.   r0   r/   r1   r2   r3   r4   )@__doc__r   scapy.fieldsr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   scapy.packetr   r   r   r   scapy.layers.inetr   rz  r   r   r  r@  r   r+  CEMI_OBJECT_TYPESCEMI_PROPERTIESr   r   r   r   r   r   r   r   r   r  r  r-  r5  rB  rF  rK  rM  rO  rS  rX  r[  r]  r_  ra  ri  rm  rp  rs  r   r   r   <module>r     s>   $ : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
 F E E E E E E E E E E E ! ! ! ! ! ! !"%& !#  & 
   






	 	  )



   




  




   	 	   % $ -	
 * "    ! %       ,!" '#$ 	*#+#"# !$9  F. . . . .j . . .$. . . . .J . . ."    6        F       F   *       ,    &       V       &   "    &   &) ) ) ) )F ) ) )X	 	 	 	 	V 	 	 	    6   6    v              F   	 	 	 	 	V 	 	 	                                6       F       f   "    &        &   "    f   *    &   ( sCt $ $ $ $ sCt $ $ $ $ CD - - - - C!f = = = = C"v > > > > C&6 B B B B C'F C C C C C"v > > > > C# ? ? ? ? C*v F F F F C+ G G G G C&6 B B B B C%& A A A A C(V D D D D C$ @ @ @ @ C$ @ @ @ @ CV < < < < D'    M7 # # # M7 # # #  ( ( (  ) ) ) "G , , , C    C    E7    FG    D'    g & & & w ' ' ' !7 + + + "G , , , w ' ' '  ( ( ( %w / / / & 0 0 0  ' * * * !7 + + + #W - - -  ) ) )  ) ) ) OW % % % % %r   