Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-exported_pdu.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-exported_pdu.c
2
 * Routines for exported_pdu dissection
3
 * Copyright 2013, Anders Broman <anders-broman@ericsson.com>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include <epan/packet.h>
15
#include <wiretap/wtap.h>
16
#include <epan/address_types.h>
17
#include <epan/exported_pdu.h>
18
#include <epan/expert.h>
19
#include <wsutil/array.h>
20
#include "packet-e212.h"
21
#include "packet-mtp3.h"
22
#include "packet-dvbci.h"
23
#include "packet-tcp.h"
24
25
void proto_register_exported_pdu(void);
26
void proto_reg_handoff_exported_pdu(void);
27
28
static int hf_ip_addr;
29
static int hf_ip_dst;
30
static int hf_ip_src;
31
static int hf_ipv6_addr;
32
static int hf_ipv6_dst;
33
static int hf_ipv6_src;
34
35
static int proto_exported_pdu;
36
static int hf_exported_pdu_tag;
37
static int hf_exported_pdu_tag_len;
38
static int hf_exported_pdu_unknown_tag_val;
39
static int hf_exported_pdu_prot_name;
40
static int hf_exported_pdu_heur_prot_name;
41
static int hf_exported_pdu_dis_table_name;
42
static int hf_exported_pdu_p2p_dir;
43
static int hf_exported_pdu_dissector_data;
44
static int hf_exported_pdu_ddata_version;
45
static int hf_exported_pdu_ddata_seq;
46
static int hf_exported_pdu_ddata_nxtseq;
47
static int hf_exported_pdu_ddata_lastackseq;
48
static int hf_exported_pdu_ddata_is_reassembled;
49
static int hf_exported_pdu_ddata_flags;
50
static int hf_exported_pdu_ddata_urgent_pointer;
51
static int hf_exported_pdu_ipv4_src;
52
static int hf_exported_pdu_ipv4_dst;
53
static int hf_exported_pdu_ipv6_src;
54
static int hf_exported_pdu_ipv6_dst;
55
static int hf_exported_pdu_port_type;
56
static int hf_exported_pdu_src_port;
57
static int hf_exported_pdu_dst_port;
58
/** static int hf_exported_pdu_sctp_ppid; **/
59
static int hf_exported_pdu_ss7_opc;
60
static int hf_exported_pdu_ss7_dpc;
61
static int hf_exported_pdu_orig_fno;
62
static int hf_exported_pdu_dvbci_evt;
63
static int hf_exported_pdu_exported_pdu;
64
static int hf_exported_pdu_dis_table_val;
65
static int hf_exported_pdu_col_proto_str;
66
static int hf_exported_pdu_col_info_str;
67
static int hf_exported_pdu_3gpp_id_type;
68
static int hf_exported_pdu_3gpp_lac;
69
static int hf_exported_pdu_3gpp_ci;
70
static int hf_exported_pdu_3gpp_eci;
71
static int hf_exported_pdu_3gpp_nci;
72
static int hf_exported_pdu_3gpp_cgi;
73
static int hf_exported_pdu_3gpp_ecgi;
74
static int hf_exported_pdu_3gpp_ncgi;
75
76
/* Initialize the subtree pointers */
77
static int ett_exported_pdu;
78
static int ett_exported_pdu_tag;
79
static int ett_exported_pdu_3gpp_cgi;
80
81
static int ss7pc_address_type = -1;
82
83
static dissector_handle_t exported_pdu_handle;
84
85
static expert_field ei_exported_pdu_unsupported_version;
86
static expert_field ei_exported_pdu_unknown_tag;
87
static expert_field ei_exported_pdu_unexpected_tag_length;
88
89
static const char *user_data_pdu = "data";
90
91
0
#define EXPORTED_PDU_NEXT_DISSECTOR_STR      0
92
0
#define EXPORTED_PDU_NEXT_HEUR_DISSECTOR_STR 1
93
0
#define EXPORTED_PDU_NEXT_DIS_TABLE_STR      2
94
95
static const value_string exported_pdu_tag_vals[] = {
96
   { EXP_PDU_TAG_END_OF_OPT,       "End-of-options" },
97
/* 1 - 9 reserved */
98
   { EXP_PDU_TAG_OPTIONS_LENGTH,        "Total length of the options excluding this TLV" },
99
   { EXP_PDU_TAG_LINKTYPE,              "Linktype value" },
100
   { EXP_PDU_TAG_DISSECTOR_NAME,        "PDU content dissector name" },
101
   { EXP_PDU_TAG_HEUR_DISSECTOR_NAME,   "PDU content heuristic dissector name" },
102
   { EXP_PDU_TAG_DISSECTOR_TABLE_NAME,  "PDU content dissector table name" },
103
    /* Add protocol type related tags here */
104
/* 14 - 19 reserved */
105
   { EXP_PDU_TAG_IPV4_SRC,              "IPv4 Source Address" },
106
   { EXP_PDU_TAG_IPV4_DST,              "IPv4 Destination Address" },
107
   { EXP_PDU_TAG_IPV6_SRC,              "IPv6 Source Address" },
108
   { EXP_PDU_TAG_IPV6_DST,              "IPv6 Destination Address" },
109
110
   { EXP_PDU_TAG_PORT_TYPE,             "Port Type" },
111
   { EXP_PDU_TAG_SRC_PORT,              "Source Port" },
112
   { EXP_PDU_TAG_DST_PORT,              "Destination Port" },
113
114
   { EXP_PDU_TAG_SS7_OPC,               "SS7 OPC" },
115
   { EXP_PDU_TAG_SS7_DPC,               "SS7 DPC" },
116
117
   { EXP_PDU_TAG_ORIG_FNO,              "Original Frame number" },
118
119
   { EXP_PDU_TAG_DVBCI_EVT,             "DVB-CI event" },
120
   { EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL,  "Dissector table value" },
121
   { EXP_PDU_TAG_COL_PROT_TEXT,         "Column Protocol String" },
122
   { EXP_PDU_TAG_TCP_INFO_DATA,         "TCP Dissector Data" },
123
   { EXP_PDU_TAG_P2P_DIRECTION,         "P2P direction" },
124
   { EXP_PDU_TAG_COL_INFO_TEXT,         "Column Information String" },
125
   { EXP_PDU_TAG_USER_DATA_PDU,         "User Data PDU" },
126
   { EXP_PDU_TAG_3GPP_ID,               "3GPP Identity" },
127
128
   { 0,        NULL   }
129
};
130
131
static const value_string exported_pdu_port_type_vals[] = {
132
   { EXP_PDU_PT_NONE,     "NONE" },
133
   { EXP_PDU_PT_SCTP,     "SCTP" },
134
   { EXP_PDU_PT_TCP,      "TCP" },
135
   { EXP_PDU_PT_UDP,      "UDP" },
136
   { EXP_PDU_PT_DCCP,     "DCCP" },
137
   { EXP_PDU_PT_IPX,      "IPX" },
138
   { EXP_PDU_PT_NCP,      "NCP" },
139
   { EXP_PDU_PT_EXCHG,    "FC EXCHG" },
140
   { EXP_PDU_PT_DDP,      "DDP" },
141
   { EXP_PDU_PT_SBCCS,    "FICON SBCCS" },
142
   { EXP_PDU_PT_IDP,      "IDP" },
143
   { EXP_PDU_PT_TIPC,     "TIPC" },
144
   { EXP_PDU_PT_USB,      "USB" },
145
   { EXP_PDU_PT_I2C,      "I2C" },
146
   { EXP_PDU_PT_IBQP,     "IBQP" },
147
   { EXP_PDU_PT_BLUETOOTH,"BLUETOOTH" },
148
   { EXP_PDU_PT_TDMOP,    "TDMOP" },
149
   { EXP_PDU_PT_IWARP_MPA,"IWARP_MPA" },
150
151
   { 0,        NULL   }
152
};
153
154
static const value_string exported_pdu_p2p_dir_vals[] = {
155
    { P2P_DIR_SENT, "Sent" },
156
    { P2P_DIR_RECV, "Received" },
157
    { P2P_DIR_UNKNOWN, "Unknown" },
158
    { 0, NULL }
159
};
160
161
static const value_string exported_pdu_3gpp_id_type_vals[] = {
162
   { EXP_PDU_3GPP_ID_CGI,  "CGI" },
163
   { EXP_PDU_3GPP_ID_ECGI, "ECGI" },
164
   { EXP_PDU_3GPP_ID_NCGI, "NCGI" },
165
   { 0, NULL }
166
};
167
168
static port_type exp_pdu_port_type_to_ws_port_type(uint32_t type)
169
0
{
170
0
    switch (type)
171
0
    {
172
0
    case EXP_PDU_PT_NONE:
173
0
        return PT_NONE;
174
0
    case EXP_PDU_PT_SCTP:
175
0
        return PT_SCTP;
176
0
    case EXP_PDU_PT_TCP:
177
0
        return PT_TCP;
178
0
    case EXP_PDU_PT_UDP:
179
0
        return PT_UDP;
180
0
    case EXP_PDU_PT_DCCP:
181
0
        return PT_DCCP;
182
0
    case EXP_PDU_PT_IPX:
183
0
        return PT_IPX;
184
0
    case EXP_PDU_PT_DDP:
185
0
        return PT_DDP;
186
0
    case EXP_PDU_PT_IDP:
187
0
        return PT_IDP;
188
0
    case EXP_PDU_PT_USB:
189
0
        return PT_USB;
190
0
    case EXP_PDU_PT_I2C:
191
0
        return PT_I2C;
192
0
    case EXP_PDU_PT_IBQP:
193
0
        return PT_IBQP;
194
0
    case EXP_PDU_PT_BLUETOOTH:
195
0
        return PT_BLUETOOTH;
196
0
    case EXP_PDU_PT_EXCHG:
197
0
    case EXP_PDU_PT_TIPC:
198
0
    case EXP_PDU_PT_TDMOP:
199
0
    case EXP_PDU_PT_NCP:
200
0
    case EXP_PDU_PT_SBCCS:
201
        //no longer supported
202
0
        break;
203
0
    }
204
205
0
    DISSECTOR_ASSERT(false);
206
0
    return PT_NONE;
207
0
}
208
209
static void
210
dissect_3gpp_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tag_tree, int offset, int tag_len)
211
0
{
212
0
    proto_item *cgi_item;
213
0
    proto_tree *cgi_tree;
214
0
    uint32_t ci_type;
215
0
    int bit_offset = offset * 8;
216
0
    if (tag_len == 0){
217
0
        proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, 0);
218
0
        return;
219
0
    }
220
0
    proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_3gpp_id_type, tvb, offset, 1, ENC_BIG_ENDIAN, &ci_type);
221
0
    offset += 1;
222
0
    bit_offset += 8;
223
0
    switch (ci_type) {
224
0
        case EXP_PDU_3GPP_ID_CGI:
225
0
            if (tag_len < 8) {
226
0
                proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, tag_len);
227
0
            } else {
228
0
                cgi_item = proto_tree_add_bits_item(tag_tree, hf_exported_pdu_3gpp_cgi, tvb, bit_offset, 56, ENC_BIG_ENDIAN);
229
0
                cgi_tree = proto_item_add_subtree(cgi_item, ett_exported_pdu_3gpp_cgi);
230
0
                offset = dissect_e212_mcc_mnc(tvb, pinfo, cgi_tree, offset, E212_CGI, false);
231
0
                proto_tree_add_item(cgi_tree, hf_exported_pdu_3gpp_lac, tvb, offset, 2, ENC_BIG_ENDIAN);
232
0
                proto_tree_add_item(cgi_tree, hf_exported_pdu_3gpp_ci, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
233
0
            }
234
0
            break;
235
0
        case EXP_PDU_3GPP_ID_ECGI:
236
0
            if (tag_len < 8) {
237
0
                proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, tag_len);
238
0
            } else {
239
0
                cgi_item = proto_tree_add_bits_item(tag_tree, hf_exported_pdu_3gpp_ecgi, tvb, bit_offset, 52, ENC_BIG_ENDIAN);
240
0
                cgi_tree = proto_item_add_subtree(cgi_item, ett_exported_pdu_3gpp_cgi);
241
0
                offset = dissect_e212_mcc_mnc(tvb, pinfo, cgi_tree, offset, E212_ECGI, false);
242
0
                bit_offset = offset * 8;
243
0
                proto_tree_add_bits_item(cgi_tree, hf_exported_pdu_3gpp_eci, tvb, bit_offset, 28, ENC_BIG_ENDIAN);
244
0
            }
245
0
            break;
246
0
        case EXP_PDU_3GPP_ID_NCGI:
247
0
            if (tag_len < 9) {
248
0
                proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, tag_len);
249
0
            } else {
250
0
                cgi_item = proto_tree_add_bits_item(tag_tree, hf_exported_pdu_3gpp_ncgi, tvb, bit_offset, 60, ENC_BIG_ENDIAN);
251
0
                cgi_tree = proto_item_add_subtree(cgi_item, ett_exported_pdu_3gpp_cgi);
252
0
                offset = dissect_e212_mcc_mnc(tvb, pinfo, cgi_tree, offset, E212_NRCGI, false);
253
0
                bit_offset = offset * 8;
254
0
                proto_tree_add_bits_item(cgi_tree, hf_exported_pdu_3gpp_nci, tvb, bit_offset, 36, ENC_BIG_ENDIAN);
255
0
            }
256
0
            break;
257
0
        default:
258
0
            proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unknown_tag, tvb, offset, tag_len);
259
0
            break;
260
0
    }
261
0
}
262
263
/* Code to actually dissect the packets */
264
static int
265
dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
266
0
{
267
0
    proto_item *exported_pdu_ti, *ti, *item;
268
0
    proto_tree *exported_pdu_tree, *tag_tree;
269
0
    tvbuff_t * payload_tvb = NULL;
270
0
    int offset = 0;
271
0
    uint32_t tag;
272
0
    int tag_len;
273
0
    int next_proto_type = -1;
274
0
    const uint8_t *proto_name = NULL;
275
0
    const uint8_t *dissector_table = NULL;
276
0
    const uint8_t *col_proto_str = NULL;
277
0
    const uint8_t* col_info_str = NULL;
278
0
    dissector_handle_t proto_handle;
279
0
    mtp3_addr_pc_t *mtp3_addr;
280
0
    uint32_t pdu_port_type;
281
0
    uint32_t dvb_ci_dir;
282
0
    uint32_t dissector_table_val=0;
283
0
    dissector_table_t dis_tbl;
284
0
    void* dissector_data = NULL;
285
286
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Exported PDU");
287
288
    /* create display subtree for the protocol */
289
0
    exported_pdu_ti = proto_tree_add_item(tree, proto_exported_pdu, tvb, offset, -1, ENC_NA);
290
0
    exported_pdu_tree = proto_item_add_subtree(exported_pdu_ti, ett_exported_pdu);
291
292
0
    do {
293
0
        ti = proto_tree_add_item_ret_uint(exported_pdu_tree, hf_exported_pdu_tag, tvb, offset, 2, ENC_BIG_ENDIAN, &tag);
294
0
        offset+=2;
295
0
        tag_tree = proto_item_add_subtree(ti, ett_exported_pdu_tag);
296
0
        proto_tree_add_item(tag_tree, hf_exported_pdu_tag_len, tvb, offset, 2, ENC_BIG_ENDIAN);
297
0
        tag_len = tvb_get_ntohs(tvb, offset);
298
0
        proto_item_set_len(ti, 4 + tag_len);
299
0
        offset+=2;
300
301
0
        switch(tag) {
302
0
            case EXP_PDU_TAG_DISSECTOR_NAME:
303
0
                next_proto_type = EXPORTED_PDU_NEXT_DISSECTOR_STR;
304
0
                proto_tree_add_item_ret_string(tag_tree, hf_exported_pdu_prot_name, tvb, offset, tag_len, ENC_UTF_8|ENC_NA, pinfo->pool, &proto_name);
305
0
                break;
306
0
            case EXP_PDU_TAG_HEUR_DISSECTOR_NAME:
307
0
                next_proto_type = EXPORTED_PDU_NEXT_HEUR_DISSECTOR_STR;
308
0
                proto_tree_add_item_ret_string(tag_tree, hf_exported_pdu_heur_prot_name, tvb, offset, tag_len, ENC_UTF_8|ENC_NA, pinfo->pool, &proto_name);
309
0
                break;
310
0
            case EXP_PDU_TAG_DISSECTOR_TABLE_NAME:
311
0
                next_proto_type = EXPORTED_PDU_NEXT_DIS_TABLE_STR;
312
0
                proto_tree_add_item_ret_string(tag_tree, hf_exported_pdu_dis_table_name, tvb, offset, tag_len, ENC_UTF_8 | ENC_NA, pinfo->pool, &dissector_table);
313
0
                break;
314
0
            case EXP_PDU_TAG_IPV4_SRC:
315
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_ipv4_src, tvb, offset, 4, ENC_BIG_ENDIAN);
316
                /* You can filter on IP by right clicking the Source/Destination columns make that work by filling the IP hf:s*/
317
0
                item = proto_tree_add_item(tag_tree, hf_ip_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
318
0
                proto_item_set_hidden(item);
319
0
                item = proto_tree_add_item(tag_tree, hf_ip_src, tvb, offset, 4, ENC_BIG_ENDIAN);
320
0
                proto_item_set_hidden(item);
321
322
0
                set_address_tvb(&pinfo->net_src, AT_IPv4, 4, tvb, offset);
323
0
                copy_address_shallow(&pinfo->src, &pinfo->net_src);
324
0
                break;
325
0
            case EXP_PDU_TAG_IPV4_DST:
326
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_ipv4_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
327
                /* You can filter on IP by right clicking the Source/Destination columns make that work by filling the IP hf:s*/
328
0
                item = proto_tree_add_item(tag_tree, hf_ip_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
329
0
                proto_item_set_hidden(item);
330
0
                item = proto_tree_add_item(tag_tree, hf_ip_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
331
0
                proto_item_set_hidden(item);
332
0
                set_address_tvb(&pinfo->net_dst, AT_IPv4, 4, tvb, offset);
333
0
                copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
334
0
                break;
335
0
            case EXP_PDU_TAG_IPV6_SRC:
336
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_ipv6_src, tvb, offset, 16, ENC_NA);
337
                /* You can filter on IP by right clicking the Source/Destination columns make that work by filling the IP hf:s*/
338
0
                item = proto_tree_add_item(tag_tree, hf_ipv6_addr, tvb, offset, 16, ENC_BIG_ENDIAN);
339
0
                proto_item_set_hidden(item);
340
0
                item = proto_tree_add_item(tag_tree, hf_ipv6_src, tvb, offset, 16, ENC_BIG_ENDIAN);
341
0
                proto_item_set_hidden(item);
342
0
                set_address_tvb(&pinfo->net_src, AT_IPv6, 16, tvb, offset);
343
0
                copy_address_shallow(&pinfo->src, &pinfo->net_src);
344
0
                break;
345
0
            case EXP_PDU_TAG_IPV6_DST:
346
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_ipv6_dst, tvb, offset, 16, ENC_NA);
347
                /* You can filter on IP by right clicking the Source/Destination columns make that work by filling the IP hf:s*/
348
0
                item = proto_tree_add_item(tag_tree, hf_ipv6_addr, tvb, offset, 16, ENC_BIG_ENDIAN);
349
0
                proto_item_set_hidden(item);
350
0
                item = proto_tree_add_item(tag_tree, hf_ipv6_dst, tvb, offset, 16, ENC_BIG_ENDIAN);
351
0
                proto_item_set_hidden(item);
352
0
                set_address_tvb(&pinfo->net_dst, AT_IPv6, 16, tvb, offset);
353
0
                copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
354
0
                break;
355
0
            case EXP_PDU_TAG_PORT_TYPE:
356
0
                proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_port_type, tvb, offset, 4, ENC_BIG_ENDIAN, &pdu_port_type);
357
0
                pinfo->ptype = exp_pdu_port_type_to_ws_port_type(pdu_port_type);
358
0
                break;
359
0
            case EXP_PDU_TAG_SRC_PORT:
360
0
                proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_src_port, tvb, offset, 4, ENC_BIG_ENDIAN, &pinfo->srcport);
361
0
                break;
362
0
            case EXP_PDU_TAG_DST_PORT:
363
0
                proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_dst_port, tvb, offset, 4, ENC_BIG_ENDIAN, &pinfo->destport);
364
0
                break;
365
0
            case EXP_PDU_TAG_SS7_OPC:
366
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_ss7_opc, tvb, offset, 4, ENC_BIG_ENDIAN);
367
0
                mtp3_addr = wmem_new0(pinfo->pool, mtp3_addr_pc_t);
368
0
                mtp3_addr->pc = tvb_get_ntohl(tvb, offset);
369
0
                mtp3_addr->type = (Standard_Type)tvb_get_ntohs(tvb, offset+4);
370
0
                mtp3_addr->ni = tvb_get_uint8(tvb, offset+6);
371
0
                set_address(&pinfo->src, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) mtp3_addr);
372
0
                break;
373
0
            case EXP_PDU_TAG_SS7_DPC:
374
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_ss7_dpc, tvb, offset, 4, ENC_BIG_ENDIAN);
375
0
                mtp3_addr = wmem_new0(pinfo->pool, mtp3_addr_pc_t);
376
0
                mtp3_addr->pc = tvb_get_ntohl(tvb, offset);
377
0
                mtp3_addr->type = (Standard_Type)tvb_get_ntohs(tvb, offset+4);
378
0
                mtp3_addr->ni = tvb_get_uint8(tvb, offset+6);
379
0
                set_address(&pinfo->dst, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) mtp3_addr);
380
0
                break;
381
0
            case EXP_PDU_TAG_ORIG_FNO:
382
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_orig_fno, tvb, offset, 4, ENC_BIG_ENDIAN);
383
0
                break;
384
0
            case EXP_PDU_TAG_DVBCI_EVT:
385
0
                proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_dvbci_evt,
386
0
                        tvb, offset, 1, ENC_BIG_ENDIAN, &dvb_ci_dir);
387
0
                dvbci_set_addrs((uint8_t)dvb_ci_dir, pinfo);
388
0
                break;
389
0
            case EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL:
390
0
                proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_dis_table_val, tvb, offset, 4, ENC_BIG_ENDIAN, &dissector_table_val);
391
0
                break;
392
0
            case EXP_PDU_TAG_COL_PROT_TEXT:
393
0
                proto_tree_add_item_ret_string(tag_tree, hf_exported_pdu_col_proto_str, tvb, offset, tag_len, ENC_UTF_8 | ENC_NA, pinfo->pool, &col_proto_str);
394
0
                break;
395
0
            case EXP_PDU_TAG_TCP_INFO_DATA:
396
0
                {
397
0
                struct tcpinfo* tcpdata = wmem_new0(pinfo->pool, struct tcpinfo);
398
0
                uint32_t u32;
399
400
0
                item = proto_tree_add_item(tag_tree, hf_exported_pdu_dissector_data, tvb, offset, tag_len, ENC_NA);
401
402
0
                proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_ddata_version, tvb, offset, 2, ENC_BIG_ENDIAN, &u32);
403
0
                if (u32 == 1) {
404
                    /* Keep old bytes-only field, but hide it */
405
0
                    proto_item_set_hidden(item);
406
407
0
                    proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_ddata_seq, tvb, offset+2, 4, ENC_BIG_ENDIAN, &tcpdata->seq);
408
0
                    proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_ddata_nxtseq, tvb, offset+6, 4, ENC_BIG_ENDIAN, &tcpdata->nxtseq);
409
0
                    proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_ddata_lastackseq, tvb, offset+10, 4, ENC_BIG_ENDIAN, &tcpdata->lastackseq);
410
0
                    proto_tree_add_item_ret_boolean(tag_tree, hf_exported_pdu_ddata_is_reassembled, tvb, offset+14, 1, ENC_BIG_ENDIAN, &tcpdata->is_reassembled);
411
0
                    proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_ddata_flags, tvb, offset+15, 2, ENC_BIG_ENDIAN, &u32);
412
0
                    tcpdata->flags = u32;
413
0
                    proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_ddata_urgent_pointer, tvb, offset+17, 2, ENC_BIG_ENDIAN, &u32);
414
0
                    tcpdata->urgent_pointer = u32;
415
416
0
                    dissector_data = tcpdata;
417
0
                }
418
0
                else { /* Only version 1 is currently supported */
419
0
                    proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unsupported_version, tvb, offset, tag_len);
420
0
                }
421
422
0
                }
423
0
                break;
424
0
            case EXP_PDU_TAG_P2P_DIRECTION:
425
0
                pinfo->p2p_dir = tvb_get_ntohl(tvb, offset);
426
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_p2p_dir, tvb, offset, 4, ENC_NA);
427
0
                break;
428
0
            case EXP_PDU_TAG_COL_INFO_TEXT:
429
0
                proto_tree_add_item_ret_string(tag_tree, hf_exported_pdu_col_info_str, tvb, offset, tag_len, ENC_UTF_8 | ENC_NA, pinfo->pool, &col_info_str);
430
0
                break;
431
0
            case EXP_PDU_TAG_USER_DATA_PDU:
432
0
                next_proto_type = EXPORTED_PDU_NEXT_DISSECTOR_STR;
433
0
                proto_name = user_data_pdu;
434
0
                break;
435
0
            case EXP_PDU_TAG_3GPP_ID:
436
0
                dissect_3gpp_id(tvb, pinfo, tag_tree, offset, tag_len);
437
0
                break;
438
0
            case EXP_PDU_TAG_END_OF_OPT:
439
0
                break;
440
0
            default:
441
0
                proto_tree_add_item(tag_tree, hf_exported_pdu_unknown_tag_val, tvb, offset, tag_len, ENC_NA);
442
0
                proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unknown_tag, tvb, offset, tag_len);
443
0
                break;
444
0
        }
445
446
0
        offset = offset + tag_len;
447
448
0
    } while(tag != 0);
449
450
    /* Limit the Exported PDU tree to the tags without payload. */
451
0
    proto_item_set_len(exported_pdu_ti, offset);
452
453
0
    payload_tvb = tvb_new_subset_remaining(tvb, offset);
454
0
    proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_exported_pdu, payload_tvb, 0, -1, ENC_NA);
455
456
0
    switch(next_proto_type) {
457
0
        case EXPORTED_PDU_NEXT_DISSECTOR_STR:
458
0
            proto_handle = find_dissector(proto_name);
459
0
            if (proto_handle) {
460
0
                if (col_proto_str) {
461
0
                    col_add_str(pinfo->cinfo, COL_PROTOCOL, col_proto_str);
462
0
                } else {
463
0
                    col_clear(pinfo->cinfo, COL_PROTOCOL);
464
0
                }
465
0
                if (col_info_str) {
466
0
                    col_add_str(pinfo->cinfo, COL_INFO, col_info_str);
467
0
                }
468
0
                else {
469
0
                    col_clear(pinfo->cinfo, COL_INFO);
470
0
                }
471
0
                call_dissector_with_data(proto_handle, payload_tvb, pinfo, tree, dissector_data);
472
0
            }
473
0
            break;
474
0
        case EXPORTED_PDU_NEXT_HEUR_DISSECTOR_STR:
475
0
        {
476
0
            heur_dtbl_entry_t *heur_diss = find_heur_dissector_by_unique_short_name(proto_name);
477
0
            if (heur_diss) {
478
0
                if (col_proto_str) {
479
0
                    col_add_str(pinfo->cinfo, COL_PROTOCOL, col_proto_str);
480
0
                } else {
481
0
                    col_clear(pinfo->cinfo, COL_PROTOCOL);
482
0
                }
483
0
                if (col_info_str) {
484
0
                    col_add_str(pinfo->cinfo, COL_INFO, col_info_str);
485
0
                }
486
0
                else {
487
0
                    col_clear(pinfo->cinfo, COL_INFO);
488
0
                }
489
0
                call_heur_dissector_direct(heur_diss, payload_tvb, pinfo, tree, dissector_data);
490
0
            }
491
0
            break;
492
0
        }
493
0
        case EXPORTED_PDU_NEXT_DIS_TABLE_STR:
494
0
        {
495
0
            dis_tbl = find_dissector_table(dissector_table);
496
0
            if (dis_tbl) {
497
0
                if (col_proto_str) {
498
0
                    col_add_str(pinfo->cinfo, COL_PROTOCOL, col_proto_str);
499
0
                } else {
500
0
                    col_clear(pinfo->cinfo, COL_PROTOCOL);
501
0
                }
502
0
                if (col_info_str) {
503
0
                    col_add_str(pinfo->cinfo, COL_INFO, col_info_str);
504
0
                }
505
0
                else {
506
0
                    col_clear(pinfo->cinfo, COL_INFO);
507
0
                }
508
0
                dissector_try_uint_with_data(dis_tbl, dissector_table_val, payload_tvb, pinfo, tree, true, dissector_data);
509
0
            }
510
0
        }
511
0
        default:
512
0
            break;
513
0
    }
514
515
0
    return tvb_captured_length(tvb);
516
0
}
517
518
/* Register the protocol with Wireshark.
519
 *
520
 */
521
void
522
proto_register_exported_pdu(void)
523
14
{
524
    /*module_t *exported_pdu_module;*/
525
526
14
    static hf_register_info hf[] = {
527
14
        { &hf_exported_pdu_tag,
528
14
            { "Tag", "exported_pdu.tag",
529
14
               FT_UINT16, BASE_DEC, VALS(exported_pdu_tag_vals), 0,
530
14
              NULL, HFILL }
531
14
        },
532
14
        { &hf_exported_pdu_tag_len,
533
14
            { "Length", "exported_pdu.tag_len",
534
14
               FT_UINT16, BASE_DEC, NULL, 0,
535
14
              NULL, HFILL }
536
14
        },
537
14
        { &hf_exported_pdu_unknown_tag_val,
538
14
            { "Unknown tags value", "exported_pdu.unknown_tag.val",
539
14
               FT_BYTES, BASE_NONE, NULL, 0,
540
14
              NULL, HFILL }
541
14
        },
542
14
        { &hf_exported_pdu_prot_name,
543
14
            { "Protocol Name", "exported_pdu.prot_name",
544
14
               FT_STRINGZPAD, BASE_NONE, NULL, 0,
545
14
              NULL, HFILL }
546
14
        },
547
14
        { &hf_exported_pdu_heur_prot_name,
548
14
            { "Heuristic Protocol Name", "exported_pdu.heur_prot_name",
549
14
               FT_STRINGZPAD, BASE_NONE, NULL, 0,
550
14
              NULL, HFILL }
551
14
        },
552
14
        { &hf_exported_pdu_dis_table_name,
553
14
            { "Dissector Table Name", "exported_pdu.dis_table_name",
554
14
               FT_STRINGZPAD, BASE_NONE, NULL, 0,
555
14
              NULL, HFILL }
556
14
        },
557
14
        { &hf_exported_pdu_p2p_dir,
558
14
            { "P2P direction", "exported_pdu.p2p_dir",
559
14
               FT_INT32, BASE_DEC, VALS(exported_pdu_p2p_dir_vals), 0,
560
14
              NULL, HFILL }
561
14
        },
562
14
        { &hf_exported_pdu_dissector_data,
563
14
            { "TCP Dissector Data", "exported_pdu.tcp_dissector_data",
564
14
               FT_BYTES, BASE_NONE, NULL, 0,
565
14
              NULL, HFILL }
566
14
        },
567
14
        { &hf_exported_pdu_ddata_version,
568
14
            { "TCP Dissector Data version", "exported_pdu.tcp_dissector_data.version",
569
14
               FT_UINT16, BASE_DEC, NULL, 0,
570
14
              NULL, HFILL }
571
14
        },
572
14
        { &hf_exported_pdu_ddata_seq,
573
14
            { "Sequence number", "exported_pdu.tcp_dissector_data.seq",
574
14
               FT_UINT32, BASE_DEC, NULL, 0,
575
14
              NULL, HFILL }
576
14
        },
577
14
        { &hf_exported_pdu_ddata_nxtseq,
578
14
            { "Next sequence number", "exported_pdu.tcp_dissector_data.nxtseq",
579
14
               FT_UINT32, BASE_DEC, NULL, 0,
580
14
              NULL, HFILL }
581
14
        },
582
14
        { &hf_exported_pdu_ddata_lastackseq,
583
14
            { "Last acked sequence number", "exported_pdu.tcp_dissector_data.lastackseq",
584
14
               FT_UINT32, BASE_DEC, NULL, 0,
585
14
              NULL, HFILL }
586
14
        },
587
14
        { &hf_exported_pdu_ddata_is_reassembled,
588
14
            { "Is reassembled", "exported_pdu.tcp_dissector_data.is_reassembled",
589
14
               FT_BOOLEAN, BASE_NONE, NULL, 0,
590
14
              NULL, HFILL }
591
14
        },
592
14
        { &hf_exported_pdu_ddata_flags,
593
14
            { "Flags", "exported_pdu.tcp_dissector_data.flags",
594
14
               FT_UINT16, BASE_HEX, NULL, 0,
595
14
              NULL, HFILL }
596
14
        },
597
14
        { &hf_exported_pdu_ddata_urgent_pointer,
598
14
            { "Urgent pointer", "exported_pdu.tcp_dissector_data.urgent_pointer",
599
14
               FT_UINT16, BASE_DEC, NULL, 0,
600
14
              NULL, HFILL }
601
14
        },
602
14
        { &hf_exported_pdu_ipv4_src,
603
14
            { "IPv4 Src", "exported_pdu.ipv4_src",
604
14
               FT_IPv4, BASE_NONE, NULL, 0,
605
14
              NULL, HFILL }
606
14
        },
607
14
        { &hf_exported_pdu_ipv4_dst,
608
14
            { "IPv4 Dst", "exported_pdu.ipv4_dst",
609
14
               FT_IPv4, BASE_NONE, NULL, 0,
610
14
              NULL, HFILL }
611
14
        },
612
14
        { &hf_exported_pdu_ipv6_src,
613
14
            { "IPv6 Src", "exported_pdu.ipv6_src",
614
14
               FT_IPv6, BASE_NONE, NULL, 0,
615
14
              NULL, HFILL }
616
14
        },
617
14
        { &hf_exported_pdu_ipv6_dst,
618
14
            { "IPv6 Dst", "exported_pdu.ipv6_dst",
619
14
               FT_IPv6, BASE_NONE, NULL, 0,
620
14
              NULL, HFILL }
621
14
        },
622
14
        { &hf_exported_pdu_port_type,
623
14
            { "Port Type", "exported_pdu.port_type",
624
14
               FT_UINT32, BASE_DEC, VALS(exported_pdu_port_type_vals), 0,
625
14
              NULL, HFILL }
626
14
        },
627
14
        { &hf_exported_pdu_src_port,
628
14
            { "Src Port", "exported_pdu.src_port",
629
14
               FT_UINT32, BASE_DEC, NULL, 0,
630
14
              NULL, HFILL }
631
14
        },
632
14
        { &hf_exported_pdu_dst_port,
633
14
            { "Dst Port", "exported_pdu.dst_port",
634
14
               FT_UINT32, BASE_DEC, NULL, 0,
635
14
              NULL, HFILL }
636
14
        },
637
14
        { &hf_exported_pdu_ss7_opc,
638
14
            { "SS7 OPC", "exported_pdu.ss7_opc",
639
14
               FT_UINT32, BASE_DEC, NULL, 0,
640
14
              NULL, HFILL }
641
14
        },
642
14
        { &hf_exported_pdu_ss7_dpc,
643
14
            { "SS7 DPC", "exported_pdu.ss7_dpc",
644
14
               FT_UINT32, BASE_DEC, NULL, 0,
645
14
              NULL, HFILL }
646
14
        },
647
14
        { &hf_exported_pdu_orig_fno,
648
14
            { "Original Frame Number", "exported_pdu.orig_fno",
649
14
               FT_UINT32, BASE_DEC, NULL, 0,
650
14
              NULL, HFILL }
651
14
        },
652
14
        { &hf_exported_pdu_dvbci_evt,
653
14
            { "DVB-CI event", "exported_pdu.dvb-ci.event",
654
14
               FT_UINT8, BASE_HEX, VALS(dvbci_event), 0,
655
14
              NULL, HFILL }
656
14
        },
657
14
        { &hf_exported_pdu_exported_pdu,
658
14
            { "Exported PDU data", "exported_pdu.exported_pdu",
659
14
               FT_BYTES, BASE_NONE|BASE_NO_DISPLAY_VALUE, NULL, 0,
660
14
              NULL, HFILL }
661
14
        },
662
14
        { &hf_exported_pdu_dis_table_val,
663
14
            { "Value to use when calling dissector table", "exported_pdu.dis_table_val",
664
14
               FT_UINT32, BASE_DEC, NULL, 0,
665
14
              NULL, HFILL }
666
14
        },
667
14
        { &hf_exported_pdu_col_proto_str,
668
14
            { "Column protocol string", "exported_pdu.col_proto_str",
669
14
               FT_STRINGZPAD, BASE_NONE, NULL, 0,
670
14
              NULL, HFILL }
671
14
        },
672
14
        { &hf_exported_pdu_col_info_str,
673
14
            { "Column information string", "exported_pdu.col_info_str",
674
14
               FT_STRINGZPAD, BASE_NONE, NULL, 0,
675
14
              NULL, HFILL }
676
14
        },
677
14
        { &hf_exported_pdu_3gpp_id_type,
678
14
            { "3GPP Identity Type", "exported_pdu.3gpp.id_type",
679
14
               FT_UINT8, BASE_DEC, VALS(exported_pdu_3gpp_id_type_vals), 0,
680
14
              NULL, HFILL }
681
14
        },
682
14
        { &hf_exported_pdu_3gpp_lac,
683
14
            { "LAC", "exported_pdu.3gpp.lac",
684
14
               FT_UINT16, BASE_HEX_DEC, NULL, 0,
685
14
              NULL, HFILL }
686
14
        },
687
14
        { &hf_exported_pdu_3gpp_ci,
688
14
            { "CI", "exported_pdu.3gpp.ci",
689
14
               FT_UINT16, BASE_HEX_DEC, NULL, 0,
690
14
              NULL, HFILL }
691
14
        },
692
14
        { &hf_exported_pdu_3gpp_eci,
693
14
            { "E-UTRAN CI", "exported_pdu.3gpp.eci",
694
14
               FT_UINT32, BASE_HEX_DEC, NULL, 0,
695
14
              NULL, HFILL }
696
14
        },
697
14
        { &hf_exported_pdu_3gpp_nci,
698
14
            { "NR CI", "exported_pdu.3gpp.nci",
699
14
               FT_UINT64, BASE_HEX_DEC, NULL, 0,
700
14
              NULL, HFILL }
701
14
        },
702
14
        { &hf_exported_pdu_3gpp_cgi,
703
14
            { "Cell Global Identifier", "exported_pdu.3gpp.cgi",
704
14
               FT_UINT64, BASE_HEX, NULL, 0,
705
14
              NULL, HFILL }
706
14
        },
707
14
        { &hf_exported_pdu_3gpp_ecgi,
708
14
            { "E-UTRAN Cell Global Identifier", "exported_pdu.3gpp.ecgi",
709
14
               FT_UINT64, BASE_HEX, NULL, 0,
710
14
              NULL, HFILL }
711
14
        },
712
14
        { &hf_exported_pdu_3gpp_ncgi,
713
14
            { "NR Cell Global Identifier", "exported_pdu.3gpp.ncgi",
714
14
               FT_UINT64, BASE_HEX, NULL, 0,
715
14
              NULL, HFILL }
716
14
        },
717
14
    };
718
719
    /* Setup protocol subtree array */
720
14
    static int *ett[] = {
721
14
        &ett_exported_pdu,
722
14
        &ett_exported_pdu_tag,
723
14
        &ett_exported_pdu_3gpp_cgi,
724
14
    };
725
726
    /* Setup expert information */
727
14
    static ei_register_info ei[] = {
728
14
        { &ei_exported_pdu_unsupported_version,
729
14
            { "exported_pdu.tcp_dissector_data.version.invalid",
730
14
                PI_PROTOCOL, PI_WARN, "Unsupported TCP Dissector Data version", EXPFILL }
731
14
        },
732
14
        { &ei_exported_pdu_unknown_tag,
733
14
            { "exported_pdu.tag.unknown",
734
14
                PI_PROTOCOL, PI_WARN, "Unrecognized tag", EXPFILL }
735
14
        },
736
14
        { &ei_exported_pdu_unexpected_tag_length,
737
14
            { "exported_pdu.tag_len.unexpected",
738
14
                PI_PROTOCOL, PI_WARN, "Unexpected tag length", EXPFILL }
739
14
        },
740
14
    };
741
14
    expert_module_t *expert_exported_pdu;
742
14
    module_t *exported_pdu_module;
743
744
    /* Register the protocol name and description */
745
14
    proto_exported_pdu = proto_register_protocol("EXPORTED_PDU", "Exported PDU", "exported_pdu");
746
747
14
    expert_exported_pdu = expert_register_protocol(proto_exported_pdu);
748
14
    expert_register_field_array(expert_exported_pdu, ei, array_length(ei));
749
750
14
    exported_pdu_handle = register_dissector("exported_pdu", dissect_exported_pdu, proto_exported_pdu);
751
752
    /* Required function calls to register the header fields and subtrees */
753
14
    proto_register_field_array(proto_exported_pdu, hf, array_length(hf));
754
14
    proto_register_subtree_array(ett, array_length(ett));
755
756
    /* Register configuration preferences */
757
14
    exported_pdu_module = prefs_register_protocol(proto_exported_pdu, NULL);
758
14
    prefs_register_dissector_preference(exported_pdu_module, "user_data_pdu",
759
14
        "User Data PDU dissector", "The dissector to use for User Data PDU", &user_data_pdu);
760
761
    /* Register for tapping
762
     * The tap is registered here but it is to be used by dissectors that
763
     * want to export their PDUs, see packet-sip.c
764
     */
765
14
    register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_3);
766
14
    register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_4);
767
14
    register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_7);
768
14
}
769
770
void
771
proto_reg_handoff_exported_pdu(void)
772
14
{
773
14
    static bool initialized = false;
774
775
14
    if (!initialized) {
776
14
        dissector_add_uint("wtap_encap", WTAP_ENCAP_WIRESHARK_UPPER_PDU, exported_pdu_handle);
777
14
        initialized = true;
778
14
    }
779
780
14
    ss7pc_address_type = address_type_get_by_name("AT_SS7PC");
781
782
    /* Get the hf id of some fields from the IP dissectors to be able to use them here*/
783
14
    hf_ip_addr    = proto_registrar_get_id_byname("ip.addr");
784
14
    hf_ip_dst     = proto_registrar_get_id_byname("ip.dst");
785
14
    hf_ip_src     = proto_registrar_get_id_byname("ip.src");
786
14
    hf_ipv6_addr  = proto_registrar_get_id_byname("ipv6.addr");
787
14
    hf_ipv6_dst   = proto_registrar_get_id_byname("ipv6.dst");
788
14
    hf_ipv6_src   = proto_registrar_get_id_byname("ipv6.src");
789
14
}
790
791
792
/*
793
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
794
 *
795
 * Local variables:
796
 * c-basic-offset: 4
797
 * tab-width: 8
798
 * indent-tabs-mode: nil
799
 * End:
800
 *
801
 * vi: set shiftwidth=4 tabstop=8 expandtab:
802
 * :indentSize=4:tabSize=8:noTabs=true:
803
 */