Skip to content

Commit 0591d24

Browse files
squizz617gpotter2
authored andcommitted
RTPS: Handle SequenceNumber_t correctly
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`.
1 parent ca5a069 commit 0591d24

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

scapy/contrib/rtps/rtps.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
X3BytesField,
2626
XByteField,
2727
XIntField,
28-
XLongField,
2928
XNBytesField,
3029
XShortField,
3130
XStrLenField,
@@ -396,8 +395,14 @@ class RTPSSubMessage_HEARTBEAT(EPacket):
396395
fmt="4s",
397396
enum=_rtps_reserved_entity_ids,
398397
),
399-
XLongField("firstAvailableSeqNum", 0),
400-
XLongField("lastSeqNum", 0),
398+
EField(IntField("firstAvailableSeqNumHi", 0),
399+
endianness_from=e_flags),
400+
EField(IntField("firstAvailableSeqNumLow", 0),
401+
endianness_from=e_flags),
402+
EField(IntField("lastSeqNumHi", 0),
403+
endianness_from=e_flags),
404+
EField(IntField("lastSeqNumLow", 0),
405+
endianness_from=e_flags),
401406
EField(IntField("count", 0),
402407
endianness_from=e_flags),
403408
]

test/contrib/rtps.uts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,3 +405,41 @@ p1 = RTPS(
405405
assert p0.build() == d
406406
assert p1.build() == d
407407
assert p1 == p0
408+
409+
+ Test for pr #3914
410+
= RTPS Heartbeat SequenceNumber_t packing and dissection
411+
412+
d = b"\x52\x54\x50\x53\x02\x02\x01\x0f\x01\x0f\x45\xd2\xb3\xf5\x58\xb9" \
413+
b"\x01\x00\x00\x00\x07\x01\x1c\x00\x00\x00\x03\xc7\x00\x00\x03\xc2" \
414+
b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" \
415+
b"\x01\x00\x00\x00"
416+
417+
p0 = RTPS(d)
418+
419+
p1 = RTPS(
420+
protocolVersion=ProtocolVersionPacket(major=2, minor=2),
421+
vendorId=VendorIdPacket(vendor_id=0x010f),
422+
guidPrefix=GUIDPrefixPacket(
423+
hostId=0x010f45d2, appId=0xb3f558b9, instanceId=0x01000000
424+
),
425+
magic=b"RTPS",
426+
) / RTPSMessage(
427+
submessages=[
428+
RTPSSubMessage_HEARTBEAT(
429+
submessageId=0x07,
430+
submessageFlags=0x01,
431+
octetsToNextHeader=28,
432+
reader_id=b"\x00\x00\x03\xc7",
433+
writer_id=b"\x00\x00\x03\xc2",
434+
firstAvailableSeqNumHi=0,
435+
firstAvailableSeqNumLow=1,
436+
lastSeqNumHi=0,
437+
lastSeqNumLow=1,
438+
count=1
439+
)
440+
]
441+
)
442+
443+
assert p0.build() == d
444+
assert p1.build() == d
445+
assert p0 == p1

0 commit comments

Comments
 (0)