dump.py: tpdu_timestamp_prefix(), tpdu_atr_time_prefix(), format_message() accepts tpdu_prefix parameter, FileDumper supports fmt + ATR time tracking __main__.py: --format/-f flag (hex|timestamp|atr-time), atr_time_start tracking in message loop sniff-start.sh: pass through --format/-f and FORMAT env var
3.7 KiB
simtrace2-pysniff
Python-based replacement for simtrace2-sniff — SIM card communication sniffer
for Osmocom SIMtrace2 hardware (firmware in trace mode).
Single dependency: PyUSB (libusb wrapper). No libosmocore, no libosmosim.
Quick Start
# Install + run
pip install pyusb
python -m simtrace2_pysniff
Or use the bundled startup script:
./sniff-start.sh # hex dump to stdout
./sniff-start.sh --format timestamp # TPDU lines with local time
./sniff-start.sh --format atr-time # TPDU lines relative to ATR
./sniff-start.sh --gsmtap 127.0.0.1:4729 # + Wireshark GSMTAP
./sniff-start.sh --pcap trace.pcap # save PCAP for later
./sniff-start.sh --inactivity-timeout 30 # reconnect on silence
The startup script performs a pre-flight USB permission check and prints install instructions if the udev rule is missing (see below).
USB Device Access
Linux
A udev rule is required for non-root USB access to the SIMtrace2 device.
sudo cp 70-simtrace2-pysniff.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
Then reconnect the SIMtrace2 USB cable. The rule uses TAG+="uaccess"
(systemd-logind ACL) — no group membership or world-writable permissions needed.
Windows
Windows does not ship a libusb-compatible driver for SIMtrace2. Use Zadig to replace the default driver:
- Download and run Zadig
- Plug in the SIMtrace2 device
- Select it in the dropdown (VID
1D50, PID60E3— "Osmocom SIMtrace 2") - Choose WinUSB (or libusbK) as the replacement driver
- Click Replace Driver (one-time operation)
After that, python -m simtrace2_pysniff works identically to Linux.
CLI Options
python -m simtrace2_pysniff [OPTIONS]
--format, -f FORMAT Output format (default: hex)
hex — plain hex dump
timestamp — TPDU lines prefixed with [HH:MM:SS.mmm]
atr-time — TPDU lines prefixed with [SSSS.mmm] from last ATR
--gsmtap HOST[:PORT] Send ATR/TPDU as GSMTAP over UDP (default port 4729)
--pcap FILE Write sniffed data to PCAP file for Wireshark
--output, -o FILE Write hex dump to file
--no-stdout Suppress hex dump to stdout
--vendor HEX USB vendor ID (default: 0x1d50)
--product HEX USB product ID (default: auto-detect)
Recovery options:
--no-reconnect Exit on USB disconnect instead of reconnecting
--inactivity-timeout SEC Reconnect after N seconds of silence (default: disabled)
Library Usage
from simtrace2_pysniff import SniffSession
session = SniffSession(inactivity_timeout=30.0)
for msg in session.iter_messages():
print(f"{msg.type}: {msg.data.hex()}")
Output Formats
hex(default): plain hex dump —ATR: 3b 9e ...,TPDU: a0 a4 00 00 02 3f 00timestamp: TPDU lines prefixed with local time —[14:32:05.123] TPDU: a0 a4 00 00 02 3f 00atr-time: TPDU lines prefixed with seconds since last ATR —[0001.234] TPDU: a0 a4 00 00 02 3f 00
Non-TPDU messages (ATR, PPS, card state changes, Fi/Di) print identically in all formats.
- GSMTAP: ATR (subtype 1) and TPDU (subtype 2) over UDP to Wireshark
- PCAP: all messages as GSMTAP-encapsulated packets (LINKTYPE 155), openable in Wireshark
Recovery
The tool survives hardware resets, cable disconnects, and firmware hangs
by default — it reconnects with exponential backoff (1s → 30s cap).
Use --inactivity-timeout to also trigger reconnect on silent firmware hangs.