1 /* packet-exported_pdu.c
2 * Routines for exported_pdu dissection
3 * Copyright 2013, Anders Broman <anders-broman@ericsson.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
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"
25 void proto_register_exported_pdu(void);
26 void proto_reg_handoff_exported_pdu(void);
28 static int hf_ip_addr
;
31 static int hf_ipv6_addr
;
32 static int hf_ipv6_dst
;
33 static int hf_ipv6_src
;
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
;
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
;
81 static int ss7pc_address_type
= -1;
83 static dissector_handle_t exported_pdu_handle
;
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
;
89 static const char *user_data_pdu
= "data";
91 #define EXPORTED_PDU_NEXT_DISSECTOR_STR 0
92 #define EXPORTED_PDU_NEXT_HEUR_DISSECTOR_STR 1
93 #define EXPORTED_PDU_NEXT_DIS_TABLE_STR 2
95 static const value_string exported_pdu_tag_vals
[] = {
96 { EXP_PDU_TAG_END_OF_OPT
, "End-of-options" },
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" },
110 { EXP_PDU_TAG_PORT_TYPE
, "Port Type" },
111 { EXP_PDU_TAG_SRC_PORT
, "Source Port" },
112 { EXP_PDU_TAG_DST_PORT
, "Destination Port" },
114 { EXP_PDU_TAG_SS7_OPC
, "SS7 OPC" },
115 { EXP_PDU_TAG_SS7_DPC
, "SS7 DPC" },
117 { EXP_PDU_TAG_ORIG_FNO
, "Original Frame number" },
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" },
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" },
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" },
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" },
168 static port_type
exp_pdu_port_type_to_ws_port_type(uint32_t type
)
172 case EXP_PDU_PT_NONE
:
174 case EXP_PDU_PT_SCTP
:
180 case EXP_PDU_PT_DCCP
:
192 case EXP_PDU_PT_IBQP
:
194 case EXP_PDU_PT_BLUETOOTH
:
196 case EXP_PDU_PT_EXCHG
:
197 case EXP_PDU_PT_TIPC
:
198 case EXP_PDU_PT_TDMOP
:
200 case EXP_PDU_PT_SBCCS
:
201 //no longer supported
205 DISSECTOR_ASSERT(false);
210 dissect_3gpp_id(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tag_tree
, int offset
, int tag_len
)
212 proto_item
*cgi_item
;
213 proto_tree
*cgi_tree
;
215 int bit_offset
= offset
* 8;
217 proto_tree_add_expert(tag_tree
, pinfo
, &ei_exported_pdu_unexpected_tag_length
, tvb
, offset
, 0);
220 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_3gpp_id_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &ci_type
);
224 case EXP_PDU_3GPP_ID_CGI
:
226 proto_tree_add_expert(tag_tree
, pinfo
, &ei_exported_pdu_unexpected_tag_length
, tvb
, offset
, tag_len
);
228 cgi_item
= proto_tree_add_bits_item(tag_tree
, hf_exported_pdu_3gpp_cgi
, tvb
, bit_offset
, 56, ENC_BIG_ENDIAN
);
229 cgi_tree
= proto_item_add_subtree(cgi_item
, ett_exported_pdu_3gpp_cgi
);
230 offset
= dissect_e212_mcc_mnc(tvb
, pinfo
, cgi_tree
, offset
, E212_CGI
, false);
231 proto_tree_add_item(cgi_tree
, hf_exported_pdu_3gpp_lac
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
232 proto_tree_add_item(cgi_tree
, hf_exported_pdu_3gpp_ci
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
235 case EXP_PDU_3GPP_ID_ECGI
:
237 proto_tree_add_expert(tag_tree
, pinfo
, &ei_exported_pdu_unexpected_tag_length
, tvb
, offset
, tag_len
);
239 cgi_item
= proto_tree_add_bits_item(tag_tree
, hf_exported_pdu_3gpp_ecgi
, tvb
, bit_offset
, 52, ENC_BIG_ENDIAN
);
240 cgi_tree
= proto_item_add_subtree(cgi_item
, ett_exported_pdu_3gpp_cgi
);
241 offset
= dissect_e212_mcc_mnc(tvb
, pinfo
, cgi_tree
, offset
, E212_ECGI
, false);
242 bit_offset
= offset
* 8;
243 proto_tree_add_bits_item(cgi_tree
, hf_exported_pdu_3gpp_eci
, tvb
, bit_offset
, 28, ENC_BIG_ENDIAN
);
246 case EXP_PDU_3GPP_ID_NCGI
:
248 proto_tree_add_expert(tag_tree
, pinfo
, &ei_exported_pdu_unexpected_tag_length
, tvb
, offset
, tag_len
);
250 cgi_item
= proto_tree_add_bits_item(tag_tree
, hf_exported_pdu_3gpp_ncgi
, tvb
, bit_offset
, 60, ENC_BIG_ENDIAN
);
251 cgi_tree
= proto_item_add_subtree(cgi_item
, ett_exported_pdu_3gpp_cgi
);
252 offset
= dissect_e212_mcc_mnc(tvb
, pinfo
, cgi_tree
, offset
, E212_NRCGI
, false);
253 bit_offset
= offset
* 8;
254 proto_tree_add_bits_item(cgi_tree
, hf_exported_pdu_3gpp_nci
, tvb
, bit_offset
, 36, ENC_BIG_ENDIAN
);
258 proto_tree_add_expert(tag_tree
, pinfo
, &ei_exported_pdu_unknown_tag
, tvb
, offset
, tag_len
);
263 /* Code to actually dissect the packets */
265 dissect_exported_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
267 proto_item
*exported_pdu_ti
, *ti
, *item
;
268 proto_tree
*exported_pdu_tree
, *tag_tree
;
269 tvbuff_t
* payload_tvb
= NULL
;
273 int next_proto_type
= -1;
274 const uint8_t *proto_name
= NULL
;
275 const uint8_t *dissector_table
= NULL
;
276 const uint8_t *col_proto_str
= NULL
;
277 const uint8_t* col_info_str
= NULL
;
278 dissector_handle_t proto_handle
;
279 mtp3_addr_pc_t
*mtp3_addr
;
280 uint32_t pdu_port_type
;
282 uint32_t dissector_table_val
=0;
283 dissector_table_t dis_tbl
;
284 void* dissector_data
= NULL
;
286 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Exported PDU");
288 /* create display subtree for the protocol */
289 exported_pdu_ti
= proto_tree_add_item(tree
, proto_exported_pdu
, tvb
, offset
, -1, ENC_NA
);
290 exported_pdu_tree
= proto_item_add_subtree(exported_pdu_ti
, ett_exported_pdu
);
293 ti
= proto_tree_add_item_ret_uint(exported_pdu_tree
, hf_exported_pdu_tag
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &tag
);
295 tag_tree
= proto_item_add_subtree(ti
, ett_exported_pdu_tag
);
296 proto_tree_add_item(tag_tree
, hf_exported_pdu_tag_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
297 tag_len
= tvb_get_ntohs(tvb
, offset
);
298 proto_item_set_len(ti
, 4 + tag_len
);
302 case EXP_PDU_TAG_DISSECTOR_NAME
:
303 next_proto_type
= EXPORTED_PDU_NEXT_DISSECTOR_STR
;
304 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
);
306 case EXP_PDU_TAG_HEUR_DISSECTOR_NAME
:
307 next_proto_type
= EXPORTED_PDU_NEXT_HEUR_DISSECTOR_STR
;
308 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
);
310 case EXP_PDU_TAG_DISSECTOR_TABLE_NAME
:
311 next_proto_type
= EXPORTED_PDU_NEXT_DIS_TABLE_STR
;
312 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
);
314 case EXP_PDU_TAG_IPV4_SRC
:
315 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 item
= proto_tree_add_item(tag_tree
, hf_ip_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
318 proto_item_set_hidden(item
);
319 item
= proto_tree_add_item(tag_tree
, hf_ip_src
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
320 proto_item_set_hidden(item
);
322 set_address_tvb(&pinfo
->net_src
, AT_IPv4
, 4, tvb
, offset
);
323 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
325 case EXP_PDU_TAG_IPV4_DST
:
326 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 item
= proto_tree_add_item(tag_tree
, hf_ip_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
329 proto_item_set_hidden(item
);
330 item
= proto_tree_add_item(tag_tree
, hf_ip_dst
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
331 proto_item_set_hidden(item
);
332 set_address_tvb(&pinfo
->net_dst
, AT_IPv4
, 4, tvb
, offset
);
333 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
335 case EXP_PDU_TAG_IPV6_SRC
:
336 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 item
= proto_tree_add_item(tag_tree
, hf_ipv6_addr
, tvb
, offset
, 16, ENC_BIG_ENDIAN
);
339 proto_item_set_hidden(item
);
340 item
= proto_tree_add_item(tag_tree
, hf_ipv6_src
, tvb
, offset
, 16, ENC_BIG_ENDIAN
);
341 proto_item_set_hidden(item
);
342 set_address_tvb(&pinfo
->net_src
, AT_IPv6
, 16, tvb
, offset
);
343 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
345 case EXP_PDU_TAG_IPV6_DST
:
346 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 item
= proto_tree_add_item(tag_tree
, hf_ipv6_addr
, tvb
, offset
, 16, ENC_BIG_ENDIAN
);
349 proto_item_set_hidden(item
);
350 item
= proto_tree_add_item(tag_tree
, hf_ipv6_dst
, tvb
, offset
, 16, ENC_BIG_ENDIAN
);
351 proto_item_set_hidden(item
);
352 set_address_tvb(&pinfo
->net_dst
, AT_IPv6
, 16, tvb
, offset
);
353 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
355 case EXP_PDU_TAG_PORT_TYPE
:
356 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_port_type
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &pdu_port_type
);
357 pinfo
->ptype
= exp_pdu_port_type_to_ws_port_type(pdu_port_type
);
359 case EXP_PDU_TAG_SRC_PORT
:
360 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_src_port
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &pinfo
->srcport
);
362 case EXP_PDU_TAG_DST_PORT
:
363 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_dst_port
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &pinfo
->destport
);
365 case EXP_PDU_TAG_SS7_OPC
:
366 proto_tree_add_item(tag_tree
, hf_exported_pdu_ss7_opc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
367 mtp3_addr
= wmem_new0(pinfo
->pool
, mtp3_addr_pc_t
);
368 mtp3_addr
->pc
= tvb_get_ntohl(tvb
, offset
);
369 mtp3_addr
->type
= (Standard_Type
)tvb_get_ntohs(tvb
, offset
+4);
370 mtp3_addr
->ni
= tvb_get_uint8(tvb
, offset
+6);
371 set_address(&pinfo
->src
, ss7pc_address_type
, sizeof(mtp3_addr_pc_t
), (uint8_t *) mtp3_addr
);
373 case EXP_PDU_TAG_SS7_DPC
:
374 proto_tree_add_item(tag_tree
, hf_exported_pdu_ss7_dpc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
375 mtp3_addr
= wmem_new0(pinfo
->pool
, mtp3_addr_pc_t
);
376 mtp3_addr
->pc
= tvb_get_ntohl(tvb
, offset
);
377 mtp3_addr
->type
= (Standard_Type
)tvb_get_ntohs(tvb
, offset
+4);
378 mtp3_addr
->ni
= tvb_get_uint8(tvb
, offset
+6);
379 set_address(&pinfo
->dst
, ss7pc_address_type
, sizeof(mtp3_addr_pc_t
), (uint8_t *) mtp3_addr
);
381 case EXP_PDU_TAG_ORIG_FNO
:
382 proto_tree_add_item(tag_tree
, hf_exported_pdu_orig_fno
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
384 case EXP_PDU_TAG_DVBCI_EVT
:
385 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_dvbci_evt
,
386 tvb
, offset
, 1, ENC_BIG_ENDIAN
, &dvb_ci_dir
);
387 dvbci_set_addrs((uint8_t)dvb_ci_dir
, pinfo
);
389 case EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL
:
390 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_dis_table_val
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &dissector_table_val
);
392 case EXP_PDU_TAG_COL_PROT_TEXT
:
393 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
);
395 case EXP_PDU_TAG_TCP_INFO_DATA
:
397 struct tcpinfo
* tcpdata
= wmem_new0(pinfo
->pool
, struct tcpinfo
);
400 item
= proto_tree_add_item(tag_tree
, hf_exported_pdu_dissector_data
, tvb
, offset
, tag_len
, ENC_NA
);
402 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_ddata_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &u32
);
404 /* Keep old bytes-only field, but hide it */
405 proto_item_set_hidden(item
);
407 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_ddata_seq
, tvb
, offset
+2, 4, ENC_BIG_ENDIAN
, &tcpdata
->seq
);
408 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_ddata_nxtseq
, tvb
, offset
+6, 4, ENC_BIG_ENDIAN
, &tcpdata
->nxtseq
);
409 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_ddata_lastackseq
, tvb
, offset
+10, 4, ENC_BIG_ENDIAN
, &tcpdata
->lastackseq
);
410 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 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_ddata_flags
, tvb
, offset
+15, 2, ENC_BIG_ENDIAN
, &u32
);
412 tcpdata
->flags
= u32
;
413 proto_tree_add_item_ret_uint(tag_tree
, hf_exported_pdu_ddata_urgent_pointer
, tvb
, offset
+17, 2, ENC_BIG_ENDIAN
, &u32
);
414 tcpdata
->urgent_pointer
= u32
;
416 dissector_data
= tcpdata
;
418 else { /* Only version 1 is currently supported */
419 proto_tree_add_expert(tag_tree
, pinfo
, &ei_exported_pdu_unsupported_version
, tvb
, offset
, tag_len
);
424 case EXP_PDU_TAG_P2P_DIRECTION
:
425 pinfo
->p2p_dir
= tvb_get_ntohl(tvb
, offset
);
426 proto_tree_add_item(tag_tree
, hf_exported_pdu_p2p_dir
, tvb
, offset
, 4, ENC_NA
);
428 case EXP_PDU_TAG_COL_INFO_TEXT
:
429 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
);
431 case EXP_PDU_TAG_USER_DATA_PDU
:
432 next_proto_type
= EXPORTED_PDU_NEXT_DISSECTOR_STR
;
433 proto_name
= user_data_pdu
;
435 case EXP_PDU_TAG_3GPP_ID
:
436 dissect_3gpp_id(tvb
, pinfo
, tag_tree
, offset
, tag_len
);
438 case EXP_PDU_TAG_END_OF_OPT
:
441 proto_tree_add_item(tag_tree
, hf_exported_pdu_unknown_tag_val
, tvb
, offset
, tag_len
, ENC_NA
);
442 proto_tree_add_expert(tag_tree
, pinfo
, &ei_exported_pdu_unknown_tag
, tvb
, offset
, tag_len
);
446 offset
= offset
+ tag_len
;
450 /* Limit the Exported PDU tree to the tags without payload. */
451 proto_item_set_len(exported_pdu_ti
, offset
);
453 payload_tvb
= tvb_new_subset_remaining(tvb
, offset
);
454 proto_tree_add_item(exported_pdu_tree
, hf_exported_pdu_exported_pdu
, payload_tvb
, 0, -1, ENC_NA
);
456 switch(next_proto_type
) {
457 case EXPORTED_PDU_NEXT_DISSECTOR_STR
:
458 proto_handle
= find_dissector(proto_name
);
461 col_add_str(pinfo
->cinfo
, COL_PROTOCOL
, col_proto_str
);
463 col_clear(pinfo
->cinfo
, COL_PROTOCOL
);
466 col_add_str(pinfo
->cinfo
, COL_INFO
, col_info_str
);
469 col_clear(pinfo
->cinfo
, COL_INFO
);
471 call_dissector_with_data(proto_handle
, payload_tvb
, pinfo
, tree
, dissector_data
);
474 case EXPORTED_PDU_NEXT_HEUR_DISSECTOR_STR
:
476 heur_dtbl_entry_t
*heur_diss
= find_heur_dissector_by_unique_short_name(proto_name
);
479 col_add_str(pinfo
->cinfo
, COL_PROTOCOL
, col_proto_str
);
481 col_clear(pinfo
->cinfo
, COL_PROTOCOL
);
484 col_add_str(pinfo
->cinfo
, COL_INFO
, col_info_str
);
487 col_clear(pinfo
->cinfo
, COL_INFO
);
489 call_heur_dissector_direct(heur_diss
, payload_tvb
, pinfo
, tree
, dissector_data
);
493 case EXPORTED_PDU_NEXT_DIS_TABLE_STR
:
495 dis_tbl
= find_dissector_table(dissector_table
);
498 col_add_str(pinfo
->cinfo
, COL_PROTOCOL
, col_proto_str
);
500 col_clear(pinfo
->cinfo
, COL_PROTOCOL
);
503 col_add_str(pinfo
->cinfo
, COL_INFO
, col_info_str
);
506 col_clear(pinfo
->cinfo
, COL_INFO
);
508 dissector_try_uint_with_data(dis_tbl
, dissector_table_val
, payload_tvb
, pinfo
, tree
, true, dissector_data
);
515 return tvb_captured_length(tvb
);
518 /* Register the protocol with Wireshark.
522 proto_register_exported_pdu(void)
524 /*module_t *exported_pdu_module;*/
526 static hf_register_info hf
[] = {
527 { &hf_exported_pdu_tag
,
528 { "Tag", "exported_pdu.tag",
529 FT_UINT16
, BASE_DEC
, VALS(exported_pdu_tag_vals
), 0,
532 { &hf_exported_pdu_tag_len
,
533 { "Length", "exported_pdu.tag_len",
534 FT_UINT16
, BASE_DEC
, NULL
, 0,
537 { &hf_exported_pdu_unknown_tag_val
,
538 { "Unknown tags value", "exported_pdu.unknown_tag.val",
539 FT_BYTES
, BASE_NONE
, NULL
, 0,
542 { &hf_exported_pdu_prot_name
,
543 { "Protocol Name", "exported_pdu.prot_name",
544 FT_STRINGZPAD
, BASE_NONE
, NULL
, 0,
547 { &hf_exported_pdu_heur_prot_name
,
548 { "Heuristic Protocol Name", "exported_pdu.heur_prot_name",
549 FT_STRINGZPAD
, BASE_NONE
, NULL
, 0,
552 { &hf_exported_pdu_dis_table_name
,
553 { "Dissector Table Name", "exported_pdu.dis_table_name",
554 FT_STRINGZPAD
, BASE_NONE
, NULL
, 0,
557 { &hf_exported_pdu_p2p_dir
,
558 { "P2P direction", "exported_pdu.p2p_dir",
559 FT_INT32
, BASE_DEC
, VALS(exported_pdu_p2p_dir_vals
), 0,
562 { &hf_exported_pdu_dissector_data
,
563 { "TCP Dissector Data", "exported_pdu.tcp_dissector_data",
564 FT_BYTES
, BASE_NONE
, NULL
, 0,
567 { &hf_exported_pdu_ddata_version
,
568 { "TCP Dissector Data version", "exported_pdu.tcp_dissector_data.version",
569 FT_UINT16
, BASE_DEC
, NULL
, 0,
572 { &hf_exported_pdu_ddata_seq
,
573 { "Sequence number", "exported_pdu.tcp_dissector_data.seq",
574 FT_UINT32
, BASE_DEC
, NULL
, 0,
577 { &hf_exported_pdu_ddata_nxtseq
,
578 { "Next sequence number", "exported_pdu.tcp_dissector_data.nxtseq",
579 FT_UINT32
, BASE_DEC
, NULL
, 0,
582 { &hf_exported_pdu_ddata_lastackseq
,
583 { "Last acked sequence number", "exported_pdu.tcp_dissector_data.lastackseq",
584 FT_UINT32
, BASE_DEC
, NULL
, 0,
587 { &hf_exported_pdu_ddata_is_reassembled
,
588 { "Is reassembled", "exported_pdu.tcp_dissector_data.is_reassembled",
589 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
592 { &hf_exported_pdu_ddata_flags
,
593 { "Flags", "exported_pdu.tcp_dissector_data.flags",
594 FT_UINT16
, BASE_HEX
, NULL
, 0,
597 { &hf_exported_pdu_ddata_urgent_pointer
,
598 { "Urgent pointer", "exported_pdu.tcp_dissector_data.urgent_pointer",
599 FT_UINT16
, BASE_DEC
, NULL
, 0,
602 { &hf_exported_pdu_ipv4_src
,
603 { "IPv4 Src", "exported_pdu.ipv4_src",
604 FT_IPv4
, BASE_NONE
, NULL
, 0,
607 { &hf_exported_pdu_ipv4_dst
,
608 { "IPv4 Dst", "exported_pdu.ipv4_dst",
609 FT_IPv4
, BASE_NONE
, NULL
, 0,
612 { &hf_exported_pdu_ipv6_src
,
613 { "IPv6 Src", "exported_pdu.ipv6_src",
614 FT_IPv6
, BASE_NONE
, NULL
, 0,
617 { &hf_exported_pdu_ipv6_dst
,
618 { "IPv6 Dst", "exported_pdu.ipv6_dst",
619 FT_IPv6
, BASE_NONE
, NULL
, 0,
622 { &hf_exported_pdu_port_type
,
623 { "Port Type", "exported_pdu.port_type",
624 FT_UINT32
, BASE_DEC
, VALS(exported_pdu_port_type_vals
), 0,
627 { &hf_exported_pdu_src_port
,
628 { "Src Port", "exported_pdu.src_port",
629 FT_UINT32
, BASE_DEC
, NULL
, 0,
632 { &hf_exported_pdu_dst_port
,
633 { "Dst Port", "exported_pdu.dst_port",
634 FT_UINT32
, BASE_DEC
, NULL
, 0,
637 { &hf_exported_pdu_ss7_opc
,
638 { "SS7 OPC", "exported_pdu.ss7_opc",
639 FT_UINT32
, BASE_DEC
, NULL
, 0,
642 { &hf_exported_pdu_ss7_dpc
,
643 { "SS7 DPC", "exported_pdu.ss7_dpc",
644 FT_UINT32
, BASE_DEC
, NULL
, 0,
647 { &hf_exported_pdu_orig_fno
,
648 { "Original Frame Number", "exported_pdu.orig_fno",
649 FT_UINT32
, BASE_DEC
, NULL
, 0,
652 { &hf_exported_pdu_dvbci_evt
,
653 { "DVB-CI event", "exported_pdu.dvb-ci.event",
654 FT_UINT8
, BASE_HEX
, VALS(dvbci_event
), 0,
657 { &hf_exported_pdu_exported_pdu
,
658 { "Exported PDU data", "exported_pdu.exported_pdu",
659 FT_BYTES
, BASE_NONE
|BASE_NO_DISPLAY_VALUE
, NULL
, 0,
662 { &hf_exported_pdu_dis_table_val
,
663 { "Value to use when calling dissector table", "exported_pdu.dis_table_val",
664 FT_UINT32
, BASE_DEC
, NULL
, 0,
667 { &hf_exported_pdu_col_proto_str
,
668 { "Column protocol string", "exported_pdu.col_proto_str",
669 FT_STRINGZPAD
, BASE_NONE
, NULL
, 0,
672 { &hf_exported_pdu_col_info_str
,
673 { "Column information string", "exported_pdu.col_info_str",
674 FT_STRINGZPAD
, BASE_NONE
, NULL
, 0,
677 { &hf_exported_pdu_3gpp_id_type
,
678 { "3GPP Identity Type", "exported_pdu.3gpp.id_type",
679 FT_UINT8
, BASE_DEC
, VALS(exported_pdu_3gpp_id_type_vals
), 0,
682 { &hf_exported_pdu_3gpp_lac
,
683 { "LAC", "exported_pdu.3gpp.lac",
684 FT_UINT16
, BASE_HEX_DEC
, NULL
, 0,
687 { &hf_exported_pdu_3gpp_ci
,
688 { "CI", "exported_pdu.3gpp.ci",
689 FT_UINT16
, BASE_HEX_DEC
, NULL
, 0,
692 { &hf_exported_pdu_3gpp_eci
,
693 { "E-UTRAN CI", "exported_pdu.3gpp.eci",
694 FT_UINT32
, BASE_HEX_DEC
, NULL
, 0,
697 { &hf_exported_pdu_3gpp_nci
,
698 { "NR CI", "exported_pdu.3gpp.nci",
699 FT_UINT64
, BASE_HEX_DEC
, NULL
, 0,
702 { &hf_exported_pdu_3gpp_cgi
,
703 { "Cell Global Identifier", "exported_pdu.3gpp.cgi",
704 FT_UINT64
, BASE_HEX
, NULL
, 0,
707 { &hf_exported_pdu_3gpp_ecgi
,
708 { "E-UTRAN Cell Global Identifier", "exported_pdu.3gpp.ecgi",
709 FT_UINT64
, BASE_HEX
, NULL
, 0,
712 { &hf_exported_pdu_3gpp_ncgi
,
713 { "NR Cell Global Identifier", "exported_pdu.3gpp.ncgi",
714 FT_UINT64
, BASE_HEX
, NULL
, 0,
719 /* Setup protocol subtree array */
720 static int *ett
[] = {
722 &ett_exported_pdu_tag
,
723 &ett_exported_pdu_3gpp_cgi
,
726 /* Setup expert information */
727 static ei_register_info ei
[] = {
728 { &ei_exported_pdu_unsupported_version
,
729 { "exported_pdu.tcp_dissector_data.version.invalid",
730 PI_PROTOCOL
, PI_WARN
, "Unsupported TCP Dissector Data version", EXPFILL
}
732 { &ei_exported_pdu_unknown_tag
,
733 { "exported_pdu.tag.unknown",
734 PI_PROTOCOL
, PI_WARN
, "Unrecognized tag", EXPFILL
}
736 { &ei_exported_pdu_unexpected_tag_length
,
737 { "exported_pdu.tag_len.unexpected",
738 PI_PROTOCOL
, PI_WARN
, "Unexpected tag length", EXPFILL
}
741 expert_module_t
*expert_exported_pdu
;
742 module_t
*exported_pdu_module
;
744 /* Register the protocol name and description */
745 proto_exported_pdu
= proto_register_protocol("EXPORTED_PDU", "Exported PDU", "exported_pdu");
747 expert_exported_pdu
= expert_register_protocol(proto_exported_pdu
);
748 expert_register_field_array(expert_exported_pdu
, ei
, array_length(ei
));
750 exported_pdu_handle
= register_dissector("exported_pdu", dissect_exported_pdu
, proto_exported_pdu
);
752 /* Required function calls to register the header fields and subtrees */
753 proto_register_field_array(proto_exported_pdu
, hf
, array_length(hf
));
754 proto_register_subtree_array(ett
, array_length(ett
));
756 /* Register configuration preferences */
757 exported_pdu_module
= prefs_register_protocol(proto_exported_pdu
, NULL
);
758 prefs_register_dissector_preference(exported_pdu_module
, "user_data_pdu",
759 "User Data PDU dissector", "The dissector to use for User Data PDU", &user_data_pdu
);
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
765 register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_3
);
766 register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_4
);
767 register_export_pdu_tap(EXPORT_PDU_TAP_NAME_LAYER_7
);
771 proto_reg_handoff_exported_pdu(void)
773 static bool initialized
= false;
776 dissector_add_uint("wtap_encap", WTAP_ENCAP_WIRESHARK_UPPER_PDU
, exported_pdu_handle
);
780 ss7pc_address_type
= address_type_get_by_name("AT_SS7PC");
782 /* Get the hf id of some fields from the IP dissectors to be able to use them here*/
783 hf_ip_addr
= proto_registrar_get_id_byname("ip.addr");
784 hf_ip_dst
= proto_registrar_get_id_byname("ip.dst");
785 hf_ip_src
= proto_registrar_get_id_byname("ip.src");
786 hf_ipv6_addr
= proto_registrar_get_id_byname("ipv6.addr");
787 hf_ipv6_dst
= proto_registrar_get_id_byname("ipv6.dst");
788 hf_ipv6_src
= proto_registrar_get_id_byname("ipv6.src");
793 * Editor modelines - https://www.wireshark.org/tools/modelines.html
798 * indent-tabs-mode: nil
801 * vi: set shiftwidth=4 tabstop=8 expandtab:
802 * :indentSize=4:tabSize=8:noTabs=true: