Rename project to SIMtrace Analyser (v2.0.0)

- move the analysis server out of simtrace2_pysniff into simtrace_analyser;
  simtrace2_pysniff stays as the simtrace2-sniff replacement capture utility
- new server CLI: simtrace-analyser-server; python -m simtrace_analyser
  (simtrace2-pysniff-server and python -m simtrace2_pysniff.server dropped)
- simtrace2_pysniff lazy-imports hardware symbols, so the server no longer
  pulls PyUSB at startup; the GSMTAP/PCAP codecs work without libusb
- version 2.0.0 everywhere (was 1.22.21); PWA SW cache simtrace-analyser-v54
- frontend: server name, clone URL and i18n strings updated; vendored-parser
  reference otaman -> SIMple
- README/README_RUS reworked product-first (analyser first, utility second)
- DB dir ~/.simtrace-analyser, /api status payload and hosted PWA unchanged
This commit is contained in:
catarrh committed 2026-09-19 12:34:16 +03:00
1 parent 8441b56e99
commit 38650b4797
20 files changed
+390 -321

No files matched your search

+69 -51
View File
@@ -1,15 +1,29 @@
# simtrace2-pysniff # SIMtrace Analyser
English | [Русский](README_RUS.md) English | [Русский](README_RUS.md)
Python-based replacement for `simtrace2-sniff` — SIM card communication sniffer APDU trace analyser for the GSMTAP-SIM format — captures SIM/UICC
for Osmocom SIMtrace2 hardware (firmware in **trace** mode). It bundles the communication from a UDP GSMTAP stream (or imports PCAP/PCAPNG files),
**simtrace-analyser** PWA (in [`frontend/`](frontend/)) and an analysis server decodes it, and serves an installable web app for browsing. The repository
that both captures APDU traffic and serves that PWA. also bundles **simtrace2-pysniff**, a Python replacement for
`simtrace2-sniff` that captures from Osmocom SIMtrace2 hardware and can feed
GSMTAP into this analyser.
**Single dependency**: PyUSB (libusb wrapper). No libosmocore, no libosmosim. ![SIMtrace Analyser PWA](frontend.png)
![simtrace-analyser PWA](frontend.png) ## Components
- **Analysis server + PWA** (`simtrace-analyser-server`) — stores captured
traffic in SQLite, decodes it, and serves the PWA ([`frontend/`](frontend/))
plus the HTTP API on a single origin. Three capture modes: a GSMTAP
listener, direct SIMtrace2 hardware capture, or disabled (browse existing
captures only).
- **Capture utility** (`simtrace2-pysniff`) — captures SIMtrace2 hardware
traffic and writes it to stdout, GSMTAP (Wireshark), or PCAP files. It is
one GSMTAP source of several that the analyser accepts (see also
[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)).
- **PWA** ([`frontend/`](frontend/)) — trace browser with decoded APDU,
SIM Toolkit, SMS and SCP80 OTA detail; sessions, PCAP import, EN/RU UI.
## Features ## Features
@@ -38,7 +52,7 @@ that both captures APDU traffic and serves that PWA.
decryption for ciphered packets decryption for ciphered packets
- ATR parse (clock-rate conversion, Fi/Di, T-bitmask) and FCP/FCI TLV - ATR parse (clock-rate conversion, Fi/Di, T-bitmask) and FCP/FCI TLV
**simtrace-analyser PWA** ([`frontend/`](frontend/)): **SIMtrace Analyser PWA** ([`frontend/`](frontend/)):
- Trace view with Map/List modes — proactive, TERMINAL RESPONSE, ENVELOPE - Trace view with Map/List modes — proactive, TERMINAL RESPONSE, ENVELOPE
and AUTH commands get distinctive styling in map view and AUTH commands get distinctive styling in map view
@@ -49,20 +63,22 @@ that both captures APDU traffic and serves that PWA.
## Prerequisites ## Prerequisites
- **Python 3.9+** - **Python 3.9+**
- **PyUSB** — `pip install pyusb` - **PyUSB** — `pip install pyusb` (needed only for capture from SIMtrace2
hardware; GSMTAP/UDP capture and PCAP import work without it)
- **libusb** — system library, present by default on Linux; on Windows the - **libusb** — system library, present by default on Linux; on Windows the
SIMtrace2 driver must be swapped (see [USB Device Access](#usb-device-access)) SIMtrace2 driver must be swapped (see [USB Device Access](#usb-device-access))
- **SIMtrace2 hardware** running firmware in *trace* mode - **SIMtrace2 hardware** running firmware in *trace* mode (only for direct
(VID `1d50`, PID `60e3`, USB class `ff`, subclass `01`). For building and capture; VID `1d50`, PID `60e3`, USB class `ff`, subclass `01`). For
flashing trace firmware, see the [upstream SIMtrace2 project](https://gitea.osmocom.org/sim-card/simtrace2). building and flashing trace firmware, see the
[upstream SIMtrace2 project](https://gitea.osmocom.org/sim-card/simtrace2).
No other dependencies. PCAP, GSMTAP, and hex dump output use only Python stdlib. No other dependencies. PCAP, GSMTAP, and hex dump output use only Python stdlib.
## Install ## Install
```sh ```sh
git clone https://github.com/anttro/simtrace2-pysniff.git git clone https://github.com/anttro/simtrace-analyser.git
cd simtrace2-pysniff cd simtrace-analyser
pip install pyusb pip install pyusb
``` ```
@@ -70,52 +86,27 @@ Or install the package into your environment:
```sh ```sh
pip install -e . pip install -e .
# then run: simtrace2-pysniff [opts] # then run: simtrace-analyser-server [opts]
# or: simtrace2-pysniff [opts]
``` ```
## Running ## Running
Two tools are provided: ### Analysis server + PWA (`simtrace-analyser-server`)
### Sniffer CLI (`simtrace2-pysniff`)
Captures SIMtrace2 traffic and writes it to stdout, GSMTAP (Wireshark), or PCAP files.
### Startup script
`./sniff-start.sh` performs a pre-flight USB permission check (prints udev
install instructions if the SIMtrace2 device is not writable) and then
launches the Python module. On Windows, use `sniff-start.bat` with the same
options (no permission check needed).
```sh
./sniff-start.sh
./sniff-start.sh --format timestamp
./sniff-start.sh --gsmtap 127.0.0.1:4729
./sniff-start.sh --pcap trace.pcap --format atr-time
```
OPTIONS can also be set via environment variables:
```sh
FORMAT=timestamp GSMTAP=127.0.0.1 ./sniff-start.sh
```
### Analysis server + PWA (`simtrace2-pysniff-server`)
Stores captured APDU traffic in SQLite and serves it over HTTP, together with Stores captured APDU traffic in SQLite and serves it over HTTP, together with
the bundled **simtrace-analyser** PWA (`frontend/`) on the same origin. Three the bundled **SIMtrace Analyser** PWA (`frontend/`) on the same origin. Three
capture modes: capture modes:
```sh ```sh
# Listen for GSMTAP from simtrace2-pysniff (or original simtrace2-sniff): # Listen for GSMTAP from simtrace2-pysniff (or original simtrace2-sniff):
simtrace2-pysniff-server --capture gsmtap simtrace-analyser-server --capture gsmtap
# Capture directly from SIMtrace2 hardware (no external tool needed): # Capture directly from SIMtrace2 hardware (no external tool needed):
simtrace2-pysniff-server --capture direct simtrace-analyser-server --capture direct
# Browse/analyse existing captures without a capture backend: # Browse/analyse existing captures without a capture backend:
simtrace2-pysniff-server --capture disabled simtrace-analyser-server --capture disabled
``` ```
The server logs its capture liveness to stderr (each line timestamped The server logs its capture liveness to stderr (each line timestamped
@@ -166,7 +157,7 @@ setup is involved. Use `--web-dir PATH` to serve a different PWA directory
A standalone copy of the PWA is hosted at **https://simtrace.atroshin.ru**. A standalone copy of the PWA is hosted at **https://simtrace.atroshin.ru**.
It is a pure frontend: point it (Settings → Server URL) at a locally running It is a pure frontend: point it (Settings → Server URL) at a locally running
`simtrace2-pysniff-server`. `simtrace-analyser-server`.
> **Browser restriction:** when the PWA is served from a public HTTPS host, > **Browser restriction:** when the PWA is served from a public HTTPS host,
> reaching a local server (`http://127.0.0.1:8081`) requires two things: the > reaching a local server (`http://127.0.0.1:8081`) requires two things: the
@@ -176,7 +167,31 @@ It is a pure frontend: point it (Settings → Server URL) at a locally running
> (or accept the permission prompt). Without the browser permission, the > (or accept the permission prompt). Without the browser permission, the
> request to `127.0.0.1` is blocked before any preflight is sent. > request to `127.0.0.1` is blocked before any preflight is sent.
### Python module (cross-platform) ### Capture utility (`simtrace2-pysniff`)
Captures SIMtrace2 hardware traffic and writes it to stdout, GSMTAP
(Wireshark), or PCAP files. It is the bundled replacement for the original
Osmocom `simtrace2-sniff`.
The `./sniff-start.sh` startup script performs a pre-flight USB permission
check (prints udev install instructions if the SIMtrace2 device is not
writable) and then launches the Python module. On Windows, use
`sniff-start.bat` with the same options (no permission check needed).
```sh
./sniff-start.sh
./sniff-start.sh --format timestamp
./sniff-start.sh --gsmtap 127.0.0.1:4729
./sniff-start.sh --pcap trace.pcap --format atr-time
```
OPTIONS can also be set via environment variables:
```sh
FORMAT=timestamp GSMTAP=127.0.0.1 ./sniff-start.sh
```
Cross-platform module invocation:
```sh ```sh
python -m simtrace2_pysniff python -m simtrace2_pysniff
@@ -192,6 +207,9 @@ simtrace2-pysniff --format atr-time
## USB Device Access ## USB Device Access
Required for capture from SIMtrace2 hardware (the utility and the server's
`--capture direct` mode); not needed for GSMTAP or PCAP sources.
### Linux ### Linux
A udev rule is required for non-root USB access to the SIMtrace2 device. A udev rule is required for non-root USB access to the SIMtrace2 device.
@@ -218,7 +236,7 @@ Windows does not ship a libusb-compatible driver for SIMtrace2. Use
After that, `python -m simtrace2_pysniff` works identically to Linux. After that, `python -m simtrace2_pysniff` works identically to Linux.
## CLI Options ## Utility CLI Options
``` ```
python -m simtrace2_pysniff [OPTIONS] python -m simtrace2_pysniff [OPTIONS]
@@ -279,14 +297,14 @@ for msg in session.iter_messages():
## Recovery ## Recovery
The tool survives hardware resets, cable disconnects, and firmware hangs The utility survives hardware resets, cable disconnects, and firmware hangs
by default — it reconnects with exponential backoff (1s → 30s cap). by default — it reconnects with exponential backoff (1s → 30s cap).
Use `--inactivity-timeout` to also trigger reconnect on silent firmware hangs. Use `--inactivity-timeout` to also trigger reconnect on silent firmware hangs.
## Related ## Related
- **[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2)** — the upstream - **[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2)** — the upstream
SIMtrace2 hardware/firmware project that this tool sniffs from. SIMtrace2 hardware/firmware project that the capture utility sniffs from.
- **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** — - **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** —
FX2LP-based passive ISO 7816 sniffer that emits the same GSMTAP-SIM stream FX2LP-based passive ISO 7816 sniffer that emits the same GSMTAP-SIM stream
on UDP 4729 (accepted by this project's GSMTAP listener). on UDP 4729 (accepted by this project's GSMTAP listener).
+70 -54
View File
@@ -1,16 +1,30 @@
# simtrace2-pysniff # SIMtrace Analyser
[English](README.md) | Русский [English](README.md) | Русский
Замена `simtrace2-sniff` на Python — сниффер обмена с SIM-картой для Анализатор APDU-трассировок в формате GSMTAP-SIM — захватывает обмен с
оборудования Osmocom SIMtrace2 (прошивка в режиме **trace**). Включает PWA SIM/UICC из UDP-потока GSMTAP (или импортирует файлы PCAP/PCAPNG),
**simtrace-analyser** (в [`frontend/`](frontend/)) и анализирующий сервер, декодирует его и отдаёт устанавливаемое веб-приложение для просмотра.
который и захватывает APDU-трафик, и отдаёт эту PWA. В репозиторий также включён **simtrace2-pysniff** — замена `simtrace2-sniff`
на Python, которая захватывает трафик с оборудования Osmocom SIMtrace2
и может передавать GSMTAP этому анализатору.
**Единственная зависимость**: PyUSB (обёртка над libusb). Без libosmocore, ![PWA SIMtrace Analyser](frontend.png)
без libosmosim.
![simtrace-analyser PWA](frontend.png) ## Компоненты
- **Анализирующий сервер + PWA** (`simtrace-analyser-server`) — сохраняет
захваченный трафик в SQLite, декодирует его и отдаёт PWA
([`frontend/`](frontend/)) вместе с HTTP API на одном origin. Три режима
захвата: GSMTAP-листенер, захват напрямую с оборудования SIMtrace2 или
отключённый захват (только просмотр существующих записей).
- **Утилита захвата** (`simtrace2-pysniff`) — захватывает трафик
оборудования SIMtrace2 и выводит его в stdout, GSMTAP (Wireshark) или
PCAP-файлы. Это один из нескольких источников GSMTAP, которые принимает
анализатор (см. также
[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)).
- **PWA** ([`frontend/`](frontend/)) — окно трассировки с декодированными
APDU, SIM Toolkit, SMS и SCP80 OTA; сессии, импорт PCAP, интерфейс EN/RU.
## Возможности ## Возможности
@@ -41,7 +55,7 @@
- Разбор ATR (пересчёт тактовой частоты, Fi/Di, битовая маска T) - Разбор ATR (пересчёт тактовой частоты, Fi/Di, битовая маска T)
и FCP/FCI TLV и FCP/FCI TLV
**PWA simtrace-analyser** ([`frontend/`](frontend/)): **PWA SIMtrace Analyser** ([`frontend/`](frontend/)):
- Окно трассировки с режимами «Карта»/«Список» — proactive, - Окно трассировки с режимами «Карта»/«Список» — proactive,
TERMINAL RESPONSE, ENVELOPE и AUTH-команды выделяются в режиме карты TERMINAL RESPONSE, ENVELOPE и AUTH-команды выделяются в режиме карты
@@ -52,13 +66,14 @@
## Требования ## Требования
- **Python 3.9+** - **Python 3.9+**
- **PyUSB** — `pip install pyusb` - **PyUSB** — `pip install pyusb` (нужен только для захвата с оборудования
SIMtrace2; захват GSMTAP/UDP и импорт PCAP работают без него)
- **libusb** — системная библиотека, обычно уже есть в Linux; в Windows - **libusb** — системная библиотека, обычно уже есть в Linux; в Windows
нужно заменить драйвер SIMtrace2 нужно заменить драйвер SIMtrace2
(см. [Доступ к USB-устройству](#доступ-к-usb-устройству)) (см. [Доступ к USB-устройству](#доступ-к-usb-устройству))
- **Оборудование SIMtrace2** с прошивкой в режиме *trace* - **Оборудование SIMtrace2** с прошивкой в режиме *trace* (только для
(VID `1d50`, PID `60e3`, USB class `ff`, subclass `01`). О сборке прямого захвата; VID `1d50`, PID `60e3`, USB class `ff`, subclass `01`).
и прошивке trace-прошивки см. О сборке и прошивке trace-прошивки см.
[проект SIMtrace2](https://gitea.osmocom.org/sim-card/simtrace2). [проект SIMtrace2](https://gitea.osmocom.org/sim-card/simtrace2).
Других зависимостей нет. Вывод PCAP, GSMTAP и hex dump использует только Других зависимостей нет. Вывод PCAP, GSMTAP и hex dump использует только
@@ -67,8 +82,8 @@
## Установка ## Установка
```sh ```sh
git clone https://github.com/anttro/simtrace2-pysniff.git git clone https://github.com/anttro/simtrace-analyser.git
cd simtrace2-pysniff cd simtrace-analyser
pip install pyusb pip install pyusb
``` ```
@@ -76,53 +91,27 @@ pip install pyusb
```sh ```sh
pip install -e . pip install -e .
# затем запуск: simtrace2-pysniff [opts] # затем запуск: simtrace-analyser-server [opts]
# или: simtrace2-pysniff [opts]
``` ```
## Запуск ## Запуск
Предоставляются два инструмента: ### Анализирующий сервер + PWA (`simtrace-analyser-server`)
### CLI сниффера (`simtrace2-pysniff`)
Захватывает трафик SIMtrace2 и выводит его в stdout, GSMTAP (Wireshark)
или файлы PCAP.
### Скрипт запуска
`./sniff-start.sh` выполняет предварительную проверку прав доступа к USB
(при неудаче печатает инструкцию по установке udev-правила) и затем
запускает модуль Python. В Windows используйте `sniff-start.bat` с теми же
параметрами (проверка прав не требуется).
```sh
./sniff-start.sh
./sniff-start.sh --format timestamp
./sniff-start.sh --gsmtap 127.0.0.1:4729
./sniff-start.sh --pcap trace.pcap --format atr-time
```
Параметры также можно задавать через переменные окружения:
```sh
FORMAT=timestamp GSMTAP=127.0.0.1 ./sniff-start.sh
```
### Анализирующий сервер + PWA (`simtrace2-pysniff-server`)
Сохраняет захваченный APDU-трафик в SQLite и отдаёт его по HTTP вместе Сохраняет захваченный APDU-трафик в SQLite и отдаёт его по HTTP вместе
со встроенной PWA **simtrace-analyser** (`frontend/`) на том же origin. со встроенной PWA **SIMtrace Analyser** (`frontend/`) на том же origin.
Три режима захвата: Три режима захвата:
```sh ```sh
# Слушать GSMTAP от simtrace2-pysniff (или оригинального simtrace2-sniff): # Слушать GSMTAP от simtrace2-pysniff (или оригинального simtrace2-sniff):
simtrace2-pysniff-server --capture gsmtap simtrace-analyser-server --capture gsmtap
# Захват напрямую с оборудования SIMtrace2 (внешний инструмент не нужен): # Захват напрямую с оборудования SIMtrace2 (внешний инструмент не нужен):
simtrace2-pysniff-server --capture direct simtrace-analyser-server --capture direct
# Просмотр/анализ существующих записей без бэкенда захвата: # Просмотр/анализ существующих записей без бэкенда захвата:
simtrace2-pysniff-server --capture disabled simtrace-analyser-server --capture disabled
``` ```
Сервер пишет в stderr информацию о жизненном цикле захвата (каждая строка Сервер пишет в stderr информацию о жизненном цикле захвата (каждая строка
@@ -174,7 +163,7 @@ CORS/Private-Network-Access не требуется. Используйте `--w
Автономная копия PWA размещена на **https://simtrace.atroshin.ru**. Автономная копия PWA размещена на **https://simtrace.atroshin.ru**.
Это чистый фронтенд: укажите в нём (Settings → Server URL) адрес Это чистый фронтенд: укажите в нём (Settings → Server URL) адрес
локально запущенного `simtrace2-pysniff-server`. локально запущенного `simtrace-analyser-server`.
> **Ограничение браузера:** когда PWA отдаётся с публичного HTTPS-хоста, > **Ограничение браузера:** когда PWA отдаётся с публичного HTTPS-хоста,
> доступ к локальному серверу (`http://127.0.0.1:8081`) требует двух > доступ к локальному серверу (`http://127.0.0.1:8081`) требует двух
@@ -185,7 +174,31 @@ CORS/Private-Network-Access не требуется. Используйте `--w
> разрешить сайту (или принять запрос разрешения). Без разрешения > разрешить сайту (или принять запрос разрешения). Без разрешения
> браузера запрос к `127.0.0.1` блокируется ещё до отправки preflight. > браузера запрос к `127.0.0.1` блокируется ещё до отправки preflight.
### Модуль Python (кроссплатформенный) ### Утилита захвата (`simtrace2-pysniff`)
Захватывает трафик оборудования SIMtrace2 и выводит его в stdout, GSMTAP
(Wireshark) или PCAP-файлы. Это встроенная замена оригинального
инструмента Osmocom `simtrace2-sniff`.
Скрипт запуска `./sniff-start.sh` выполняет предварительную проверку прав
доступа к USB (при неудаче печатает инструкцию по установке udev-правила)
и затем запускает модуль Python. В Windows используйте `sniff-start.bat`
с теми же параметрами (проверка прав не требуется).
```sh
./sniff-start.sh
./sniff-start.sh --format timestamp
./sniff-start.sh --gsmtap 127.0.0.1:4729
./sniff-start.sh --pcap trace.pcap --format atr-time
```
Параметры также можно задавать через переменные окружения:
```sh
FORMAT=timestamp GSMTAP=127.0.0.1 ./sniff-start.sh
```
Кроссплатформенный запуск модуля:
```sh ```sh
python -m simtrace2_pysniff python -m simtrace2_pysniff
@@ -202,6 +215,9 @@ simtrace2-pysniff --format atr-time
## Доступ к USB-устройству ## Доступ к USB-устройству
Нужен для захвата с оборудования SIMtrace2 (утилита и режим
`--capture direct` сервера); для источников GSMTAP и PCAP не требуется.
### Linux ### Linux
Для доступа к устройству SIMtrace2 без root нужно udev-правило. Для доступа к устройству SIMtrace2 без root нужно udev-правило.
@@ -229,7 +245,7 @@ sudo udevadm trigger
После этого `python -m simtrace2_pysniff` работает так же, как в Linux. После этого `python -m simtrace2_pysniff` работает так же, как в Linux.
## Параметры CLI ## Параметры CLI утилиты
``` ```
python -m simtrace2_pysniff [OPTIONS] python -m simtrace2_pysniff [OPTIONS]
@@ -295,15 +311,15 @@ for msg in session.iter_messages():
## Восстановление ## Восстановление
Инструмент по умолчанию переживает сбросы оборудования, отключения кабеля Утилита по умолчанию переживает сбросы оборудования, отключения кабеля
и зависания прошивки — он переподключается с экспоненциальной задержкой и зависания прошивки — она переподключается с экспоненциальной задержкой
(1с → 30с). Используйте `--inactivity-timeout`, чтобы также переподключаться (1с → 30с). Используйте `--inactivity-timeout`, чтобы также переподключаться
при «тихих» зависаниях прошивки. при «тихих» зависаниях прошивки.
## Связанные проекты ## Связанные проекты
- **[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2)** — вышестоящий - **[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2)** — вышестоящий
проект оборудования/прошивки SIMtrace2, с которого этот инструмент проект оборудования/прошивки SIMtrace2, с которого утилита захвата
снимает трафик. снимает трафик.
- **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** — - **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** —
пассивный ISO 7816 сниффер на базе FX2LP, выдающий такой же поток пассивный ISO 7816 сниффер на базе FX2LP, выдающий такой же поток
+17 -17
View File
@@ -297,7 +297,7 @@ body { font: 14px/1.5 system-ui, sans-serif; background: var(--bg); color: var(-
<div class="header-right"> <div class="header-right">
<span class="capture-chip" id="capture-chip" style="display:none"></span> <span class="capture-chip" id="capture-chip" style="display:none"></span>
<button id="install-btn" data-l10n="Install PWA">Install PWA</button> <button id="install-btn" data-l10n="Install PWA">Install PWA</button>
<a href="https://github.com/anttro/simtrace2-pysniff" target="_blank" rel="noopener">GitHub</a> <a href="https://github.com/anttro/simtrace-analyser" target="_blank" rel="noopener">GitHub</a>
<button id="lang-btn" onclick="toggleLang()" title="Language / Язык">EN</button> <button id="lang-btn" onclick="toggleLang()" title="Language / Язык">EN</button>
<button id="theme-btn" onclick="toggleTheme()">☀️</button> <button id="theme-btn" onclick="toggleTheme()">☀️</button>
</div> </div>
@@ -676,7 +676,7 @@ function desCbcDecrypt(keyBytes, ivBytes, ctBytes) {
return out; return out;
} }
// ──────────────────── C-APDU parsing (vendored from otaman) ──────────────────── // ──────────────────── C-APDU parsing (vendored from SIMple) ────────────────────
// Parses C-APDU hex streams (e.g. SCP80 secured-packet application messages) // Parses C-APDU hex streams (e.g. SCP80 secured-packet application messages)
// into {label, hex, desc, children} trees. // into {label, hex, desc, children} trees.
const PARSE_INS = { const PARSE_INS = {
@@ -2504,16 +2504,16 @@ function updateVersionWarn(serverVersion) {
const elv = el('version-warn'); const elv = el('version-warn');
const sv = parseVersion(serverVersion); const sv = parseVersion(serverVersion);
if (sv === null) { if (sv === null) {
elv.textContent = t('Server version unknown — update simtrace2-pysniff-server.'); elv.textContent = t('Server version unknown — update simtrace-analyser-server.');
return; return;
} }
const cmpMin = compareVersions(serverVersion, MIN_SERVER_VERSION); const cmpMin = compareVersions(serverVersion, MIN_SERVER_VERSION);
if (cmpMin !== null && cmpMin < 0) { if (cmpMin !== null && cmpMin < 0) {
elv.textContent = t('Server version {v} is outdated. Please update simtrace2-pysniff-server.').replace('{v}', serverVersion); elv.textContent = t('Server version {v} is outdated. Please update simtrace-analyser-server.').replace('{v}', serverVersion);
return; return;
} }
if (sv[0] > parseVersion(PWA_VERSION)[0]) { if (sv[0] > parseVersion(PWA_VERSION)[0]) {
elv.textContent = t('Server version {v} is newer than expected. Update simtrace2-pysniff for full compatibility.').replace('{v}', serverVersion); elv.textContent = t('Server version {v} is newer than expected. Update SIMtrace Analyser for full compatibility.').replace('{v}', serverVersion);
return; return;
} }
elv.textContent = ''; elv.textContent = '';
@@ -2635,9 +2635,9 @@ async function checkConnection() {
el('conn-instructions').innerHTML = ` el('conn-instructions').innerHTML = `
<h3>${t('Setup')}</h3> <h3>${t('Setup')}</h3>
<ol> <ol>
<li>${t('Clone and install simtrace2-pysniff:')}<br> <li>${t('Clone and install SIMtrace Analyser:')}<br>
<code>git clone https://github.com/anttro/simtrace2-pysniff.git</code><br> <code>git clone https://github.com/anttro/simtrace-analyser.git</code><br>
<code>cd simtrace2-pysniff && pip install -e .</code></li> <code>cd simtrace-analyser && pip install -e .</code></li>
<li>${t('Start the server in direct mode (recommended):')}<br> <li>${t('Start the server in direct mode (recommended):')}<br>
<code>./start.sh --capture direct</code><br> <code>./start.sh --capture direct</code><br>
<span style="color:var(--text-muted);">${t('Requires SIMtrace2 hardware connected via USB; captures directly from the device.')}</span></li> <span style="color:var(--text-muted);">${t('Requires SIMtrace2 hardware connected via USB; captures directly from the device.')}</span></li>
@@ -2681,7 +2681,7 @@ function onFilterChange() {
} }
// ──────────────────── Versioning ──────────────────── // ──────────────────── Versioning ────────────────────
const PWA_VERSION = '1.22.21'; const PWA_VERSION = '2.0.0';
const MIN_SERVER_VERSION = '1.0.0'; const MIN_SERVER_VERSION = '1.0.0';
function parseVersion(v) { function parseVersion(v) {
@@ -2705,8 +2705,8 @@ function compareVersions(a, b) {
// ──────────────────── i18n ──────────────────── // ──────────────────── i18n ────────────────────
let currentLang = 'en'; let currentLang = 'en';
const HINT_BLOCKED = 'The browser likely blocked access to the local server. Allow local network access for this site (Chrome/Edge/Vivaldi: Site settings → Local network access → Allow) and confirm simtrace2-pysniff-server is running at {url}.'; const HINT_BLOCKED = 'The browser likely blocked access to the local server. Allow local network access for this site (Chrome/Edge/Vivaldi: Site settings → Local network access → Allow) and confirm simtrace-analyser-server is running at {url}.';
const HINT_UNREACHABLE = 'Couldn\'t reach the server. Check that simtrace2-pysniff-server is running and the URL is correct ({url}). If this page is served over HTTPS, also allow local network access in the browser (Site settings → Local network access → Allow).'; const HINT_UNREACHABLE = 'Couldn\'t reach the server. Check that simtrace-analyser-server is running and the URL is correct ({url}). If this page is served over HTTPS, also allow local network access in the browser (Site settings → Local network access → Allow).';
const LANG_RU = { const LANG_RU = {
'Trace': 'Трассировка', 'Trace': 'Трассировка',
@@ -2785,10 +2785,10 @@ const LANG_RU = {
'Empty file': 'Пустой файл', 'Empty file': 'Пустой файл',
'Install from the address bar:\nclick the install icon (⊕ / monitor icon) at the right\nend of Chrome\'s address bar, then "Install SIMtrace Analyser".': 'Install from the address bar:\nclick the install icon (⊕ / monitor icon) at the right\nend of Chrome\'s address bar, then "Install SIMtrace Analyser".':
'Установка из адресной строки:\nнажмите значок установки (⊕ / значок монитора) в правом\nконце адресной строки Chrome, затем «Установить SIMtrace Analyser».', 'Установка из адресной строки:\nнажмите значок установки (⊕ / значок монитора) в правом\nконце адресной строки Chrome, затем «Установить SIMtrace Analyser».',
[HINT_BLOCKED]: 'Браузер, вероятно, заблокировал доступ к локальному серверу. Разрешите доступ к локальной сети для этого сайта (Chrome/Edge/Vivaldi: Настройки сайта → Доступ к локальной сети → Разрешить) и убедитесь, что simtrace2-pysniff-server запущен по адресу {url}.', [HINT_BLOCKED]: 'Браузер, вероятно, заблокировал доступ к локальному серверу. Разрешите доступ к локальной сети для этого сайта (Chrome/Edge/Vivaldi: Настройки сайта → Доступ к локальной сети → Разрешить) и убедитесь, что simtrace-analyser-server запущен по адресу {url}.',
[HINT_UNREACHABLE]: 'Не удалось связаться с сервером. Проверьте, что simtrace2-pysniff-server запущен и URL указан верно ({url}). Если эта страница открыта по HTTPS, также разрешите доступ к локальной сети в браузере (Настройки сайта → Доступ к локальной сети → Разрешить).', [HINT_UNREACHABLE]: 'Не удалось связаться с сервером. Проверьте, что simtrace-analyser-server запущен и URL указан верно ({url}). Если эта страница открыта по HTTPS, также разрешите доступ к локальной сети в браузере (Настройки сайта → Доступ к локальной сети → Разрешить).',
'Setup': 'Настройка', 'Setup': 'Настройка',
'Clone and install simtrace2-pysniff:': 'Клонируйте и установите simtrace2-pysniff:', 'Clone and install SIMtrace Analyser:': 'Клонируйте и установите SIMtrace Analyser:',
'Start the server in direct mode (recommended):': 'Запустите сервер в режиме direct (рекомендуется):', 'Start the server in direct mode (recommended):': 'Запустите сервер в режиме direct (рекомендуется):',
'Requires SIMtrace2 hardware connected via USB; captures directly from the device.': 'Требуется оборудование SIMtrace2, подключённое по USB; захват выполняется напрямую с устройства.', 'Requires SIMtrace2 hardware connected via USB; captures directly from the device.': 'Требуется оборудование SIMtrace2, подключённое по USB; захват выполняется напрямую с устройства.',
'Then set the URL above to http://127.0.0.1:8081 and return to the Trace tab.': 'Затем укажите URL выше (http://127.0.0.1:8081) и вернитесь на вкладку «Трассировка».', 'Then set the URL above to http://127.0.0.1:8081 and return to the Trace tab.': 'Затем укажите URL выше (http://127.0.0.1:8081) и вернитесь на вкладку «Трассировка».',
@@ -2797,9 +2797,9 @@ const LANG_RU = {
'Start the server:': 'Запустите сервер:', 'Start the server:': 'Запустите сервер:',
'Start a GSMTAP source in another terminal — either:': 'Запустите источник GSMTAP в другом терминале — либо:', 'Start a GSMTAP source in another terminal — either:': 'Запустите источник GSMTAP в другом терминале — либо:',
'(original Osmocom tool)': '(оригинальный инструмент Osmocom)', '(original Osmocom tool)': '(оригинальный инструмент Osmocom)',
'Server version unknown — update simtrace2-pysniff-server.': 'Версия сервера неизвестна — обновите simtrace2-pysniff-server.', 'Server version unknown — update simtrace-analyser-server.': 'Версия сервера неизвестна — обновите simtrace-analyser-server.',
'Server version {v} is outdated. Please update simtrace2-pysniff-server.': 'Версия сервера {v} устарела. Обновите simtrace2-pysniff-server.', 'Server version {v} is outdated. Please update simtrace-analyser-server.': 'Версия сервера {v} устарела. Обновите simtrace-analyser-server.',
'Server version {v} is newer than expected. Update simtrace2-pysniff for full compatibility.': 'Версия сервера {v} новее ожидаемой. Обновите simtrace2-pysniff для полной совместимости.', 'Server version {v} is newer than expected. Update SIMtrace Analyser for full compatibility.': 'Версия сервера {v} новее ожидаемой. Обновите SIMtrace Analyser для полной совместимости.',
'Capture mode: GSMTAP — the server is listening for incoming UDP/GSMTAP traffic. Ensure a GSMTAP source (e.g. simtrace2-pysniff or simtrace2-sniff) is feeding the server.': 'Режим захвата: GSMTAP — сервер ожидает входящий UDP/GSMTAP-трафик. Убедитесь, что источник GSMTAP (например, simtrace2-pysniff или simtrace2-sniff) передаёт данные серверу.', 'Capture mode: GSMTAP — the server is listening for incoming UDP/GSMTAP traffic. Ensure a GSMTAP source (e.g. simtrace2-pysniff or simtrace2-sniff) is feeding the server.': 'Режим захвата: GSMTAP — сервер ожидает входящий UDP/GSMTAP-трафик. Убедитесь, что источник GSMTAP (например, simtrace2-pysniff или simtrace2-sniff) передаёт данные серверу.',
'Capture mode: direct — the server captures from SIMtrace2 hardware. Keep the device connected.': 'Режим захвата: direct — сервер захватывает данные с устройства SIMtrace2. Не отключайте устройство.', 'Capture mode: direct — the server captures from SIMtrace2 hardware. Keep the device connected.': 'Режим захвата: direct — сервер захватывает данные с устройства SIMtrace2. Не отключайте устройство.',
'Capture is disabled — only pre-captured traces (saved sessions / PCAP import) are available.': 'Захват отключён — доступны только ранее записанные трассировки (сохранённые сессии / импорт PCAP).', 'Capture is disabled — only pre-captured traces (saved sessions / PCAP import) are available.': 'Захват отключён — доступны только ранее записанные трассировки (сохранённые сессии / импорт PCAP).',
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE = 'simtrace-analyser-v53'; const CACHE = 'simtrace-analyser-v54';
const PRECACHE = [ const PRECACHE = [
'index.html', 'index.html',
+5 -5
View File
@@ -3,9 +3,9 @@ requires = ["setuptools>=64"]
build-backend = "setuptools.backends._legacy:_Backend" build-backend = "setuptools.backends._legacy:_Backend"
[project] [project]
name = "simtrace2-pysniff" name = "simtrace-analyser"
version = "1.22.21" version = "2.0.0"
description = "Python-based sniffing tool for SIMtrace2 hardware (SIM card communication sniffer)" description = "SIMtrace Analyser — APDU trace analyser for GSMTAP/PCAP captures (bundles the simtrace2-pysniff utility)"
readme = {file = "README.md", content-type = "text/markdown"} readme = {file = "README.md", content-type = "text/markdown"}
license = {text = "GPL-2.0-or-later"} license = {text = "GPL-2.0-or-later"}
requires-python = ">=3.9" requires-python = ">=3.9"
@@ -14,8 +14,8 @@ dependencies = [
] ]
[project.scripts] [project.scripts]
simtrace-analyser-server = "simtrace_analyser.__main__:main"
simtrace2-pysniff = "simtrace2_pysniff.__main__:main" simtrace2-pysniff = "simtrace2_pysniff.__main__:main"
simtrace2-pysniff-server = "simtrace2_pysniff.server.__main__:main"
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
include = ["simtrace2_pysniff*"] include = ["simtrace_analyser*", "simtrace2_pysniff*"]
+31 -7
View File
@@ -1,12 +1,11 @@
"""simtrace2-pysniff — Python replacement for simtrace2-sniff.""" """simtrace2-pysniff — Python replacement for simtrace2-sniff.
from .device import SniffSession, DeviceDisconnected, find_sniffer_device Capture utility bundled with SIMtrace Analyser. Hardware access (PyUSB) is
from .protocol import parse_message, SniffMessage imported lazily, so the GSMTAP/PCAP codec modules can be used without libusb.
from .gsmtap import GsmtapSender, GsmtapReceiver """
from .pcap import PcapWriter
from .dump import FileDumper, format_message from simtrace_analyser.version import __version__
__version__ = '1.22.21'
__all__ = [ __all__ = [
'SniffSession', 'SniffSession',
'DeviceDisconnected', 'DeviceDisconnected',
@@ -20,3 +19,28 @@ __all__ = [
'format_message', 'format_message',
'__version__', '__version__',
] ]
_LAZY_IMPORTS = {
'SniffSession': ('.device', 'SniffSession'),
'DeviceDisconnected': ('.device', 'DeviceDisconnected'),
'find_sniffer_device': ('.device', 'find_sniffer_device'),
'parse_message': ('.protocol', 'parse_message'),
'SniffMessage': ('.protocol', 'SniffMessage'),
'GsmtapSender': ('.gsmtap', 'GsmtapSender'),
'GsmtapReceiver': ('.gsmtap', 'GsmtapReceiver'),
'PcapWriter': ('.pcap', 'PcapWriter'),
'FileDumper': ('.dump', 'FileDumper'),
'format_message': ('.dump', 'format_message'),
}
def __getattr__(name):
"""Import utility symbols on first use (PEP 562)."""
try:
module_name, attr = _LAZY_IMPORTS[name]
except KeyError:
raise AttributeError(f'module {__name__!r} has no attribute {name!r}') from None
from importlib import import_module
value = getattr(import_module(module_name, __name__), attr)
globals()[name] = value
return value
-1
View File
@@ -1 +0,0 @@
"""simtrace2-pysniff server sub-package."""
+9
View File
@@ -0,0 +1,9 @@
"""simtrace_analyser — server side of SIMtrace Analyser.
Stores captured GSMTAP/PCAP APDU traffic in SQLite, decodes it, and serves
the PWA (``frontend/``) plus the HTTP API on a single origin.
"""
from .version import __version__
__all__ = ['__version__']
@@ -1,8 +1,8 @@
"""simtrace2-pysniff-server — CLI entry point. """simtrace-analyser-server — CLI entry point.
Usage: Usage:
simtrace2-pysniff-server --capture gsmtap [--gsmtap-port 4729] [--port 8081] simtrace-analyser-server --capture gsmtap [--gsmtap-port 4729] [--port 8081]
simtrace2-pysniff-server --capture direct [--port 8081] simtrace-analyser-server --capture direct [--port 8081]
""" """
import argparse import argparse
@@ -13,19 +13,19 @@ from http.server import HTTPServer
from .server import RequestHandler from .server import RequestHandler
from .database import Database, DEFAULT_DB_PATH from .database import Database, DEFAULT_DB_PATH
from .capture import CaptureManager, GsmtapListener, DirectSniffer from .capture import CaptureManager, GsmtapListener, DirectSniffer
from .. import __version__ from .version import __version__
def _default_web_dir(): def _default_web_dir():
# <repo>/frontend, whether run from source or an editable install. # <repo>/frontend, whether run from source or an editable install.
# __file__ is <repo>/simtrace2_pysniff/server/__main__.py → up three levels. # __file__ is <repo>/simtrace_analyser/__main__.py → up two levels.
return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'frontend') return os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'frontend')
def main(): def main():
p = argparse.ArgumentParser( p = argparse.ArgumentParser(
prog='simtrace2-pysniff-server', prog='simtrace-analyser-server',
description='HTTP API + PWA server for SIMtrace2 APDU capture and analysis') description='HTTP API + PWA server for APDU trace capture and analysis')
p.add_argument('--host', default='127.0.0.1', p.add_argument('--host', default='127.0.0.1',
help='HTTP bind address (default: 127.0.0.1)') help='HTTP bind address (default: 127.0.0.1)')
p.add_argument('--port', type=int, default=8081, p.add_argument('--port', type=int, default=8081,
@@ -63,7 +63,7 @@ def main():
server = HTTPServer((args.host, args.port), RequestHandler) server = HTTPServer((args.host, args.port), RequestHandler)
server.web_dir = args.web_dir server.web_dir = args.web_dir
print(f'simtrace2-pysniff-server v{__version__} — http://{args.host}:{args.port}', file=sys.stderr) print(f'simtrace-analyser-server v{__version__} — http://{args.host}:{args.port}', file=sys.stderr)
print(f' capture mode: {args.capture}', file=sys.stderr) print(f' capture mode: {args.capture}', file=sys.stderr)
if args.capture == 'gsmtap': if args.capture == 'gsmtap':
print(f' GSMTAP port: {args.gsmtap_port}', file=sys.stderr) print(f' GSMTAP port: {args.gsmtap_port}', file=sys.stderr)
@@ -6,7 +6,7 @@ import threading
import time import time
import traceback import traceback
from ..gsmtap import (GsmtapReceiver, GSMTAP_SIM_ATR, from simtrace2_pysniff.gsmtap import (GsmtapReceiver, GSMTAP_SIM_ATR,
GSMTAP_SIM_PPS_REQ, GSMTAP_SIM_PPS_RSP, GSMTAP_SIM_PPS_REQ, GSMTAP_SIM_PPS_RSP,
GSMTAP_SIM_RST_EVENT, GSMTAP_SIM_VCC_EVENT) GSMTAP_SIM_RST_EVENT, GSMTAP_SIM_VCC_EVENT)
@@ -76,7 +76,7 @@ class GsmtapListener:
class DirectSniffer: class DirectSniffer:
def __init__(self): def __init__(self):
from ..device import SniffSession from simtrace2_pysniff.device import SniffSession
self._session = SniffSession( self._session = SniffSession(
reconnect=True, reconnect=True,
reconnect_delay_min=1.0, reconnect_delay_min=1.0,
@@ -98,7 +98,7 @@ class DirectSniffer:
self._session.close() self._session.close()
def iter_messages(self): def iter_messages(self):
from ..device import DeviceDisconnected from simtrace2_pysniff.device import DeviceDisconnected
try: try:
for msg in self._session.iter_messages(): for msg in self._session.iter_messages():
if not self._running: if not self._running:
@@ -398,7 +398,7 @@ class Database:
# Only card-level changes invalidate the selection. A # Only card-level changes invalidate the selection. A
# waiting-time timeout interrupts a single TPDU but leaves the # waiting-time timeout interrupts a single TPDU but leaves the
# card selected, so the phone usually just retries. # card selected, so the phone usually just retries.
from ..protocol import ( from simtrace2_pysniff.protocol import (
CHANGE_FLAG_CARD_INSERT, CHANGE_FLAG_CARD_EJECT, CHANGE_FLAG_CARD_INSERT, CHANGE_FLAG_CARD_EJECT,
CHANGE_FLAG_RESET_ASSERT, CHANGE_FLAG_RESET_DEASSERT, CHANGE_FLAG_RESET_ASSERT, CHANGE_FLAG_RESET_DEASSERT,
) )
@@ -4,7 +4,7 @@ Pure Python, no dependencies. Decodes raw TPDU bytes captured by
the SIMtrace2 sniffer into structured dicts for the PWA to display. the SIMtrace2 sniffer into structured dicts for the PWA to display.
""" """
from ..gsmtap import GSMTAP_FLAG_BAD_FCS from simtrace2_pysniff.gsmtap import GSMTAP_FLAG_BAD_FCS
# ──────────────────── Status Word names ──────────────────── # ──────────────────── Status Word names ────────────────────
@@ -1,4 +1,4 @@
"""HTTP API + static PWA server for simtrace2-pysniff.""" """HTTP API + static PWA server for SIMtrace Analyser."""
import json import json
import os import os
@@ -11,9 +11,9 @@ from urllib.parse import urlparse, parse_qs, quote
from .database import Database from .database import Database
from .capture import CaptureManager, GsmtapListener, DirectSniffer, _log from .capture import CaptureManager, GsmtapListener, DirectSniffer, _log
from ..gsmtap import build_gsmtap_packet, GSMTAP_SIM_ATR, GSMTAP_SIM_APDU from simtrace2_pysniff.gsmtap import build_gsmtap_packet, GSMTAP_SIM_ATR, GSMTAP_SIM_APDU
from ..pcap import build_pcap, parse_pcap, parse_pcapng from simtrace2_pysniff.pcap import build_pcap, parse_pcap, parse_pcapng
from .. import __version__ from .version import __version__
# Static file serving (the PWA lives in <repo>/frontend, served by this server # Static file serving (the PWA lives in <repo>/frontend, served by this server
+3
View File
@@ -0,0 +1,3 @@
"""Single source of truth for the SIMtrace Analyser version."""
__version__ = '2.0.0'
+3 -3
View File
@@ -1,7 +1,7 @@
@echo off @echo off
setlocal enabledelayedexpansion setlocal enabledelayedexpansion
:: simtrace2-pysniff-server startup script for Windows :: simtrace-analyser-server startup script for Windows
:: ::
:: Usage: start.bat [--capture gsmtap|direct] [--port PORT] [--db PATH] [--gsmtap-port PORT] :: Usage: start.bat [--capture gsmtap|direct] [--port PORT] [--db PATH] [--gsmtap-port PORT]
:: ::
@@ -47,8 +47,8 @@ shift
goto :parse_args goto :parse_args
:run :run
echo Starting simtrace2-pysniff-server... echo Starting simtrace-analyser-server...
echo PWA (simtrace-analyser) will be served at http://127.0.0.1:%PORT%/ echo PWA (simtrace-analyser) will be served at http://127.0.0.1:%PORT%/
set "PYTHONPATH=%~dp0" set "PYTHONPATH=%~dp0"
python -m simtrace2_pysniff.server --capture %CAPTURE% --port %PORT% --gsmtap-port %GSMTAP_PORT% %EXTRA_ARGS% python -m simtrace_analyser --capture %CAPTURE% --port %PORT% --gsmtap-port %GSMTAP_PORT% %EXTRA_ARGS%
+3 -3
View File
@@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# simtrace2-pysniff-server startup script # simtrace-analyser-server startup script
# #
# Usage: ./start.sh [--capture gsmtap|direct] [--port PORT] [--db PATH] [--gsmtap-port PORT] # Usage: ./start.sh [--capture gsmtap|direct] [--port PORT] [--db PATH] [--gsmtap-port PORT]
# #
@@ -71,6 +71,6 @@ ARGS+=(--port "$PORT")
[[ "$CAPTURE" == "gsmtap" ]] && ARGS+=(--gsmtap-port "$GSMTAP_PORT") [[ "$CAPTURE" == "gsmtap" ]] && ARGS+=(--gsmtap-port "$GSMTAP_PORT")
ARGS+=("${EXTRA_ARGS[@]}") ARGS+=("${EXTRA_ARGS[@]}")
echo "Starting simtrace2-pysniff-server..." >&2 echo "Starting simtrace-analyser-server..." >&2
echo "PWA (simtrace-analyser) will be served at http://127.0.0.1:$PORT/" >&2 echo "PWA (simtrace-analyser) will be served at http://127.0.0.1:$PORT/" >&2
exec env PYTHONPATH="$PROJECT_DIR" python3 -m simtrace2_pysniff.server "${ARGS[@]}" exec env PYTHONPATH="$PROJECT_DIR" python3 -m simtrace_analyser "${ARGS[@]}"
+7 -7
View File
@@ -7,8 +7,8 @@ import tempfile
import time import time
import unittest import unittest
from simtrace2_pysniff.server.capture import CaptureManager, gsmtap_msg_type from simtrace_analyser.capture import CaptureManager, gsmtap_msg_type
from simtrace2_pysniff.server.database import Database from simtrace_analyser.database import Database
class TestGsmtapSubtypeMapping(unittest.TestCase): class TestGsmtapSubtypeMapping(unittest.TestCase):
@@ -67,7 +67,7 @@ class TestCaptureManager(unittest.TestCase):
self.assertEqual(db.count_messages(sid), 1) self.assertEqual(db.count_messages(sid), 1)
def test_direct_sniffer_device_disconnect(self): def test_direct_sniffer_device_disconnect(self):
from simtrace2_pysniff.server.capture import DirectSniffer from simtrace_analyser.capture import DirectSniffer
sn = DirectSniffer() sn = DirectSniffer()
sn._session = _DisconnectingSession() sn._session = _DisconnectingSession()
self.assertEqual(list(sn.iter_messages()), []) self.assertEqual(list(sn.iter_messages()), [])
@@ -84,7 +84,7 @@ class TestCaptureManager(unittest.TestCase):
self.assertEqual([m['type'] for m in msgs], ['gap', 'tpdu']) self.assertEqual([m['type'] for m in msgs], ['gap', 'tpdu'])
def test_direct_sniffer_connected(self): def test_direct_sniffer_connected(self):
from simtrace2_pysniff.server.capture import DirectSniffer from simtrace_analyser.capture import DirectSniffer
class _FakeSession: class _FakeSession:
connected = True connected = True
@@ -96,7 +96,7 @@ class TestCaptureManager(unittest.TestCase):
self.assertFalse(sn.connected) self.assertFalse(sn.connected)
def test_device_connected_gsmtap_none(self): def test_device_connected_gsmtap_none(self):
from simtrace2_pysniff.server.capture import GsmtapListener from simtrace_analyser.capture import GsmtapListener
listener = GsmtapListener(bind_port=0) listener = GsmtapListener(bind_port=0)
self.addCleanup(listener.stop) self.addCleanup(listener.stop)
mgr, _ = self._manager(listener) mgr, _ = self._manager(listener)
@@ -170,7 +170,7 @@ class _RaisingBackend:
class TestGsmtapListenerRobustness(unittest.TestCase): class TestGsmtapListenerRobustness(unittest.TestCase):
def test_listener_survives_bad_packet(self): def test_listener_survives_bad_packet(self):
from simtrace2_pysniff.server.capture import GsmtapListener from simtrace_analyser.capture import GsmtapListener
listener = GsmtapListener(bind_port=0) listener = GsmtapListener(bind_port=0)
listener._receiver.close() # drop the real socket before swapping listener._receiver.close() # drop the real socket before swapping
listener._receiver = _FlakyReceiver(listener, ['raise_non_sim', 'good']) listener._receiver = _FlakyReceiver(listener, ['raise_non_sim', 'good'])
@@ -181,7 +181,7 @@ class TestGsmtapListenerRobustness(unittest.TestCase):
self.assertEqual(listener.dropped, 1) self.assertEqual(listener.dropped, 1)
def test_listener_survives_short_packet(self): def test_listener_survives_short_packet(self):
from simtrace2_pysniff.server.capture import GsmtapListener from simtrace_analyser.capture import GsmtapListener
listener = GsmtapListener(bind_port=0) listener = GsmtapListener(bind_port=0)
listener._receiver.close() # drop the real socket before swapping listener._receiver.close() # drop the real socket before swapping
listener._receiver = _FlakyReceiver(listener, ['raise_short', 'good']) listener._receiver = _FlakyReceiver(listener, ['raise_short', 'good'])
+146 -146
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -4,7 +4,7 @@ import struct
import unittest import unittest
from simtrace2_pysniff.pcap import build_pcap, PCAP_MAGIC, LINKTYPE_ETHERNET from simtrace2_pysniff.pcap import build_pcap, PCAP_MAGIC, LINKTYPE_ETHERNET
from simtrace2_pysniff.server.server import _content_disposition from simtrace_analyser.server import _content_disposition
FRAMING = 14 + 20 + 8 # Ethernet + IPv4 + UDP FRAMING = 14 + 20 + 8 # Ethernet + IPv4 + UDP
+7 -7
View File
@@ -147,8 +147,8 @@ class TestTsresol(unittest.TestCase):
class TestImportEndpoint(unittest.TestCase): class TestImportEndpoint(unittest.TestCase):
def _handler(self, body): def _handler(self, body):
from simtrace2_pysniff.server.server import RequestHandler from simtrace_analyser.server import RequestHandler
from simtrace2_pysniff.server.database import Database from simtrace_analyser.database import Database
class Fake(RequestHandler): class Fake(RequestHandler):
def __init__(self, body, db): def __init__(self, body, db):
@@ -224,12 +224,12 @@ class TestImportEndpoint(unittest.TestCase):
class TestVersion(unittest.TestCase): class TestVersion(unittest.TestCase):
def test_package_version(self): def test_package_version(self):
from simtrace2_pysniff import __version__ from simtrace2_pysniff import __version__
self.assertEqual(__version__, '1.22.21') self.assertEqual(__version__, '2.0.0')
def test_status_includes_version(self): def test_status_includes_version(self):
import os import os
from simtrace2_pysniff.server.server import RequestHandler from simtrace_analyser.server import RequestHandler
from simtrace2_pysniff.server.database import Database from simtrace_analyser.database import Database
from simtrace2_pysniff import __version__ from simtrace2_pysniff import __version__
class FakeCapture: class FakeCapture:
@@ -259,8 +259,8 @@ class TestVersion(unittest.TestCase):
class TestCaptureDisabled(unittest.TestCase): class TestCaptureDisabled(unittest.TestCase):
def _handler(self, capture_mode): def _handler(self, capture_mode):
import os import os
from simtrace2_pysniff.server.server import RequestHandler from simtrace_analyser.server import RequestHandler
from simtrace2_pysniff.server.database import Database from simtrace_analyser.database import Database
class Fake(RequestHandler): class Fake(RequestHandler):
def __init__(self, db, capture_mode): def __init__(self, db, capture_mode):