From 1ae8e542cf335cbf363edcbeec295c71d5ed697f Mon Sep 17 00:00:00 2001 From: JR Date: Sat, 14 Nov 2026 20:16:44 +0100 Subject: [PATCH] pnio_rpc: read the RTA PDU type from the low nibble of PDUType PNIORealTimeAcyclicPDUHeader declared PDUTypeType before PDUTypeVersion, so the type was read from and written to bits 4-7. IEC 61158-6-10 and Wireshark put the type in bits 0-3 and the version in bits 4-7: an ACK (0x13) dissected as DATA version 3, and PDUTypeType=3 with PDUTypeVersion=1 was written as 0x31. AI-Assisted: yes (Claude Opus 5.5) --- scapy/contrib/pnio_rpc.py | 3 ++- test/contrib/pnio_rpc.uts | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/scapy/contrib/pnio_rpc.py b/scapy/contrib/pnio_rpc.py index e3dd9626d67..8ad90dcd3b6 100644 --- a/scapy/contrib/pnio_rpc.py +++ b/scapy/contrib/pnio_rpc.py @@ -1353,8 +1353,9 @@ class PNIORealTimeAcyclicPDUHeader(Packet): # IEC-61158-6-10:2021, Table 241 ShortField("AlarmDstEndpoint", 0), ShortField("AlarmSrcEndpoint", 0), - BitEnumField("PDUTypeType", 0, 4, PDU_TYPE_TYPE), + # PDUType: Version in bits 4-7, Type in bits 0-3 BitEnumField("PDUTypeVersion", 0, 4, PDU_TYPE_VERSION), + BitEnumField("PDUTypeType", 0, 4, PDU_TYPE_TYPE), BitField("AddFlags", 0, 8), XShortField("SendSeqNum", 0), XShortField("AckSeqNum", 0), diff --git a/test/contrib/pnio_rpc.uts b/test/contrib/pnio_rpc.uts index 01cbdad9f21..5ebeb354ea6 100644 --- a/test/contrib/pnio_rpc.uts +++ b/test/contrib/pnio_rpc.uts @@ -872,6 +872,12 @@ p = Ether(b'\x00\x11\x22\x33\x44\x55' \ assert p[Alarm_Low].RTA_SDU is None assert AlarmNotification_Low not in p assert len(p[Padding].load) == 32 +assert p[Alarm_Low].PDUTypeType == 3 +assert p[Alarm_Low].PDUTypeVersion == 1 + += PNIO Alarm building writes the PDU type in the low nibble +p = Alarm_Low(PDUTypeType=2, PDUTypeVersion=1) +assert raw(p)[4:5] == b'\x12' = PNIO Alarm building computes VarPartLen p = Alarm_High(RTA_SDU=AlarmNotification_High(AlarmType=3))