Fix GSMTAP linktype + type/sub-type values so Wireshark decodes PCAP
pcap.py: LINKTYPE_GSMTAP (155) was wrong — 155 is DLT_USER8, so Wireshark showed 'USER 8 / DLT=155'. Now write Ethernet-encapsulated PCAP (LINKTYPE 1): each GSMTAP message wrapped in Ethernet + IPv4 + UDP (port 4729), with correct checksums — matching a real tcpdump capture of GSMTAP-over-UDP and how Wireshark's gsmtap dissector is keyed. gsmtap.py: GSMTAP_TYPE_SIM was 0x07 (WiMAX burst) — corrected to 0x04; GSMTAP_SIM_APDU was 0x02 (PPS req) — corrected to 0x00; added PPS_REQ/ PPS_RSP. These match libosmocore/Wireshark packet-gsmtap.h. Verified with tshark: PCAP now decodes as GSM SIM (SELECT/STATUS/ATR) instead of 'USER 8'. tests: pcap tests assert Ethernet linktype + framing + GSMTAP payload.
This commit is contained in:
1 parent
e09aac4cb7
commit
cb4c07f3c2
3 files changed
+76
-20
No files matched your search
+28
-9
@@ -3,13 +3,14 @@
|
||||
import struct
|
||||
import unittest
|
||||
|
||||
from simtrace2_pysniff.pcap import build_pcap, PCAP_MAGIC, LINKTYPE_GSMTAP
|
||||
from simtrace2_pysniff.pcap import build_pcap, PCAP_MAGIC, LINKTYPE_ETHERNET
|
||||
from simtrace2_pysniff.server.server import _content_disposition
|
||||
|
||||
FRAMING = 14 + 20 + 8 # Ethernet + IPv4 + UDP
|
||||
|
||||
|
||||
class TestBuildPcap(unittest.TestCase):
|
||||
def _gsmtap_hdr(self, sub_type):
|
||||
import struct
|
||||
return struct.pack('!BBBBHBBIBBBB', 2, 4, 7, 0, 0, 0, 0, 0, sub_type, 0, 0, 0)
|
||||
|
||||
def test_empty(self):
|
||||
@@ -19,16 +20,34 @@ class TestBuildPcap(unittest.TestCase):
|
||||
self.assertEqual(magic, PCAP_MAGIC)
|
||||
self.assertEqual((vmaj, vmin), (2, 4))
|
||||
self.assertEqual(snaplen, 65535)
|
||||
self.assertEqual(network, LINKTYPE_GSMTAP)
|
||||
self.assertEqual(network, LINKTYPE_ETHERNET)
|
||||
|
||||
def test_one_packet(self):
|
||||
pkt = build_pcap([(self._gsmtap_hdr(2), b'\xa0\xa4\x00\x00\x02\x3f\x00', 1234567890.5)])
|
||||
self.assertEqual(len(pkt), 24 + 16 + (16 + 7)) # global + pkt hdr + gsmtap hdr + data
|
||||
ts_sec, ts_usec, incl_len, orig_len = struct.unpack('<IIII', data_bytes := pkt[24:40])
|
||||
# global + pkt hdr + framing (Eth+IP+UDP) + gsmtap hdr + data
|
||||
self.assertEqual(len(pkt), 24 + 16 + FRAMING + 16 + 7)
|
||||
ts_sec, ts_usec, incl_len, orig_len = struct.unpack('<IIII', pkt[24:40])
|
||||
self.assertEqual(ts_sec, 1234567890)
|
||||
self.assertEqual(ts_usec, 500000)
|
||||
self.assertEqual(incl_len, 23)
|
||||
self.assertEqual(orig_len, 23)
|
||||
self.assertEqual(incl_len, FRAMING + 16 + 7)
|
||||
self.assertEqual(orig_len, FRAMING + 16 + 7)
|
||||
|
||||
def test_ethernet_and_udp_headers(self):
|
||||
gsmtap_hdr = self._gsmtap_hdr(2)
|
||||
data = b'\xa0\xa4\x00\x00\x02\x3f\x00'
|
||||
pkt = build_pcap([(gsmtap_hdr, data, 1.0)])
|
||||
payload = pkt[24 + 16:] # skip global + pkt header
|
||||
|
||||
# Ethernet: dst MAC, src MAC, ethertype 0x0800 (IPv4)
|
||||
self.assertEqual(payload[12:14], b'\x08\x00')
|
||||
# IPv4: protocol UDP (17), src/dst 127.0.0.1
|
||||
self.assertEqual(payload[23], 17)
|
||||
self.assertEqual(payload[26:30], b'\x7f\x00\x00\x01')
|
||||
self.assertEqual(payload[30:34], b'\x7f\x00\x00\x01')
|
||||
# UDP: dst port 4729
|
||||
self.assertEqual(struct.unpack('!H', payload[36:38])[0], 4729)
|
||||
# GSMTAP payload follows framing
|
||||
self.assertEqual(payload[FRAMING:], gsmtap_hdr + data)
|
||||
|
||||
def test_multiple_packets(self):
|
||||
packets = [
|
||||
@@ -36,8 +55,8 @@ class TestBuildPcap(unittest.TestCase):
|
||||
(self._gsmtap_hdr(2), b'\x80\xf2\x00\x00\x00', 2.0),
|
||||
]
|
||||
data = build_pcap(packets)
|
||||
# global header + 2 packets (each: 16 pkt hdr + 16 gsmtap hdr + data)
|
||||
self.assertEqual(len(data), 24 + (16 + 16 + 2) + (16 + 16 + 5))
|
||||
# global header + 2 packets (each: 16 pkt hdr + framing + 16 gsmtap hdr + data)
|
||||
self.assertEqual(len(data), 24 + (16 + FRAMING + 16 + 2) + (16 + FRAMING + 16 + 5))
|
||||
|
||||
|
||||
class TestContentDisposition(unittest.TestCase):
|
||||
|
||||
Reference in new issue
Block a user