Decode EF_DIR EAP discretionary template (TS 102 310)
This commit is contained in:
1 parent
f11a6a62e6
commit
26043e5381
3 files changed
+53
-3
No files matched your search
+8
-1
@@ -723,7 +723,14 @@ function fileRows(f) {
|
|||||||
for (const s of f.services) rows.push(['Service ' + s.n, s.name || '']);
|
for (const s of f.services) rows.push(['Service ' + s.n, s.name || '']);
|
||||||
}
|
}
|
||||||
if (f.applications) {
|
if (f.applications) {
|
||||||
for (const a of f.applications) rows.push(['App', (a.label ? a.label + ' · ' : '') + (a.aid || '')]);
|
for (const a of f.applications) {
|
||||||
|
rows.push(['App', (a.label ? a.label + ' · ' : '') + (a.aid || '')]);
|
||||||
|
if (a.eap) {
|
||||||
|
const types = (a.eap.eap_types || []).join(', ');
|
||||||
|
const dfs = (a.eap.dfs || []).map(d => d.toUpperCase()).join(', ');
|
||||||
|
rows.push(['EAP', `${a.eap.label || 'EAP'} (${types}) in ${dfs}`]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (f.direction) rows.push(['SMS', f.direction + ' — ' + f.status]);
|
if (f.direction) rows.push(['SMS', f.direction + ' — ' + f.status]);
|
||||||
if (f.message_ids) rows.push(['Message IDs', f.message_ids.join(', ')]);
|
if (f.message_ids) rows.push(['Message IDs', f.message_ids.join(', ')]);
|
||||||
|
|||||||
@@ -2505,7 +2505,8 @@ def _decode_plmn_act(u16):
|
|||||||
|
|
||||||
|
|
||||||
def _decode_dir(raw, p1=None):
|
def _decode_dir(raw, p1=None):
|
||||||
"""EF_DIR record: application template(s) — AID (4F) + label (50)."""
|
"""EF_DIR record: application template(s) — AID (4F) + label (50)
|
||||||
|
+ optional EAP discretionary template (73, TS 102 310)."""
|
||||||
apps = []
|
apps = []
|
||||||
for tag, _length, value in parse_tlv(raw):
|
for tag, _length, value in parse_tlv(raw):
|
||||||
if tag != 0x61:
|
if tag != 0x61:
|
||||||
@@ -2518,11 +2519,40 @@ def _decode_dir(raw, p1=None):
|
|||||||
label = _decode_annex_a(v2)
|
label = _decode_annex_a(v2)
|
||||||
if label:
|
if label:
|
||||||
app['label'] = label
|
app['label'] = label
|
||||||
|
elif t2 == 0x73:
|
||||||
|
eap = _decode_eap_template(v2)
|
||||||
|
if eap:
|
||||||
|
app['eap'] = eap
|
||||||
if app:
|
if app:
|
||||||
apps.append(app)
|
apps.append(app)
|
||||||
return {'applications': apps} if apps else {'raw': raw.hex().upper()}
|
return {'applications': apps} if apps else {'raw': raw.hex().upper()}
|
||||||
|
|
||||||
|
|
||||||
|
# IANA EAP method types seen in TS 102 310 EF_DIR entries.
|
||||||
|
_EAP_TYPES = {
|
||||||
|
18: 'EAP-SIM',
|
||||||
|
23: 'EAP-AKA',
|
||||||
|
50: 'EAP-AKA\'',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _decode_eap_template(value):
|
||||||
|
"""TS 102 310 §5.2: 73 → A0 { 80 EAP types, 81 DF FIDs, 82 label }."""
|
||||||
|
for t2, _l2, v2 in parse_tlv(value):
|
||||||
|
if t2 != 0xA0:
|
||||||
|
continue
|
||||||
|
eap = {}
|
||||||
|
for t3, _l3, v3 in parse_tlv(v2):
|
||||||
|
if t3 == 0x80:
|
||||||
|
eap['eap_types'] = [_EAP_TYPES.get(b, b) for b in v3]
|
||||||
|
elif t3 == 0x81:
|
||||||
|
eap['dfs'] = [v3[i:i + 2].hex() for i in range(0, len(v3), 2)]
|
||||||
|
elif t3 == 0x82:
|
||||||
|
eap['label'] = v3.decode('ascii', 'replace')
|
||||||
|
return eap
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def _decode_arr(raw, p1=None):
|
def _decode_arr(raw, p1=None):
|
||||||
entries = []
|
entries = []
|
||||||
for tag, _length, value in parse_tlv(raw):
|
for tag, _length, value in parse_tlv(raw):
|
||||||
@@ -2829,7 +2859,16 @@ def _file_summary(f):
|
|||||||
if f.get('services'):
|
if f.get('services'):
|
||||||
return f"{len(f['services'])} services allocated"
|
return f"{len(f['services'])} services allocated"
|
||||||
if f.get('applications'):
|
if f.get('applications'):
|
||||||
return '; '.join((a.get('label') or a.get('aid') or '') for a in f['applications'])
|
parts = []
|
||||||
|
for a in f['applications']:
|
||||||
|
s = a.get('label') or a.get('aid') or ''
|
||||||
|
eap = a.get('eap')
|
||||||
|
if eap:
|
||||||
|
types = ', '.join(str(t) for t in eap.get('eap_types', []))
|
||||||
|
dfs = ', '.join(KNOWN_FIDS.get(d, d) for d in eap.get('dfs', []))
|
||||||
|
s += f" [{eap.get('label', 'EAP')}: {types} in {dfs}]"
|
||||||
|
parts.append(s)
|
||||||
|
return '; '.join(parts)
|
||||||
if f.get('tpdu'):
|
if f.get('tpdu'):
|
||||||
t = f['tpdu']
|
t = f['tpdu']
|
||||||
s = t.get('mti', '')
|
s = t.get('mti', '')
|
||||||
|
|||||||
@@ -1019,6 +1019,10 @@ class TestFileDecoders(unittest.TestCase):
|
|||||||
'730ea00c80011781025f408203454150ffffffffffffffffffffffffffffffffffffff'))
|
'730ea00c80011781025f408203454150ffffffffffffffffffffffffffffffffffffff'))
|
||||||
self.assertEqual(f['applications'][0]['label'], 'MegaFon')
|
self.assertEqual(f['applications'][0]['label'], 'MegaFon')
|
||||||
self.assertEqual(f['applications'][0]['aid'], 'A0000000871002FFFFF00189000001FF')
|
self.assertEqual(f['applications'][0]['aid'], 'A0000000871002FFFFF00189000001FF')
|
||||||
|
eap = f['applications'][0]['eap']
|
||||||
|
self.assertEqual(eap['eap_types'], ['EAP-AKA'])
|
||||||
|
self.assertEqual(eap['dfs'], ['5f40'])
|
||||||
|
self.assertEqual(eap['label'], 'EAP')
|
||||||
|
|
||||||
def test_nai_empty_record(self):
|
def test_nai_empty_record(self):
|
||||||
from simtrace2_pysniff.server.decode import _decode_file_data
|
from simtrace2_pysniff.server.decode import _decode_file_data
|
||||||
|
|||||||
Reference in new issue
Block a user