From d7b984a792df43d3da636e2fcaa3316e03010504 Mon Sep 17 00:00:00 2001 From: Guillaume Valadon Date: Tue, 19 Dec 2017 15:54:13 +0100 Subject: [PATCH] Applying comments to PR#698 (#991) * Added optional extension mechanism from RFC 1889 RFC 1889 section 5.3.1 defines an optional header extension mechanism for proprietary use. This is required by some implementations. Additionally, the sync and sourcesync fields are not named as in the RFC and are somewhat confusing, I added comments. * + Added some tests for RTP * + moved lambda inside RTP class * + All tests are green * + removed commented out code * rtp.py rewritten to use an extra class for the extension header * moved testcases + minor fix * + minor fixes * Comments applied --- scapy/layers/rtp.py | 11 ++++++++++- test/regression.uts | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/scapy/layers/rtp.py b/scapy/layers/rtp.py index 9c28ed386..96afc7588 100644 --- a/scapy/layers/rtp.py +++ b/scapy/layers/rtp.py @@ -25,6 +25,14 @@ _rtp_payload_types = { 31: 'H261', 32: 'MPV', 33: 'MP2T', 34: 'H263' } + +class RTPExtension(Packet): + name = "RTP extension" + fields_desc = [ ShortField("header_id", 0), + FieldLenField("header_len", None, count_of="header", fmt="H"), + FieldListField('header', [], IntField("hdr", 0), count_from=lambda pkt: pkt.header_len) ] + + class RTP(Packet): name="RTP" fields_desc = [ BitField('version', 2, 2), @@ -37,4 +45,5 @@ class RTP(Packet): IntField('timestamp', 0), IntField('sourcesync', 0), FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ] - + +bind_layers(RTP, RTPExtension, extension=1) diff --git a/test/regression.uts b/test/regression.uts index a85492efb..5f2754c6b 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -9425,3 +9425,47 @@ with mock.patch("scapy._version_from_git_describe") as version_mocked: assert(scapy._version() == version) os.unlink(version_filename) assert(scapy._version() == "git-archive.dev$Format:%h") + + +############ +# RTP +############ + ++ RTP tests + += test rtp with extension header +~ rtp + +data = b'\x90o\x14~YY\xf5h\xcc#\xd7\xcfUH\x00\x03\x167116621 \x000\x00' +pkt = RTP(data) +assert "RTP" in pkt +parsed = pkt["RTP"] +assert parsed.version == 2 +assert parsed.extension +assert parsed.numsync == 0 +assert not parsed.marker +assert parsed.payload_type == 111 +assert parsed.sequence == 5246 +assert parsed.timestamp == 1499067752 +assert parsed.sourcesync == 0xcc23d7cf +assert "RTPExtension" in parsed, parsed.show() +assert parsed["RTPExtension"].header_id == 0x5548 +assert parsed["RTPExtension"].header == [0x16373131,0x36363231,0x20003000] + += test layer creation + +created = RTP(extension=True, payload_type="PCMA", sequence=0x1234, timestamp=12345678, sourcesync=0xabcdef01) +created /= RTPExtension(header_id=0x4321, header=[0x11223344]) +assert str(created) == b'\x90\x08\x124\x00\xbcaN\xab\xcd\xef\x01C!\x00\x01\x11"3D', ' '.join(x.encode('hex') for x in str(created)) +parsed = RTP(str(created)) +assert parsed.payload_type == 8 +assert "RTPExtension" in parsed, parsed.show() +assert parsed["RTPExtension"].header == [0x11223344] + += test RTP without extension + +created = RTP(extension=False, payload_type="DVI4", sequence=0x1234, timestamp=12345678, sourcesync=0xabcdef01) +assert str(created) == b'\x80\x11\x124\x00\xbcaN\xab\xcd\xef\x01', ' '.join(x.encode('hex') for x in str(created)) +parsed = RTP(str(created)) +assert parsed.sourcesync == 0xabcdef01 +assert "RTPExtension" not in parsed