Skip to content

Commit da81d35

Browse files
committed
Add telecom-aware privacy and transport profiles
1 parent 489b2d2 commit da81d35

28 files changed

Lines changed: 942 additions & 53 deletions

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ Common starting points:
118118

119119
- `internal` for local-only work
120120
- `share` for internal sharing with subscriber pseudonymization
121+
- `telecom-context` for sharing that keeps IMSI MCC/MNC and MSISDN CC visible
121122
- `prod-safe` for stronger masking before external sharing
122123
- `llm-telecom-safe` for external LLM handoff
123124

@@ -132,6 +133,17 @@ pcap2llm analyze trace.pcapng \
132133

133134
Full privacy guidance: [`docs/PRIVACY_SHARING.md`](docs/PRIVACY_SHARING.md)
134135

136+
`telecom-context` uses telecom-aware partial protection:
137+
138+
- IMSI: `MCC+MNC` stays visible, MSIN is masked
139+
- MSISDN: E.164 country code stays visible, subscriber suffix is masked
140+
- German MSISDNs also keep the built-in mobile NDC when it matches `(0)15`,
141+
`(0)160`, `(0)162`, `(0)163`, or `(0)17x`
142+
- IMEI: TAC stays visible, serial suffix is masked
143+
144+
The default IMSI heuristic is intentionally simple: MCC `3xx` uses a 3-digit
145+
MNC, all other MCCs use a 2-digit MNC unless overridden in config.
146+
135147
## Important Limits
136148

137149
By default `detail.json` contains the first **1,000 packets**. You can raise

docs/ANLEITUNG_DE.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ Typische Startpunkte:
244244

245245
- `internal`: lokal, unveraendert
246246
- `share`: intern teilen, Endpunkte und Subscriber-Daten pseudonymisieren
247+
- `telecom-context`: MCC/MNC, CC, deutsche Mobilfunk-NDCs und IMEI-TAC sichtbar lassen, Rest maskieren
247248
- `prod-safe`: staerker schuetzen, bevor du nach aussen gehst
248249
- `llm-telecom-safe`: guter Standard fuer externe LLMs
249250

@@ -267,6 +268,39 @@ Mehr dazu:
267268
- [`PRIVACY_SHARING.md`](PRIVACY_SHARING.md)
268269
- [`LLM_TROUBLESHOOTING_WORKFLOW.md`](LLM_TROUBLESHOOTING_WORKFLOW.md)
269270

271+
### IMSI/MSISDN mit Routing-Kontext schuetzen
272+
273+
Wenn der Empfaenger MCC/MNC oder den E.164-Country-Code fuer die Fehlersuche
274+
braucht, aber keine vollstaendigen Subscriber-Identifier sehen soll, nutze:
275+
276+
```yaml
277+
privacy_profile: telecom-context
278+
```
279+
280+
Oder gezielt pro Lauf:
281+
282+
```yaml
283+
privacy_modes:
284+
imsi: keep_mcc_mnc_mask_msin
285+
msisdn: keep_cc_ndc_mask_subscriber
286+
```
287+
288+
Die IMSI-Heuristik ist bewusst einfach: MCC `3xx` verwendet eine 3-stellige
289+
MNC, alle anderen MCCs verwenden 2 Stellen. MSISDN ist konservativer: nur der
290+
Country Code bleibt sichtbar. Deutschland ist die eingebaute Ausnahme; passende
291+
Mobilfunk-NDCs fuer `(0)15`, `(0)160`, `(0)162`, `(0)163` und `(0)17x` bleiben
292+
sichtbar. Abweichungen und Partnerlisten kannst du in der Config setzen:
293+
294+
```yaml
295+
numbering:
296+
imsi_mnc_lengths:
297+
"262": 2
298+
"310": 3
299+
msisdn_ndc_prefixes:
300+
"31": ["20"]
301+
"49": ["15", "160", "162", "163", "170", "171", "172", "173"]
302+
```
303+
270304
## Endpunkte lesbarer machen
271305

272306
Du kannst rohe IPs durch bekannte Knoten- oder Rollennamen anreichern.

docs/DOCUMENTATION_MAP.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ Use it when you want to know:
9292
| [`PROFILES_5G.md`](PROFILES_5G.md) | 5GC users | 5G SA core profile family guide | [`PROFILES.md`](PROFILES.md), [`WORKFLOWS.md`](WORKFLOWS.md), [`QUICKSTART_5GC.md`](QUICKSTART_5GC.md) |
9393
| [`PROFILES_VOICE.md`](PROFILES_VOICE.md) | IMS voice users | VoLTE / VoNR profile family guide | [`PROFILES.md`](PROFILES.md), [`WORKFLOWS.md`](WORKFLOWS.md) |
9494
| [`PROFILES_2G3G.md`](PROFILES_2G3G.md) | legacy-core users | 2G/3G / GERAN profile family guide | [`PROFILES.md`](PROFILES.md), [`WORKFLOWS.md`](WORKFLOWS.md) |
95+
| [`TRANSPORT_DECODE_PROFILE_PLAN.md`](TRANSPORT_DECODE_PROFILE_PLAN.md) | contributors, transport troubleshooters | plan for TCP, UDP, and SCTP-focused decode profiles | [`PROFILES.md`](PROFILES.md), [`REFERENCE.md`](REFERENCE.md) |
9596
| [`QUICKSTART_LTE_EPC.md`](QUICKSTART_LTE_EPC.md) | LTE/EPC users | smallest LTE/EPC-oriented starting pattern | [`PROFILES_LTE.md`](PROFILES_LTE.md), [`WORKFLOWS.md`](WORKFLOWS.md), [`REFERENCE.md`](REFERENCE.md) |
9697
| [`QUICKSTART_5GC.md`](QUICKSTART_5GC.md) | 5GC users | smallest 5G core-oriented starting pattern | [`PROFILES_5G.md`](PROFILES_5G.md), [`WORKFLOWS.md`](WORKFLOWS.md), [`QUICKSTART_HTTP2_SBI.md`](QUICKSTART_HTTP2_SBI.md) |
9798
| [`QUICKSTART_HTTP2_SBI.md`](QUICKSTART_HTTP2_SBI.md) | SBI users | shortest HTTP/2/SBI-focused command pattern | [`PROFILES_5G.md`](PROFILES_5G.md), [`QUICKSTART_5GC.md`](QUICKSTART_5GC.md), [`PRIVACY_SHARING.md`](PRIVACY_SHARING.md) |
@@ -126,6 +127,7 @@ Across the full set, the documentation now covers:
126127
- optional signaling-flow visualization with `flow.json`, `flow.svg`, and `visualize`
127128
- protocol-family workflows for LTE, 5G, voice/IMS, and legacy SS7/GERAN
128129
- profile selection and custom profile authoring
130+
- transport decode profile planning for TCP, UDP, and SCTP
129131
- privacy profiles, sharing rules, and encryption model
130132
- machine-readable `--llm-mode` behavior
131133
- external LLM handoff workflow

docs/PRIVACY_SHARING.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Related docs:
1717
| Scenario | Recommended profile | Notes |
1818
|---|---|---|
1919
| Internal team troubleshooting | `share` | Good default for most internal work; endpoint and subscriber identifiers are pseudonymized |
20+
| Telecom-aware cross-team sharing | `telecom-context` | Keeps MCC/MNC, CC, German mobile NDCs, and IMEI TAC visible while masking subscriber-specific suffixes |
2021
| Vendor ticket | `prod-safe` | Remove tokens, reduce sensitive metadata |
2122
| Lab replay / test environment | `lab` | Stronger anonymization, still useful context |
2223
| Personal local analysis | `internal` | Only in fully trusted environments |
@@ -66,6 +67,34 @@ pcap2llm analyze trace.pcapng --profile lte-core --privacy-profile share --out .
6667
above. It keeps the TAC prefix visible and masks the serial suffix. This mode
6768
exists only for `imei`; it is not available for `email`.
6869

70+
**Telecom-aware partial subscriber protection** keeps routing context visible
71+
while protecting the subscriber-specific suffix:
72+
73+
- `imsi: keep_mcc_mnc_mask_msin`
74+
- `imsi: keep_mcc_mnc_pseudonymize_msin`
75+
- `imsi: keep_mcc_mnc_encrypt_msin`
76+
- `msisdn: keep_cc_ndc_mask_subscriber`
77+
- `msisdn: keep_cc_ndc_pseudonymize_subscriber`
78+
- `msisdn: keep_cc_ndc_encrypt_subscriber`
79+
80+
For IMSI, the default MNC-length heuristic is MCC `3xx` -> 3-digit MNC,
81+
otherwise 2-digit MNC.
82+
83+
For MSISDN, the default is more conservative: keep only the E.164 country code
84+
and protect the rest. Germany is the built-in exception; German mobile NDCs for
85+
`(0)15`, `(0)160`, `(0)162`, `(0)163`, and `(0)17x` are also kept. Add explicit
86+
roaming-partner CC/NDC prefixes in the config file:
87+
88+
```yaml
89+
numbering:
90+
imsi_mnc_lengths:
91+
"262": 2
92+
"310": 3
93+
msisdn_ndc_prefixes:
94+
"31": ["20"]
95+
"49": ["15", "160", "162", "163", "170", "171", "172", "173"]
96+
```
97+
6998
**Encryption does not make casual sharing safe.** If you share an encrypted artifact and the key is shared separately later, the data is fully recoverable. Pseudonymization is the safer choice when you want irreversible protection for the shared artifact.
7099
71100
---

docs/PROFILES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@ Use the family guide that matches the network domain you are troubleshooting:
2424
| 5G SA Core | 5GC overview, N1/N2, SBI, UDM/AUSF/UDR, policy, charging, DNS, public warning | [`PROFILES_5G.md`](PROFILES_5G.md) |
2525
| VoLTE / VoNR / IMS | SIP, Diameter, IMS DNS, Session Border Controller, 5GS voice state, auth/policy SBI | [`PROFILES_VOICE.md`](PROFILES_VOICE.md) |
2626
| 2G/3G Core / GERAN | Gn/Gp, Gr, Gs, GERAN, MAP, CAP, ISUP, SCCP/MTP, legacy DNS | [`PROFILES_2G3G.md`](PROFILES_2G3G.md) |
27+
| Transport decode | TCP, UDP, SCTP, IP/IPv6, ICMP lower-layer diagnostics | [`TRANSPORT_DECODE_PROFILE_PLAN.md`](TRANSPORT_DECODE_PROFILE_PLAN.md) |
2728

2829
Quick rule:
2930

3031
- Start with the broad family overview profile if the failing interface is still unclear.
3132
- Move to the narrower interface profile as soon as the real signaling path is known.
3233
- Prefer the voice family over generic SIP-like thinking when the problem is really IMS voice service.
34+
- Use `transport-sctp`, `transport-tcp`, `transport-udp`, or `transport-core`
35+
when the transport behavior itself is the question or upper-layer decode is unreliable.
3336

3437
## Where to Put a Custom Profile
3538

docs/REFERENCE.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ For bounded analyze runs, the JSON artifacts also include `selection.start_packe
163163
```
164164
Profile & filtering:
165165
--profile Protocol profile (default: lte-core)
166-
--privacy-profile Privacy profile: internal | share | lab | prod-safe | llm-telecom-safe | <path>
166+
--privacy-profile Privacy profile: internal | share | lab | prod-safe | llm-telecom-safe | telecom-context | <path>
167167
-Y / --display-filter TShark display filter
168168
--config YAML config file
169169
@@ -757,6 +757,7 @@ For full details and supported types, see [`NETWORK_ELEMENT_DETECTION.md`](NETWO
757757
| `lab` | Pseudonymize all subscriber data, mask IPs |
758758
| `prod-safe` | Maximum protection — mask IPs, pseudonymize all PII, remove tokens/email/URI/payload |
759759
| `llm-telecom-safe` | External LLM-safe default — pseudonymize endpoints and subscriber IDs, remove secrets/payload, keep telecom structure |
760+
| `telecom-context` | Keep IMSI MCC/MNC, MSISDN CC, German mobile NDCs, and IMEI TAC visible while masking subscriber-specific suffixes |
760761

761762
```bash
762763
pcap2llm analyze sample.pcapng --profile lte-core --privacy-profile share
@@ -783,10 +784,32 @@ pcap2llm analyze sample.pcapng \
783784
- `remove` — delete the field entirely
784785
- `keep_tac_mask_serial` — IMEI only; keep the TAC prefix and mask the serial
785786
suffix
787+
- `keep_mcc_mnc_mask_msin` — IMSI only; keep MCC/MNC and mask MSIN
788+
- `keep_mcc_mnc_pseudonymize_msin` — IMSI only; keep MCC/MNC and pseudonymize MSIN
789+
- `keep_mcc_mnc_encrypt_msin` — IMSI only; keep MCC/MNC and encrypt MSIN
790+
- `keep_cc_ndc_mask_subscriber` — MSISDN only; keep E.164 CC and mask subscriber suffix
791+
- `keep_cc_ndc_pseudonymize_subscriber` — MSISDN only; keep E.164 CC and pseudonymize subscriber suffix
792+
- `keep_cc_ndc_encrypt_subscriber` — MSISDN only; keep E.164 CC and encrypt subscriber suffix
786793

787794
`email` does not have a special partial-keep mode. For email addresses, use the
788795
standard modes: `keep`, `mask`, `pseudonymize`, `encrypt`, or `remove`.
789796

797+
Partial IMSI protection defaults to a simple MNC-length heuristic: MCC `3xx`
798+
uses 3 MNC digits, all other MCCs use 2. MSISDN protection keeps only the E.164
799+
country code by default; Germany is the built-in exception and keeps matching
800+
mobile NDCs for `(0)15`, `(0)160`, `(0)162`, `(0)163`, and `(0)17x`. Override
801+
IMSI lengths and add roaming-partner NDC prefixes in config:
802+
803+
```yaml
804+
numbering:
805+
imsi_mnc_lengths:
806+
"262": 2
807+
"310": 3
808+
msisdn_ndc_prefixes:
809+
"31": ["20"]
810+
"49": ["15", "160", "162", "163", "170", "171", "172", "173"]
811+
```
812+
790813
**Pseudonyms are stable across runs** — the same input value always produces the same alias (BLAKE2s hash). This allows correlation between separate analyses of related captures.
791814

792815
### Encryption workflow
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Transport Decode Profile Plan
2+
3+
This plan is for analysis profiles, not privacy profiles. The goal is to make
4+
TCP, UDP, and SCTP troubleshooting useful even when the higher-layer protocol is
5+
unknown, malformed, encrypted, or intentionally ignored.
6+
7+
## Goals
8+
9+
- Add profile-level views for transport-layer diagnostics.
10+
- Preserve packet-level transport evidence with minimal interpretation loss.
11+
- Make SCTP troubleshooting first-class, including stream IDs, chunks, PPIDs,
12+
associations, retransmission signals, heartbeats, SACK behavior, and ABORT /
13+
SHUTDOWN paths.
14+
- Keep the existing telecom profiles focused on service protocols, while adding
15+
explicit transport decode profiles for lower-layer investigations.
16+
17+
## Available Profiles
18+
19+
| Profile | Focus |
20+
|---|---|
21+
| `transport-core` | TCP, UDP, SCTP, IP, ICMP overview for mixed captures |
22+
| `transport-sctp` | SCTP association and chunk-level analysis |
23+
| `transport-tcp` | TCP streams, retransmissions, resets, handshakes, TLS adjacency |
24+
| `transport-udp` | UDP conversations, DNS/NTP/RTP-adjacent traffic, fragmentation hints |
25+
26+
## Profile Shape
27+
28+
Each profile should use `verbatim_protocols` for the transport protocol under
29+
inspection so TShark fields survive reduction with minimal flattening:
30+
31+
```yaml
32+
name: transport-sctp
33+
description: SCTP transport decode profile for association, stream, chunk, and retransmission analysis.
34+
relevant_protocols:
35+
- sctp
36+
- ip
37+
top_protocol_priority:
38+
- sctp
39+
- ip
40+
protocol_aliases:
41+
sctp: [sctp]
42+
ip: [ip, ipv6]
43+
verbatim_protocols:
44+
- sctp
45+
reduced_transport_fields:
46+
- proto
47+
- src_port
48+
- dst_port
49+
- stream
50+
- sctp_stream
51+
- anomaly
52+
- notes
53+
summary_heuristics:
54+
- Highlight SCTP retransmissions, duplicate TSNs, gaps, SACK-only bursts, ABORT, and SHUTDOWN.
55+
```
56+
57+
## Implementation Steps
58+
59+
1. Add the four profile YAML files under `src/pcap2llm/profiles/`. Done.
60+
2. Extend profile tests so each transport profile loads and has expected
61+
protocol aliases, priorities, and verbatim settings.
62+
3. Extend index inspection to surface transport-specific counters:
63+
retransmissions, resets, SCTP chunk types, SACK/ABORT/SHUTDOWN counts, and
64+
stream IDs where available.
65+
4. Add summary heuristics so `summary.json` calls out transport symptoms before
66+
the user has to inspect `detail.json`.
67+
5. Add flow-model support for transport-only diagrams:
68+
TCP handshake/reset markers, SCTP INIT/COOKIE/SACK/ABORT/SHUTDOWN, and UDP
69+
request/response pair hints where ports or DNS transaction IDs allow it.
70+
6. Document usage in `docs/PROFILES.md`, `docs/REFERENCE.md`, and the German
71+
guide.
72+
73+
## Open Design Choice
74+
75+
SCTP should probably be the first implementation target. It has the clearest
76+
telecom value and benefits most from verbatim decode because upper layers such
77+
as S1AP, NGAP, M3UA, or Diameter-over-SCTP can hide transport failure signals
78+
when the user starts from an application profile.

docs/WEB_GUI.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ way until you intentionally open it for troubleshooting or auditability.
195195
- `Delete job` removes the full job directory
196196
- dashboard available at `/dashboard` with job and privacy-profile statistics
197197
- jobs can be multi-selected and deleted from the start page
198-
- Telekom-inspired magenta/neutral visual theme with active navigation states,
198+
- Neutral teal/gray visual theme with active navigation states,
199199
consistent focus rings, and shared light/dark color tokens
200200
- dark-mode toggle in the header persists via `localStorage`
201201
- responsive layout for smaller screens
@@ -302,6 +302,18 @@ This IMEI-only mode keeps the TAC prefix visible and masks the serial suffix.
302302
It is not an email-specific mode. Email addresses use only the standard modes:
303303
`keep`, `mask`, `pseudonymize`, `encrypt`, or `remove`.
304304

305+
For IMSI, the UI also exposes:
306+
307+
- `keep_mcc_mnc_mask_msin`
308+
- `keep_mcc_mnc_pseudonymize_msin`
309+
- `keep_mcc_mnc_encrypt_msin`
310+
311+
For MSISDN, the UI also exposes:
312+
313+
- `keep_cc_ndc_mask_subscriber`
314+
- `keep_cc_ndc_pseudonymize_subscriber`
315+
- `keep_cc_ndc_encrypt_subscriber`
316+
305317
### API Endpoints
306318

307319
List all local profiles as JSON:

docs/privacy_coverage.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,26 @@ Most configurable data classes support the standard protection modes
3535
the TAC prefix visible and masks the serial suffix. This specialized mode does
3636
not apply to `email`.
3737

38+
`imsi` supports telecom-aware partial modes:
39+
40+
- `keep_mcc_mnc_mask_msin`
41+
- `keep_mcc_mnc_pseudonymize_msin`
42+
- `keep_mcc_mnc_encrypt_msin`
43+
44+
These keep the E.212 MCC/MNC routing context and protect the MSIN suffix. By
45+
default, MCC `3xx` uses a 3-digit MNC and other MCCs use a 2-digit MNC unless
46+
`numbering.imsi_mnc_lengths` overrides the MCC.
47+
48+
`msisdn` supports E.164-aware partial modes:
49+
50+
- `keep_cc_ndc_mask_subscriber`
51+
- `keep_cc_ndc_pseudonymize_subscriber`
52+
- `keep_cc_ndc_encrypt_subscriber`
53+
54+
These keep the E.164 country code visible and protect the subscriber suffix.
55+
Germany is the built-in exception: known German mobile NDCs remain visible.
56+
Use `numbering.msisdn_ndc_prefixes` for roaming-partner-specific CC/NDC plans.
57+
3858
## Canonical Classes
3959

4060
- `network_address`

0 commit comments

Comments
 (0)