Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-meta.c
Line
Count
Source (jump to first uncovered line)
1
/* Routines for 'Metadata' disassembly
2
 *
3
 * Wireshark - Network traffic analyzer
4
 * By Gerald Combs <gerald@wireshark.org>
5
 * Copyright 1998 Gerald Combs
6
 *
7
 * SPDX-License-Identifier: GPL-2.0-or-later
8
 */
9
10
#include "config.h"
11
12
13
#include <epan/packet.h>
14
#include <wiretap/wtap.h>
15
#include <epan/expert.h>
16
#include <epan/proto_data.h>
17
#include "packet-sscop.h"
18
#include "packet-gsm_a_common.h"
19
20
void proto_register_meta(void);
21
void proto_reg_handoff_meta(void);
22
23
/* schemas */
24
0
#define META_SCHEMA_PCAP        1
25
0
#define META_SCHEMA_DXT         2
26
27
/* protocols */
28
0
#define META_PROTO_DXT_ETHERNET        1
29
0
#define META_PROTO_DXT_ETHERNET_CRC   36
30
0
#define META_PROTO_DXT_ATM            41
31
0
#define META_PROTO_DXT_ERF_AAL5       49
32
#define META_PROTO_DXT_M3UA           61
33
#define META_PROTO_DXT_NBAP           69
34
0
#define META_PROTO_DXT_ATM_AAL2       76
35
0
#define META_PROTO_DXT_FP_HINT        82
36
0
#define META_PROTO_DXT_HDLC          106
37
#define META_PROTO_DXT_CONTAINER     127
38
#define META_PROTO_DXT_FP_CAPTURE    193
39
#define META_PROTO_DXT_UTRAN_CAPSULE 194
40
41
/* data types */
42
#define META_TYPE_NONE             0
43
#define META_TYPE_BOOLEAN          1
44
#define META_TYPE_UINT8            2
45
#define META_TYPE_UINT16           3
46
#define META_TYPE_UINT32           4
47
#define META_TYPE_UINT64           5
48
#define META_TYPE_STRING          16
49
50
/* item ids */
51
#define META_ID_NULL               0
52
0
#define META_ID_DIRECTION          1
53
0
#define META_ID_SIGNALING          2
54
0
#define META_ID_INCOMPLETE         3
55
0
#define META_ID_DECIPHERED         4
56
#define META_ID_PAYLOADCUT         5
57
0
#define META_ID_TIMESTAMP64        6
58
0
#define META_ID_AAL5PROTO          7
59
0
#define META_ID_PHYLINKID        256
60
0
#define META_ID_LOCALDEVID       257
61
0
#define META_ID_REMOTEDEVID      258
62
0
#define META_ID_TAPGROUPID       259
63
0
#define META_ID_IMSI            1024
64
0
#define META_ID_IMEI            1025
65
0
#define META_ID_CELL            1026
66
0
#define META_ID_TLLI            1027
67
0
#define META_ID_NSAPI           1028
68
0
#define META_ID_APN             1029
69
0
#define META_ID_RAT             1030
70
0
#define META_ID_CALLING         1031
71
0
#define META_ID_CALLED          1032
72
73
enum meta_direction {
74
    META_DIR_UP,
75
    META_DIR_DOWN
76
};
77
78
static int proto_meta;
79
extern int proto_sscop;
80
81
/* fields */
82
static int hf_meta_schema;
83
static int hf_meta_hdrlen;
84
static int hf_meta_proto;
85
static int hf_meta_reserved;
86
static int hf_meta_item;
87
static int hf_meta_item_id;
88
static int hf_meta_item_type;
89
static int hf_meta_item_len;
90
static int hf_meta_item_data;
91
/* specific fields */
92
static int hf_meta_item_direction;
93
static int hf_meta_item_ts;
94
static int hf_meta_item_phylinkid;
95
static int hf_meta_item_nsapi;
96
static int hf_meta_item_imsi_value;
97
static int hf_meta_item_imsi_digits;
98
static int hf_meta_item_imei_value;
99
static int hf_meta_item_imei_digits;
100
static int hf_meta_item_signaling;
101
static int hf_meta_item_incomplete;
102
static int hf_meta_item_deciphered;
103
static int hf_meta_item_apn;
104
static int hf_meta_item_rat;
105
static int hf_meta_item_aal5proto;
106
static int hf_meta_item_cell;
107
static int hf_meta_item_localdevid;
108
static int hf_meta_item_remotedevid;
109
static int hf_meta_item_tapgroupid;
110
static int hf_meta_item_tlli;
111
static int hf_meta_item_calling;
112
static int hf_meta_item_called;
113
114
/* subtrees */
115
static int ett_meta;
116
static int ett_meta_item;
117
static int ett_meta_cell;
118
static int ett_meta_imsi;
119
static int ett_meta_imei;
120
121
static expert_field ei_meta_malformed;
122
static expert_field ei_meta_invalid_header;
123
124
/* default handle */
125
static dissector_handle_t data_handle;
126
static dissector_handle_t atm_untrunc_handle;
127
static dissector_handle_t sscf_nni_handle;
128
static dissector_handle_t alcap_handle;
129
static dissector_handle_t nbap_handle;
130
static dissector_handle_t ethwithfcs_handle;
131
static dissector_handle_t ethwithoutfcs_handle;
132
static dissector_handle_t fphint_handle;
133
static dissector_handle_t mtp2_handle;
134
135
static dissector_table_t meta_dissector_table;
136
137
static const value_string meta_schema_vals[] = {
138
    { META_SCHEMA_PCAP,     "PCAP" },
139
    { META_SCHEMA_DXT,      "DXT" },
140
    { 0, NULL }
141
};
142
143
static const value_string meta_proto_vals[] = {
144
    { META_PROTO_DXT_ETHERNET,      "Ethernet without FCS" },
145
    { META_PROTO_DXT_ETHERNET_CRC,  "Ethernet with FCS" },
146
    { META_PROTO_DXT_ATM,           "ATM" },
147
    { META_PROTO_DXT_ERF_AAL5,      "ERF AAL5" },
148
    /* XXX: META_PROTO_DXT_M3UA ? */
149
    /* XXX: META_PROTO_DXT_NBAP ? */
150
    { META_PROTO_DXT_ATM_AAL2,      "ATM AAL2" },
151
    { META_PROTO_DXT_FP_HINT,       "FP Hint" },
152
    { META_PROTO_DXT_HDLC,          "HDLC" },
153
    { META_PROTO_DXT_CONTAINER,     "DXT CONTAINER" },
154
    { META_PROTO_DXT_FP_CAPTURE,    "FP CAPTURE" },
155
    { META_PROTO_DXT_UTRAN_CAPSULE, "UTRAN CAPSULE" },
156
    { 0, NULL }
157
};
158
static value_string_ext meta_proto_vals_ext = VALUE_STRING_EXT_INIT(meta_proto_vals);
159
160
static const value_string meta_type_vals[] = {
161
    { META_TYPE_NONE,       "NONE" },
162
    { META_TYPE_BOOLEAN,    "BOOLEAN" },
163
    { META_TYPE_UINT8,      "UINT8" },
164
    { META_TYPE_UINT16,     "UINT16" },
165
    { META_TYPE_UINT32,     "UINT32" },
166
    { META_TYPE_UINT64,     "UINT64" },
167
    { META_TYPE_STRING,     "STRING" },
168
    { 0, NULL }
169
};
170
171
/* TODO: this must be on a per-schema basis! */
172
static const value_string meta_id_vals[] = {
173
    { META_ID_NULL,         "NULL" },
174
    { META_ID_DIRECTION,    "Direction" },
175
    { META_ID_SIGNALING,    "Signaling" },
176
    { META_ID_INCOMPLETE,   "Incomplete" },
177
    { META_ID_DECIPHERED,   "Deciphered" },
178
    { META_ID_PAYLOADCUT,   "Payload cutted" },
179
    { META_ID_TIMESTAMP64,  "Timestamp" },
180
    { META_ID_AAL5PROTO,    "AAL5 Protocol Type" },
181
    { META_ID_PHYLINKID,    "Physical Link ID" },
182
    { META_ID_LOCALDEVID,   "Local Device ID" },
183
    { META_ID_REMOTEDEVID,  "Remote Device ID" },
184
    { META_ID_TAPGROUPID,   "Tap Group ID" },
185
    { META_ID_IMSI,         "IMSI" },
186
    { META_ID_IMEI,         "IMEI" },
187
    { META_ID_CELL,         "Mobile Cell" },
188
    { META_ID_TLLI,         "TLLI" },
189
    { META_ID_NSAPI,        "NSAPI" },
190
    { META_ID_APN,          "APN" },
191
    { META_ID_RAT,          "RAT" },
192
    { META_ID_CALLING,      "Calling Station ID" },
193
    { META_ID_CALLED,       "Called Station ID" },
194
    { 0, NULL }
195
};
196
static value_string_ext meta_id_vals_ext = VALUE_STRING_EXT_INIT(meta_id_vals);
197
198
0
#define META_AAL5PROTO_MTP3     2
199
0
#define META_AAL5PROTO_NS       3
200
0
#define META_AAL5PROTO_ALCAP    5
201
0
#define META_AAL5PROTO_NBAP     6
202
static const value_string meta_aal5proto_vals[] = {
203
    { META_AAL5PROTO_MTP3,  "SSCOP MTP3" },
204
    { META_AAL5PROTO_ALCAP, "SSCOP ALCAP" },
205
    { META_AAL5PROTO_NBAP,  "SSCOP NBAP" },
206
    { META_AAL5PROTO_NS,    "GPRS NS" },
207
    { 0, NULL }
208
};
209
210
static const value_string meta_direction_vals[] = {
211
    { 0,    "Up" },
212
    { 1,    "Down" },
213
    { 0,    NULL }
214
};
215
216
static uint16_t skip_item(proto_tree *meta_tree, tvbuff_t *tvb, packet_info *pinfo _U_, uint16_t offs)
217
0
{
218
0
    uint16_t    id;
219
0
    uint8_t     type;
220
0
    uint16_t    len, aligned_len, total_len;
221
0
    proto_tree *item_tree;
222
0
    proto_item *subti;
223
224
0
    id          = tvb_get_letohs(tvb, offs); offs += 2;
225
0
    type        = tvb_get_uint8(tvb, offs); offs++;
226
0
    len         = tvb_get_uint8(tvb, offs); offs++;
227
0
    aligned_len = (len + 3) & 0xfffc;
228
0
    total_len   = aligned_len + 4; /* 4: id, type, len fields */
229
230
0
    subti = proto_tree_add_item(meta_tree, hf_meta_item, tvb, offs - 4,
231
0
        aligned_len + 4, ENC_NA);
232
0
    item_tree = proto_item_add_subtree(subti, ett_meta_item);
233
0
    proto_tree_add_uint(item_tree, hf_meta_item_id, tvb, offs - 4, 2, id);
234
0
    proto_tree_add_uint(item_tree, hf_meta_item_type, tvb, offs - 2, 1, type);
235
0
    proto_tree_add_uint(item_tree, hf_meta_item_len,
236
0
        tvb, offs - 1, 1, len);
237
0
    if (len > 0)
238
0
        proto_tree_add_item(item_tree, hf_meta_item_data,
239
0
            tvb, offs, len, ENC_NA);
240
241
0
    return total_len;
242
0
}
243
244
/*
245
* offs: current offset in tvb
246
*/
247
static uint16_t evaluate_meta_item_pcap(proto_tree *meta_tree, tvbuff_t *tvb, packet_info *pinfo, uint16_t offs)
248
0
{
249
0
    uint16_t    id;
250
0
    uint8_t     type;
251
0
    uint16_t    len, aligned_len, total_len;
252
0
    proto_tree *item_tree;
253
0
    proto_item *subti;
254
    /* field values */
255
0
    uint8_t     dir;
256
0
    uint64_t    ts;
257
258
0
    id          = tvb_get_letohs(tvb, offs); offs += 2;
259
0
    type        = tvb_get_uint8(tvb, offs); offs++;
260
0
    len         = tvb_get_uint8(tvb, offs); offs++;
261
0
    aligned_len = (len + 3) & 0xfffc;
262
0
    total_len   = aligned_len + 4; /* 4: id, type, len fields */
263
264
0
    switch (id) {
265
0
        case META_ID_DIRECTION:
266
0
            dir = tvb_get_uint8(tvb, offs);
267
0
            pinfo->p2p_dir = dir == META_DIR_UP ? P2P_DIR_RECV : P2P_DIR_SENT;
268
0
            proto_tree_add_uint(meta_tree, hf_meta_item_direction, tvb, offs, 1, dir);
269
0
            break;
270
0
        case META_ID_TIMESTAMP64:
271
0
            ts = tvb_get_letoh64(tvb, offs);
272
0
            proto_tree_add_uint64(meta_tree, hf_meta_item_ts, tvb, offs, 8, ts);
273
0
            break;
274
0
        case META_ID_SIGNALING:
275
0
            proto_tree_add_boolean(meta_tree, hf_meta_item_signaling, tvb,
276
0
                offs, 0, 1);
277
0
            break;
278
0
        case META_ID_INCOMPLETE:
279
0
            proto_tree_add_boolean(meta_tree, hf_meta_item_incomplete, tvb,
280
0
                offs, 0, 1);
281
0
            break;
282
0
        default:
283
0
            subti = proto_tree_add_item(meta_tree, hf_meta_item, tvb, offs - 4,
284
0
                aligned_len + 4, ENC_NA);
285
0
            item_tree = proto_item_add_subtree(subti, ett_meta_item);
286
0
            proto_tree_add_uint(item_tree, hf_meta_item_id, tvb, offs - 4, 2, id);
287
0
            proto_tree_add_uint(item_tree, hf_meta_item_type, tvb, offs - 2, 1, type);
288
0
            proto_tree_add_uint(item_tree, hf_meta_item_len,
289
0
                tvb, offs - 1, 1, len);
290
0
            if (len > 0)
291
0
                proto_tree_add_item(item_tree, hf_meta_item_data,
292
0
                    tvb, offs, len, ENC_NA);
293
0
    }
294
0
    return total_len;
295
0
}
296
297
/*
298
* offs: current offset in tvb
299
*/
300
static uint16_t evaluate_meta_item_dxt(proto_tree *meta_tree, tvbuff_t *tvb, packet_info *pinfo, uint16_t offs, struct atm_phdr *atm_info)
301
0
{
302
0
    uint16_t            id;
303
0
    uint8_t             type;
304
0
    uint16_t            len, aligned_len, total_len;
305
0
    proto_tree         *item_tree;
306
0
    proto_item         *subti;
307
    /* field values */
308
0
    uint8_t             dir, nsapi, rat, aal5proto;
309
0
    uint16_t            phylinkid, localdevid, remotedevid, tapgroupid;
310
0
    uint32_t            tlli;
311
0
    uint64_t            ts, cell;
312
0
    sscop_payload_info *p_sscop_info;
313
0
    proto_item         *cell_item, *imsi_item, *imei_item;
314
0
    proto_tree         *cell_tree, *imsi_tree, *imei_tree;
315
316
0
    id          = tvb_get_letohs(tvb, offs); offs += 2;
317
0
    type        = tvb_get_uint8(tvb, offs); offs++;
318
0
    len         = tvb_get_uint8(tvb, offs); offs++;
319
0
    aligned_len = (len + 3) & 0xfffc;
320
0
    total_len   = aligned_len + 4; /* 4: id, type, len fields */
321
322
0
    switch (id) {
323
0
        case META_ID_DIRECTION:
324
0
            dir = tvb_get_uint8(tvb, offs);
325
0
            pinfo->p2p_dir = (dir == META_DIR_UP ? P2P_DIR_RECV : P2P_DIR_SENT);
326
0
            proto_tree_add_uint(meta_tree, hf_meta_item_direction, tvb, offs, 1, dir);
327
0
            break;
328
0
        case META_ID_TIMESTAMP64:
329
0
            ts = tvb_get_letoh64(tvb, offs);
330
0
            proto_tree_add_uint64(meta_tree, hf_meta_item_ts, tvb, offs, 8, ts);
331
0
            break;
332
0
        case META_ID_PHYLINKID:
333
0
            phylinkid = tvb_get_letohs(tvb, offs);
334
0
            pinfo->link_number = phylinkid;
335
0
            proto_tree_add_uint(meta_tree, hf_meta_item_phylinkid, tvb,
336
0
                offs, 2, phylinkid);
337
0
            break;
338
0
        case META_ID_NSAPI:
339
0
            nsapi = tvb_get_uint8(tvb, offs);
340
0
            proto_tree_add_uint(meta_tree, hf_meta_item_nsapi, tvb,
341
0
                offs, 1, nsapi);
342
0
            break;
343
0
        case META_ID_IMSI:
344
0
            imsi_item = proto_tree_add_item(meta_tree, hf_meta_item_imsi_digits, tvb,
345
0
                offs, 8, ENC_BCD_DIGITS_0_9|ENC_LITTLE_ENDIAN);
346
0
            imsi_tree = proto_item_add_subtree(imsi_item, ett_meta_imsi);
347
0
            proto_tree_add_item(imsi_tree, hf_meta_item_imsi_value,
348
0
                tvb, offs, 8, ENC_LITTLE_ENDIAN);
349
0
            break;
350
0
        case META_ID_IMEI:
351
0
            imei_item = proto_tree_add_item(meta_tree, hf_meta_item_imei_digits, tvb,
352
0
                offs, 8, ENC_BCD_DIGITS_0_9|ENC_LITTLE_ENDIAN);
353
0
            imei_tree = proto_item_add_subtree(imei_item, ett_meta_imei);
354
0
            proto_tree_add_item(imei_tree, hf_meta_item_imei_value,
355
0
                tvb, offs, 8, ENC_LITTLE_ENDIAN);
356
0
            break;
357
0
        case META_ID_APN:
358
0
            proto_tree_add_item(meta_tree, hf_meta_item_apn, tvb,
359
0
                offs, len, ENC_ASCII);
360
0
            break;
361
0
        case META_ID_RAT:
362
0
            rat = tvb_get_uint8(tvb, offs);
363
0
            proto_tree_add_uint(meta_tree, hf_meta_item_rat, tvb,
364
0
                offs, 1, rat);
365
0
            break;
366
0
        case META_ID_CELL:
367
0
            cell = tvb_get_ntoh64(tvb, offs);
368
0
            cell_item = proto_tree_add_uint64_format(meta_tree, hf_meta_item_cell,
369
0
                                                     tvb, offs, 8, cell, "Mobile Cell");
370
0
            cell_tree = proto_item_add_subtree(cell_item, ett_meta_cell);
371
0
            de_gmm_rai(tvb, cell_tree, pinfo, offs, 8, NULL, 0);
372
0
            de_cell_id(tvb, cell_tree, pinfo, offs + 6, 2, NULL, 0);
373
0
            break;
374
0
        case META_ID_SIGNALING:
375
0
            proto_tree_add_boolean(meta_tree, hf_meta_item_signaling, tvb,
376
0
                                   offs, 0, 1);
377
0
            break;
378
0
        case META_ID_INCOMPLETE:
379
0
            proto_tree_add_boolean(meta_tree, hf_meta_item_incomplete, tvb,
380
0
                offs, 0, 1);
381
0
            break;
382
0
        case META_ID_DECIPHERED:
383
0
            proto_tree_add_boolean(meta_tree, hf_meta_item_deciphered, tvb,
384
0
                offs, 0, 1);
385
0
            break;
386
0
        case META_ID_AAL5PROTO:
387
0
            aal5proto    = tvb_get_uint8(tvb, offs);
388
0
            p_sscop_info = (sscop_payload_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_sscop, 0);
389
0
            if (!p_sscop_info) {
390
0
                p_sscop_info = wmem_new0(wmem_file_scope(), sscop_payload_info);
391
0
                p_add_proto_data(wmem_file_scope(), pinfo, proto_sscop, 0, p_sscop_info);
392
0
            }
393
0
            switch (aal5proto) {
394
0
                case META_AAL5PROTO_MTP3:
395
0
                    p_sscop_info->subdissector = sscf_nni_handle;
396
                    /* hint for ATM dissector that this frame contains SSCOP */
397
0
                    memset(atm_info, 0, sizeof(*atm_info));
398
0
                    atm_info->type = TRAF_SSCOP;
399
0
                    break;
400
0
                case META_AAL5PROTO_ALCAP:
401
0
                    p_sscop_info->subdissector = alcap_handle;
402
0
                    break;
403
0
                case META_AAL5PROTO_NBAP:
404
0
                    p_sscop_info->subdissector = nbap_handle;
405
0
                    break;
406
0
                case META_AAL5PROTO_NS:
407
                    /* hint for ATM dissector that this frame contains GPRS NS */
408
0
                    memset(atm_info, 0, sizeof(*atm_info));
409
0
                    atm_info->type = TRAF_GPRS_NS;
410
0
                    break;
411
                /* TODO: check for additional protos on Iu 802 LLC/SNAP ... */
412
0
                default:
413
                    /* TODO: add warning */
414
0
                    p_remove_proto_data(wmem_file_scope(), pinfo, proto_sscop, 0);
415
0
            }
416
0
            proto_tree_add_uint(meta_tree, hf_meta_item_aal5proto, tvb,
417
0
                offs, 1, aal5proto);
418
0
            break;
419
0
        case META_ID_LOCALDEVID:
420
0
            localdevid = tvb_get_letohs(tvb, offs);
421
0
            proto_tree_add_uint(meta_tree, hf_meta_item_localdevid, tvb,
422
0
                offs, 2, localdevid);
423
0
            break;
424
0
        case META_ID_REMOTEDEVID:
425
0
            remotedevid = tvb_get_letohs(tvb, offs);
426
0
            proto_tree_add_uint(meta_tree, hf_meta_item_remotedevid, tvb,
427
0
                offs, 2, remotedevid);
428
0
            break;
429
0
        case META_ID_TAPGROUPID:
430
0
            tapgroupid = tvb_get_letohs(tvb, offs);
431
0
            proto_tree_add_uint(meta_tree, hf_meta_item_tapgroupid, tvb,
432
0
                offs, 2, tapgroupid);
433
0
            break;
434
0
        case META_ID_TLLI:
435
0
            tlli = tvb_get_letohs(tvb, offs);
436
0
            proto_tree_add_uint(meta_tree, hf_meta_item_tlli, tvb,
437
0
                offs, 4, tlli);
438
0
            break;
439
0
        case META_ID_CALLING:
440
0
            proto_tree_add_item(meta_tree, hf_meta_item_calling, tvb,
441
0
                offs, len, ENC_ASCII);
442
0
            break;
443
0
        case META_ID_CALLED:
444
0
            proto_tree_add_item(meta_tree, hf_meta_item_called, tvb,
445
0
                offs, len, ENC_ASCII);
446
0
            break;
447
0
        default:
448
0
            subti = proto_tree_add_item(meta_tree, hf_meta_item, tvb, offs - 4,
449
0
                aligned_len + 4, ENC_NA);
450
0
            item_tree = proto_item_add_subtree(subti, ett_meta_item);
451
0
            proto_tree_add_uint(item_tree, hf_meta_item_id, tvb, offs - 4, 2, id);
452
0
            proto_tree_add_uint(item_tree, hf_meta_item_type, tvb, offs - 2, 1, type);
453
0
            proto_tree_add_uint(item_tree, hf_meta_item_len,
454
0
                tvb, offs - 1, 1, len);
455
0
            if (len > 0)
456
0
                proto_tree_add_item(item_tree, hf_meta_item_data,
457
0
                    tvb, offs, len, ENC_NA);
458
0
    }
459
0
    return total_len;
460
0
}
461
462
/*
463
 * offs: current offset within tvb
464
 * header_length: length of meta header
465
 */
466
static int32_t evaluate_meta_items(uint16_t schema, tvbuff_t *tvb, packet_info *pinfo,
467
    proto_tree *meta_tree, uint16_t offs, int32_t header_length,
468
    struct atm_phdr *atm_info)
469
0
{
470
0
    int16_t item_len;
471
0
    int32_t total_len = 0;
472
473
0
    while (total_len < header_length) {
474
0
        switch (schema) {
475
0
            case META_SCHEMA_DXT:
476
0
                item_len = evaluate_meta_item_dxt(meta_tree, tvb, pinfo, offs + total_len, atm_info);
477
0
                break;
478
0
            case META_SCHEMA_PCAP:
479
0
                item_len = evaluate_meta_item_pcap(meta_tree, tvb, pinfo, offs + total_len);
480
0
                break;
481
0
            default:
482
0
                item_len = skip_item(meta_tree, tvb, pinfo, offs + total_len);
483
0
        }
484
0
        if (item_len < 4) { /* 4 is the minimum length of an item: id + type + length field */
485
0
            expert_add_info_format(pinfo, meta_tree, &ei_meta_malformed,
486
0
                "Malformed Packet %s (wrong item encoding)", pinfo->current_proto);
487
0
            return -1;
488
0
        }
489
0
        total_len += item_len;
490
0
    }
491
0
    return total_len;
492
0
}
493
494
static int
495
dissect_meta(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
496
0
{
497
0
#define META_HEADER_SIZE 8
498
0
    uint16_t            schema, proto, hdrlen, reserved;
499
0
    int32_t             item_len;
500
0
    uint32_t            aal2_ext, atm_hdr;
501
0
    proto_tree         *meta_tree      = NULL;
502
0
    proto_item         *ti             = NULL;
503
0
    tvbuff_t           *next_tvb       = NULL;
504
0
    dissector_handle_t  next_dissector = data_handle;
505
0
    void               *next_dissector_data = NULL;
506
0
    struct atm_phdr     atm_info;
507
508
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "META");
509
510
0
    schema   = tvb_get_letohs(tvb, 0);
511
0
    hdrlen   = tvb_get_letohs(tvb, 2);
512
0
    proto    = tvb_get_letohs(tvb, 4);
513
0
    reserved = tvb_get_letohs(tvb, 6);
514
515
0
    if (tree) {
516
0
        ti = proto_tree_add_item(tree, proto_meta, tvb, 0, hdrlen + 4, ENC_NA);
517
0
        meta_tree = proto_item_add_subtree(ti, ett_meta);
518
0
        proto_tree_add_uint(meta_tree, hf_meta_schema, tvb, 0, 2, schema);
519
0
        proto_tree_add_uint(meta_tree, hf_meta_hdrlen, tvb, 2, 2, hdrlen);
520
0
        proto_tree_add_uint(meta_tree, hf_meta_proto, tvb, 4, 2, proto);
521
0
        proto_tree_add_uint(meta_tree, hf_meta_reserved, tvb, 6, 2, reserved);
522
0
    }
523
0
    item_len = evaluate_meta_items(schema, tvb, pinfo, meta_tree, META_HEADER_SIZE, hdrlen, &atm_info);
524
525
0
    if (item_len < 0) {
526
        /* evaluate_meta_items signalled an error */
527
0
        return META_HEADER_SIZE; /* stop parsing */
528
0
    }
529
530
0
    if (hdrlen != item_len) {
531
0
        expert_add_info(pinfo, ti, &ei_meta_invalid_header);
532
0
        return META_HEADER_SIZE;
533
0
    }
534
535
    /* find next subdissector based on the chosen schema */
536
0
    switch (schema) {
537
0
        case META_SCHEMA_PCAP:
538
            /* TODO */
539
0
            break;
540
0
        case META_SCHEMA_DXT:
541
0
            switch (proto) {
542
0
                case META_PROTO_DXT_ETHERNET:
543
0
                    next_dissector = ethwithoutfcs_handle;
544
0
                    break;
545
0
                case META_PROTO_DXT_ETHERNET_CRC:
546
0
                    next_dissector = ethwithfcs_handle;
547
0
                    break;
548
0
                case META_PROTO_DXT_FP_HINT:
549
0
                    next_dissector = fphint_handle;
550
0
                    break;
551
0
                case META_PROTO_DXT_ATM:
552
0
                    memset(&atm_info, 0, sizeof atm_info);
553
0
                    atm_info.aal  = AAL_OAMCELL;
554
0
                    atm_info.type = TRAF_UNKNOWN;
555
0
                    next_dissector = atm_untrunc_handle;
556
0
                    next_dissector_data = &atm_info;
557
0
                    break;
558
0
                case META_PROTO_DXT_ATM_AAL2:
559
0
                    aal2_ext = tvb_get_ntohl(tvb, item_len + META_HEADER_SIZE); item_len += 4;
560
0
                    atm_hdr  = tvb_get_ntohl(tvb, item_len + META_HEADER_SIZE); item_len += 4;
561
0
                    memset(&atm_info, 0, sizeof(atm_info));
562
0
                    atm_info.aal = AAL_2;
563
                    /* atm_info.flags = pinfo->p2p_dir; */
564
0
                    atm_info.vpi  = ((atm_hdr & 0x0ff00000) >> 20);
565
0
                    atm_info.vci  = ((atm_hdr & 0x000ffff0) >>  4);
566
0
                    atm_info.aal2_cid = aal2_ext & 0x000000ff;
567
0
                    atm_info.type = TRAF_UMTS_FP;
568
0
                    next_dissector = atm_untrunc_handle;
569
0
                    next_dissector_data = &atm_info;
570
0
                    break;
571
0
                case META_PROTO_DXT_ERF_AAL5:
572
0
                    atm_hdr = tvb_get_ntohl(tvb, item_len + META_HEADER_SIZE); item_len += 4;
573
0
                    atm_info.vpi = ((atm_hdr & 0x0ff00000) >> 20);
574
0
                    atm_info.vci = ((atm_hdr & 0x000ffff0) >>  4);
575
0
                    atm_info.aal = AAL_5;
576
0
                    next_dissector = atm_untrunc_handle;
577
0
                    next_dissector_data = &atm_info;
578
0
                    break;
579
0
                case META_PROTO_DXT_HDLC:
580
0
                    next_dissector = mtp2_handle;
581
0
                    next_tvb = tvb_new_subset_length_caplen(tvb, item_len + META_HEADER_SIZE,
582
0
                        tvb_reported_length(tvb)-item_len-META_HEADER_SIZE-2, -1);
583
0
                    break;
584
0
                default:
585
0
                    next_dissector =
586
0
                        dissector_get_uint_handle(meta_dissector_table, proto);
587
0
            }
588
0
    }
589
0
    if (!next_tvb)
590
0
        next_tvb = tvb_new_subset_remaining(tvb, item_len + META_HEADER_SIZE);
591
592
0
    call_dissector_with_data(next_dissector, next_tvb, pinfo, tree,
593
0
                             next_dissector_data);
594
0
    return tvb_captured_length(tvb);
595
0
}
596
597
void
598
proto_register_meta(void)
599
14
{
600
14
    static hf_register_info hf[] = {
601
        /* metadata header */
602
14
        { &hf_meta_schema,
603
14
          { "Schema", "meta.schema",
604
14
            FT_UINT16, BASE_DEC, VALS(meta_schema_vals), 0,
605
14
            NULL, HFILL }
606
14
        },
607
14
        { &hf_meta_hdrlen,
608
14
          { "Header Length", "meta.hdrlen",
609
14
            FT_UINT16, BASE_DEC, NULL, 0,
610
14
            NULL, HFILL }
611
14
        },
612
14
        { &hf_meta_proto,
613
14
          { "Protocol", "meta.proto",
614
14
            FT_UINT16, BASE_DEC | BASE_EXT_STRING, &meta_proto_vals_ext, 0,
615
14
            NULL, HFILL }
616
14
        },
617
14
        { &hf_meta_reserved,
618
14
          { "Reserved", "meta.reserved",
619
14
            FT_UINT16, BASE_HEX, NULL, 0,
620
14
            NULL, HFILL }
621
14
        },
622
623
        /* general meta item */
624
14
        { &hf_meta_item,
625
14
          { "Unknown Item", "meta.item",
626
14
            FT_NONE, BASE_NONE, NULL, 0,
627
14
            NULL, HFILL }
628
14
        },
629
14
        { &hf_meta_item_id,
630
14
          { "Item ID", "meta.item.id",
631
14
            FT_UINT16, BASE_HEX | BASE_EXT_STRING, &meta_id_vals_ext, 0x0,
632
14
            NULL, HFILL }
633
14
        },
634
14
        { &hf_meta_item_type,
635
14
          { "Item Type", "meta.item.type",
636
14
            FT_UINT8, BASE_HEX, VALS(meta_type_vals), 0x0,
637
14
            NULL, HFILL }
638
14
        },
639
14
        { &hf_meta_item_len,
640
14
          { "Item Length", "meta.item.len",
641
14
            FT_UINT8, BASE_DEC, NULL, 0,
642
14
            NULL, HFILL }
643
14
        },
644
14
        { &hf_meta_item_data,
645
14
          { "Item Data", "meta.item.data",
646
14
            FT_BYTES, BASE_NONE, NULL, 0x0,
647
14
            NULL, HFILL }
648
14
        },
649
650
        /* specific meta items */
651
14
        { &hf_meta_item_direction,
652
14
          { "Direction", "meta.direction",
653
14
            FT_UINT8, BASE_DEC, VALS(meta_direction_vals), 0,
654
14
            NULL, HFILL }
655
14
        },
656
14
        { &hf_meta_item_ts,
657
14
          { "Timestamp", "meta.timestamp",
658
14
            FT_UINT64, BASE_DEC, NULL, 0,
659
14
            NULL, HFILL }
660
14
        },
661
14
        { &hf_meta_item_phylinkid,
662
14
          { "Physical Link ID", "meta.phylinkid",
663
14
            FT_UINT16, BASE_DEC, NULL, 0,
664
14
            NULL, HFILL }
665
14
        },
666
14
        { &hf_meta_item_nsapi,
667
14
          { "NSAPI", "meta.nsapi",
668
14
            FT_UINT8, BASE_DEC, NULL, 0,
669
14
            NULL, HFILL }
670
14
        },
671
14
        { &hf_meta_item_imsi_digits,
672
14
          { "IMSI digits", "meta.imsi_digits",
673
14
            FT_STRING, BASE_NONE, NULL, 0,
674
14
            NULL, HFILL }
675
14
        },
676
14
        { &hf_meta_item_imsi_value,
677
14
          { "IMSI value", "meta.imsi_value",
678
14
            FT_UINT64, BASE_HEX, NULL, 0,
679
14
            NULL, HFILL }
680
14
        },
681
14
        { &hf_meta_item_imei_digits,
682
14
          { "IMEI digits", "meta.imei_digits",
683
14
            FT_STRING, BASE_NONE, NULL, 0,
684
14
            NULL, HFILL }
685
14
        },
686
14
        { &hf_meta_item_imei_value,
687
14
          { "IMEI value", "meta.imei_value",
688
14
            FT_UINT64, BASE_HEX, NULL, 0,
689
14
            NULL, HFILL }
690
14
        },
691
14
        { &hf_meta_item_signaling,
692
14
          { "Signaling", "meta.signaling",
693
14
            FT_BOOLEAN, BASE_NONE, NULL, 0,
694
14
            NULL, HFILL }
695
14
        },
696
14
        { &hf_meta_item_incomplete,
697
14
          { "Incomplete", "meta.incomplete",
698
14
            FT_BOOLEAN, BASE_NONE, NULL, 0,
699
14
            NULL, HFILL }
700
14
        },
701
14
        { &hf_meta_item_deciphered,
702
14
          { "Deciphered", "meta.deciphered",
703
14
            FT_BOOLEAN, BASE_NONE, NULL, 0,
704
14
            NULL, HFILL }
705
14
        },
706
14
        { &hf_meta_item_apn,
707
14
          { "APN", "meta.apn",
708
14
            FT_STRINGZ, BASE_NONE, NULL, 0,
709
14
            NULL, HFILL }
710
14
        },
711
14
        { &hf_meta_item_rat,
712
14
          { "RAT", "meta.rat",
713
14
            FT_UINT8, BASE_DEC, NULL, 0,
714
14
            NULL, HFILL }
715
14
        },
716
14
        { &hf_meta_item_aal5proto,
717
14
          { "AAL5 Protocol Type", "meta.aal5proto",
718
14
            FT_UINT8, BASE_DEC, VALS(meta_aal5proto_vals), 0,
719
14
            NULL, HFILL }
720
14
        },
721
14
        { &hf_meta_item_cell,
722
14
          { "Mobile Cell", "meta.cell",
723
14
            FT_UINT64, BASE_HEX, NULL, 0,
724
14
            NULL, HFILL }
725
14
        },
726
727
14
        { &hf_meta_item_localdevid,
728
14
          { "Local Device ID", "meta.localdevid",
729
14
            FT_UINT16, BASE_DEC, NULL, 0,
730
14
            NULL, HFILL }
731
14
        },
732
14
        { &hf_meta_item_remotedevid,
733
14
          { "Remote Device ID", "meta.remotedevid",
734
14
            FT_UINT16, BASE_DEC, NULL, 0,
735
14
            NULL, HFILL }
736
14
        },
737
14
        { &hf_meta_item_tapgroupid,
738
14
          { "Tap Group ID", "meta.tapgroupid",
739
14
            FT_UINT16, BASE_DEC, NULL, 0,
740
14
            NULL, HFILL }
741
14
        },
742
14
        { &hf_meta_item_tlli,
743
14
          { "TLLI", "meta.tlli",
744
14
            FT_UINT32, BASE_DEC, NULL, 0,
745
14
            NULL, HFILL }
746
14
        },
747
14
        { &hf_meta_item_calling,
748
14
          { "Calling Station ID", "meta.calling",
749
14
            FT_STRINGZ, BASE_NONE, NULL, 0,
750
14
            NULL, HFILL }
751
14
        },
752
14
        { &hf_meta_item_called,
753
14
          { "Called Station ID", "meta.called",
754
14
            FT_STRINGZ, BASE_NONE, NULL, 0,
755
14
            NULL, HFILL }
756
14
        },
757
14
    };
758
759
14
    static int *ett[] = {
760
14
        &ett_meta,
761
14
        &ett_meta_item,
762
14
        &ett_meta_cell,
763
14
        &ett_meta_imsi,
764
14
        &ett_meta_imei
765
14
    };
766
767
14
    static ei_register_info ei[] = {
768
14
        { &ei_meta_malformed, { "meta.malformed", PI_MALFORMED, PI_ERROR, "Malformed data", EXPFILL }},
769
14
        { &ei_meta_invalid_header, { "meta.invalid_header_length", PI_MALFORMED, PI_ERROR, "Invalid Header Length", EXPFILL }},
770
14
    };
771
772
14
    expert_module_t* expert_meta;
773
774
14
    proto_meta = proto_register_protocol("Metadata", "META", "meta");
775
14
    register_dissector("meta", dissect_meta, proto_meta);
776
777
14
    proto_register_field_array(proto_meta, hf, array_length(hf));
778
14
    proto_register_subtree_array(ett, array_length(ett));
779
14
    expert_meta = expert_register_protocol(proto_meta);
780
14
    expert_register_field_array(expert_meta, ei, array_length(ei));
781
782
14
    meta_dissector_table = register_dissector_table("meta.proto",
783
14
            "META protocol", proto_meta, FT_UINT16, BASE_DEC);
784
14
}
785
786
void
787
proto_reg_handoff_meta(void)
788
14
{
789
#if 0   /* enable once WTAP_ENCAP_META exists */
790
    dissector_handle_t meta_handle;
791
792
    meta_handle          = find_dissector("meta");
793
    dissector_add_uint("wtap_encap", WTAP_ENCAP_META, meta_handle);
794
#endif
795
14
    data_handle          = find_dissector("data");
796
14
    alcap_handle         = find_dissector_add_dependency("alcap", proto_meta);
797
14
    atm_untrunc_handle   = find_dissector_add_dependency("atm_untruncated", proto_meta);
798
14
    nbap_handle          = find_dissector_add_dependency("nbap", proto_meta);
799
14
    sscf_nni_handle      = find_dissector_add_dependency("sscf-nni", proto_meta);
800
14
    ethwithfcs_handle    = find_dissector_add_dependency("eth_withfcs", proto_meta);
801
14
    ethwithoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_meta);
802
14
    fphint_handle        = find_dissector_add_dependency("fp_hint", proto_meta);
803
14
    mtp2_handle          = find_dissector_add_dependency("mtp2", proto_meta);
804
14
}
805
806
/*
807
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
808
 *
809
 * Local variables:
810
 * c-basic-offset: 4
811
 * tab-width: 8
812
 * indent-tabs-mode: nil
813
 * End:
814
 *
815
 * vi: set shiftwidth=4 tabstop=8 expandtab:
816
 * :indentSize=4:tabSize=8:noTabs=true:
817
 */