laforge has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/pysim/+/30438 )


Change subject: pySim-trace: Add support for reading GSMTAP from pcap files
......................................................................

pySim-trace: Add support for reading GSMTAP from pcap files

So far we supported
* GSMTAP live traces via a UDP socket
* RSPRO traces from pcap files (or live)

We were lacking support for reading GSMTAP stored in pcap, which
is what this patch implements.

Change-Id: I46d42774b39a2735500ff5804206ddcfa545568c
---
M pySim-trace.py
A pySim/apdu_source/pyshark_gsmtap.py
2 files changed, 98 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/38/30438/1

diff --git a/pySim-trace.py b/pySim-trace.py
index 33cb75a..79069a6 100755
--- a/pySim-trace.py
+++ b/pySim-trace.py
@@ -18,6 +18,7 @@

 from pySim.apdu_source.gsmtap import GsmtapApduSource
 from pySim.apdu_source.pyshark_rspro import PysharkRsproPcap, PysharkRsproLive
+from pySim.apdu_source.pyshark_gsmtap import PysharkGsmtapPcap

 from pySim.apdu.ts_102_221 import UiccSelect, UiccStatus

@@ -130,6 +131,11 @@
 parser_gsmtap.add_argument('-p', '--bind-port', default=4729,
                            help='Local UDP port')

+parser_gsmtap_pyshark_pcap = subparsers.add_parser('gsmtap-pyshark-pcap', 
help="""
+    PCAP file containing GSMTAP (SIM APDU) communication; processed via 
pyshark.""")
+parser_gsmtap_pyshark_pcap.add_argument('-f', '--pcap-file', required=True,
+                                       help='Name of the PCAP[ng] file to be 
read')
+
 parser_rspro_pyshark_pcap = subparsers.add_parser('rspro-pyshark-pcap', 
help="""
     PCAP file containing RSPRO (osmo-remsim) communication; processed via 
pyshark.
     REQUIRES OSMOCOM PATCHED WIRESHARK!""")
@@ -153,6 +159,8 @@
         s = PysharkRsproPcap(opts.pcap_file)
     elif opts.source == 'rspro-pyshark-live':
         s = PysharkRsproLive(opts.interface)
+    elif opts.source == 'gsmtap-pyshark-pcap':
+        s = PysharkGsmtapPcap(opts.pcap_file)

     tracer = Tracer(source=s, suppress_status=opts.suppress_status, 
suppress_select=opts.suppress_select)
     logger.info('Entering main loop...')
diff --git a/pySim/apdu_source/pyshark_gsmtap.py 
b/pySim/apdu_source/pyshark_gsmtap.py
new file mode 100644
index 0000000..8ea9ae7
--- /dev/null
+++ b/pySim/apdu_source/pyshark_gsmtap.py
@@ -0,0 +1,90 @@
+# coding=utf-8
+
+# (C) 2022 by Harald Welte <lafo...@osmocom.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+import sys
+import logging
+from pprint import pprint as pp
+from typing import Tuple
+import pyshark
+
+from pySim.utils import h2b, b2h
+from pySim.apdu import Tpdu
+from pySim.gsmtap import GsmtapMessage
+from . import ApduSource, PacketType, CardReset
+
+from pySim.apdu.ts_102_221 import ApduCommands as UiccApduCommands
+from pySim.apdu.ts_31_102 import ApduCommands as UsimApduCommands
+from pySim.apdu.global_platform import ApduCommands as GpApduCommands
+ApduCommands = UiccApduCommands + UsimApduCommands + GpApduCommands
+
+logger = logging.getLogger(__name__)
+
+class _PysharkGsmtap(ApduSource):
+    """APDU Source [provider] base class for reading GSMTAP SIM APDU via 
tshark."""
+
+    def __init__(self, pyshark_inst):
+        self.pyshark = pyshark_inst
+        self.bank_id = None
+        self.bank_slot = None
+        self.cmd_tpdu = None
+        super().__init__()
+
+    def read_packet(self) -> PacketType:
+        p = self.pyshark.next()
+        return self._parse_packet(p)
+
+    def _set_or_verify_bank_slot(self, bsl: Tuple[int, int]):
+        """Keep track of the bank:slot to make sure we don't mix traces of 
multiple cards"""
+        if not self.bank_id:
+            self.bank_id = bsl[0]
+            self.bank_slot = bsl[1]
+        else:
+            if self.bank_id != bsl[0] or self.bank_slot != bsl[1]:
+                raise ValueError('Received data for unexpected B(%u:%u)' % 
(bsl[0], bsl[1]))
+
+    def _parse_packet(self, p) -> PacketType:
+        udp_layer = p['udp']
+        udp_payload_hex = udp_layer.get_field('payload').replace(':','')
+        gsmtap = GsmtapMessage(h2b(udp_payload_hex))
+        gsmtap_msg = gsmtap.decode()
+        if gsmtap_msg['type'] != 'sim':
+            raise ValueError('Unsupported GSMTAP type %s' % gsmtap_msg['type'])
+        sub_type = gsmtap_msg['sub_type']
+        if sub_type == 'apdu':
+            return ApduCommands.parse_cmd_bytes(gsmtap_msg['body'])
+        elif sub_type == 'atr':
+            # card has been reset
+            return CardReset()
+        elif sub_type in ['pps_req', 'pps_rsp']:
+            # simply ignore for now
+            pass
+        else:
+            raise ValueError('Unsupported GSMTAP-SIM sub-type %s' % sub_type)
+
+class PysharkGsmtapPcap(_PysharkGsmtap):
+    """APDU Source [provider] class for reading GSMTAP from a PCAP
+    file via pyshark, which in turn uses tshark (part of wireshark).
+    """
+    def __init__(self, pcap_filename):
+        """
+        Args:
+            pcap_filename: File name of the pcap file to be opened
+        """
+        pyshark_inst = pyshark.FileCapture(pcap_filename, 
display_filter='gsm_sim', use_json=True, keep_packets=False)
+        super().__init__(pyshark_inst)
+

--
To view, visit https://gerrit.osmocom.org/c/pysim/+/30438
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I46d42774b39a2735500ff5804206ddcfa545568c
Gerrit-Change-Number: 30438
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <lafo...@osmocom.org>
Gerrit-MessageType: newchange

Reply via email to