Skip to content

Commit

Permalink
RTPS: Handle SequenceNumber_t correctly
Browse files Browse the repository at this point in the history
As per DDS-RTPS specification, `firstSN` (named `firstAvailableSeqNum` in scapy) and `lastSN` (named `lastSeqNum` in scapy) fields of a Heartbeat submessage are of type `SequenceNumber_t`, which consists of two subfields, namely, `int32_t high` and `uint32_t low`. This change allows us to correctly assign values to fields.

For example, currently, `firstAvailableSeqNum = 0x01` is packed as `\x00\x00\x00\x01\x00\x00\x00\x00`, which is semantically wrong.
With the change, it is packed as `\x00\x00\x00\x00\x01\x00\x00\x00`.
  • Loading branch information
squizz617 authored and gpotter2 committed Feb 5, 2024
1 parent ca5a069 commit 0591d24
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
11 changes: 8 additions & 3 deletions scapy/contrib/rtps/rtps.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
X3BytesField,
XByteField,
XIntField,
XLongField,
XNBytesField,
XShortField,
XStrLenField,
Expand Down Expand Up @@ -396,8 +395,14 @@ class RTPSSubMessage_HEARTBEAT(EPacket):
fmt="4s",
enum=_rtps_reserved_entity_ids,
),
XLongField("firstAvailableSeqNum", 0),
XLongField("lastSeqNum", 0),
EField(IntField("firstAvailableSeqNumHi", 0),
endianness_from=e_flags),
EField(IntField("firstAvailableSeqNumLow", 0),
endianness_from=e_flags),
EField(IntField("lastSeqNumHi", 0),
endianness_from=e_flags),
EField(IntField("lastSeqNumLow", 0),
endianness_from=e_flags),
EField(IntField("count", 0),
endianness_from=e_flags),
]
Expand Down
38 changes: 38 additions & 0 deletions test/contrib/rtps.uts
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,41 @@ p1 = RTPS(
assert p0.build() == d
assert p1.build() == d
assert p1 == p0

+ Test for pr #3914
= RTPS Heartbeat SequenceNumber_t packing and dissection

d = b"\x52\x54\x50\x53\x02\x02\x01\x0f\x01\x0f\x45\xd2\xb3\xf5\x58\xb9" \
b"\x01\x00\x00\x00\x07\x01\x1c\x00\x00\x00\x03\xc7\x00\x00\x03\xc2" \
b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" \
b"\x01\x00\x00\x00"

p0 = RTPS(d)

p1 = RTPS(
protocolVersion=ProtocolVersionPacket(major=2, minor=2),
vendorId=VendorIdPacket(vendor_id=0x010f),
guidPrefix=GUIDPrefixPacket(
hostId=0x010f45d2, appId=0xb3f558b9, instanceId=0x01000000
),
magic=b"RTPS",
) / RTPSMessage(
submessages=[
RTPSSubMessage_HEARTBEAT(
submessageId=0x07,
submessageFlags=0x01,
octetsToNextHeader=28,
reader_id=b"\x00\x00\x03\xc7",
writer_id=b"\x00\x00\x03\xc2",
firstAvailableSeqNumHi=0,
firstAvailableSeqNumLow=1,
lastSeqNumHi=0,
lastSeqNumLow=1,
count=1
)
]
)

assert p0.build() == d
assert p1.build() == d
assert p0 == p1

0 comments on commit 0591d24

Please sign in to comment.