Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-exported_pdu.c
blob08d08c6c958728a0978b6a2cd0da780d11f25e3c
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
12 #include "config.h"
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;
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;
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" },
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" },
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" },
128 { 0, NULL }
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" },
151 { 0, NULL }
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 }
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 }
168 static port_type exp_pdu_port_type_to_ws_port_type(uint32_t type)
170 switch (type)
172 case EXP_PDU_PT_NONE:
173 return PT_NONE;
174 case EXP_PDU_PT_SCTP:
175 return PT_SCTP;
176 case EXP_PDU_PT_TCP:
177 return PT_TCP;
178 case EXP_PDU_PT_UDP:
179 return PT_UDP;
180 case EXP_PDU_PT_DCCP:
181 return PT_DCCP;
182 case EXP_PDU_PT_IPX:
183 return PT_IPX;
184 case EXP_PDU_PT_DDP:
185 return PT_DDP;
186 case EXP_PDU_PT_IDP:
187 return PT_IDP;
188 case EXP_PDU_PT_USB:
189 return PT_USB;
190 case EXP_PDU_PT_I2C:
191 return PT_I2C;
192 case EXP_PDU_PT_IBQP:
193 return PT_IBQP;
194 case EXP_PDU_PT_BLUETOOTH:
195 return PT_BLUETOOTH;
196 case EXP_PDU_PT_EXCHG:
197 case EXP_PDU_PT_TIPC:
198 case EXP_PDU_PT_TDMOP:
199 case EXP_PDU_PT_NCP:
200 case EXP_PDU_PT_SBCCS:
201 //no longer supported
202 break;
205 DISSECTOR_ASSERT(false);
206 return PT_NONE;
209 static void
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;
214 uint32_t ci_type;
215 int bit_offset = offset * 8;
216 if (tag_len == 0){
217 proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, 0);
218 return;
220 proto_tree_add_item_ret_uint(tag_tree, hf_exported_pdu_3gpp_id_type, tvb, offset, 1, ENC_BIG_ENDIAN, &ci_type);
221 offset += 1;
222 bit_offset += 8;
223 switch (ci_type) {
224 case EXP_PDU_3GPP_ID_CGI:
225 if (tag_len < 8) {
226 proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, tag_len);
227 } else {
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);
234 break;
235 case EXP_PDU_3GPP_ID_ECGI:
236 if (tag_len < 8) {
237 proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, tag_len);
238 } else {
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);
245 break;
246 case EXP_PDU_3GPP_ID_NCGI:
247 if (tag_len < 9) {
248 proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unexpected_tag_length, tvb, offset, tag_len);
249 } else {
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);
256 break;
257 default:
258 proto_tree_add_expert(tag_tree, pinfo, &ei_exported_pdu_unknown_tag, tvb, offset, tag_len);
259 break;
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_)
267 proto_item *exported_pdu_ti, *ti, *item;
268 proto_tree *exported_pdu_tree, *tag_tree;
269 tvbuff_t * payload_tvb = NULL;
270 int offset = 0;
271 uint32_t tag;
272 int tag_len;
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;
281 uint32_t dvb_ci_dir;
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);
292 do {
293 ti = proto_tree_add_item_ret_uint(exported_pdu_tree, hf_exported_pdu_tag, tvb, offset, 2, ENC_BIG_ENDIAN, &tag);
294 offset+=2;
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);
299 offset+=2;
301 switch(tag) {
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);
305 break;
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);
309 break;
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);
313 break;
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);
324 break;
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);
334 break;
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);
344 break;
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);
354 break;
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);
358 break;
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);
361 break;
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);
364 break;
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);
372 break;
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);
380 break;
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);
383 break;
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);
388 break;
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);
391 break;
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);
394 break;
395 case EXP_PDU_TAG_TCP_INFO_DATA:
397 struct tcpinfo* tcpdata = wmem_new0(pinfo->pool, struct tcpinfo);
398 uint32_t u32;
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);
403 if (u32 == 1) {
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);
423 break;
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);
427 break;
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);
430 break;
431 case EXP_PDU_TAG_USER_DATA_PDU:
432 next_proto_type = EXPORTED_PDU_NEXT_DISSECTOR_STR;
433 proto_name = user_data_pdu;
434 break;
435 case EXP_PDU_TAG_3GPP_ID:
436 dissect_3gpp_id(tvb, pinfo, tag_tree, offset, tag_len);
437 break;
438 case EXP_PDU_TAG_END_OF_OPT:
439 break;
440 default:
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);
443 break;
446 offset = offset + tag_len;
448 } while(tag != 0);
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);
459 if (proto_handle) {
460 if (col_proto_str) {
461 col_add_str(pinfo->cinfo, COL_PROTOCOL, col_proto_str);
462 } else {
463 col_clear(pinfo->cinfo, COL_PROTOCOL);
465 if (col_info_str) {
466 col_add_str(pinfo->cinfo, COL_INFO, col_info_str);
468 else {
469 col_clear(pinfo->cinfo, COL_INFO);
471 call_dissector_with_data(proto_handle, payload_tvb, pinfo, tree, dissector_data);
473 break;
474 case EXPORTED_PDU_NEXT_HEUR_DISSECTOR_STR:
476 heur_dtbl_entry_t *heur_diss = find_heur_dissector_by_unique_short_name(proto_name);
477 if (heur_diss) {
478 if (col_proto_str) {
479 col_add_str(pinfo->cinfo, COL_PROTOCOL, col_proto_str);
480 } else {
481 col_clear(pinfo->cinfo, COL_PROTOCOL);
483 if (col_info_str) {
484 col_add_str(pinfo->cinfo, COL_INFO, col_info_str);
486 else {
487 col_clear(pinfo->cinfo, COL_INFO);
489 call_heur_dissector_direct(heur_diss, payload_tvb, pinfo, tree, dissector_data);
491 break;
493 case EXPORTED_PDU_NEXT_DIS_TABLE_STR:
495 dis_tbl = find_dissector_table(dissector_table);
496 if (dis_tbl) {
497 if (col_proto_str) {
498 col_add_str(pinfo->cinfo, COL_PROTOCOL, col_proto_str);
499 } else {
500 col_clear(pinfo->cinfo, COL_PROTOCOL);
502 if (col_info_str) {
503 col_add_str(pinfo->cinfo, COL_INFO, col_info_str);
505 else {
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);
511 default:
512 break;
515 return tvb_captured_length(tvb);
518 /* Register the protocol with Wireshark.
521 void
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,
530 NULL, HFILL }
532 { &hf_exported_pdu_tag_len,
533 { "Length", "exported_pdu.tag_len",
534 FT_UINT16, BASE_DEC, NULL, 0,
535 NULL, HFILL }
537 { &hf_exported_pdu_unknown_tag_val,
538 { "Unknown tags value", "exported_pdu.unknown_tag.val",
539 FT_BYTES, BASE_NONE, NULL, 0,
540 NULL, HFILL }
542 { &hf_exported_pdu_prot_name,
543 { "Protocol Name", "exported_pdu.prot_name",
544 FT_STRINGZPAD, BASE_NONE, NULL, 0,
545 NULL, HFILL }
547 { &hf_exported_pdu_heur_prot_name,
548 { "Heuristic Protocol Name", "exported_pdu.heur_prot_name",
549 FT_STRINGZPAD, BASE_NONE, NULL, 0,
550 NULL, HFILL }
552 { &hf_exported_pdu_dis_table_name,
553 { "Dissector Table Name", "exported_pdu.dis_table_name",
554 FT_STRINGZPAD, BASE_NONE, NULL, 0,
555 NULL, HFILL }
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,
560 NULL, HFILL }
562 { &hf_exported_pdu_dissector_data,
563 { "TCP Dissector Data", "exported_pdu.tcp_dissector_data",
564 FT_BYTES, BASE_NONE, NULL, 0,
565 NULL, HFILL }
567 { &hf_exported_pdu_ddata_version,
568 { "TCP Dissector Data version", "exported_pdu.tcp_dissector_data.version",
569 FT_UINT16, BASE_DEC, NULL, 0,
570 NULL, HFILL }
572 { &hf_exported_pdu_ddata_seq,
573 { "Sequence number", "exported_pdu.tcp_dissector_data.seq",
574 FT_UINT32, BASE_DEC, NULL, 0,
575 NULL, HFILL }
577 { &hf_exported_pdu_ddata_nxtseq,
578 { "Next sequence number", "exported_pdu.tcp_dissector_data.nxtseq",
579 FT_UINT32, BASE_DEC, NULL, 0,
580 NULL, HFILL }
582 { &hf_exported_pdu_ddata_lastackseq,
583 { "Last acked sequence number", "exported_pdu.tcp_dissector_data.lastackseq",
584 FT_UINT32, BASE_DEC, NULL, 0,
585 NULL, HFILL }
587 { &hf_exported_pdu_ddata_is_reassembled,
588 { "Is reassembled", "exported_pdu.tcp_dissector_data.is_reassembled",
589 FT_BOOLEAN, BASE_NONE, NULL, 0,
590 NULL, HFILL }
592 { &hf_exported_pdu_ddata_flags,
593 { "Flags", "exported_pdu.tcp_dissector_data.flags",
594 FT_UINT16, BASE_HEX, NULL, 0,
595 NULL, HFILL }
597 { &hf_exported_pdu_ddata_urgent_pointer,
598 { "Urgent pointer", "exported_pdu.tcp_dissector_data.urgent_pointer",
599 FT_UINT16, BASE_DEC, NULL, 0,
600 NULL, HFILL }
602 { &hf_exported_pdu_ipv4_src,
603 { "IPv4 Src", "exported_pdu.ipv4_src",
604 FT_IPv4, BASE_NONE, NULL, 0,
605 NULL, HFILL }
607 { &hf_exported_pdu_ipv4_dst,
608 { "IPv4 Dst", "exported_pdu.ipv4_dst",
609 FT_IPv4, BASE_NONE, NULL, 0,
610 NULL, HFILL }
612 { &hf_exported_pdu_ipv6_src,
613 { "IPv6 Src", "exported_pdu.ipv6_src",
614 FT_IPv6, BASE_NONE, NULL, 0,
615 NULL, HFILL }
617 { &hf_exported_pdu_ipv6_dst,
618 { "IPv6 Dst", "exported_pdu.ipv6_dst",
619 FT_IPv6, BASE_NONE, NULL, 0,
620 NULL, HFILL }
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,
625 NULL, HFILL }
627 { &hf_exported_pdu_src_port,
628 { "Src Port", "exported_pdu.src_port",
629 FT_UINT32, BASE_DEC, NULL, 0,
630 NULL, HFILL }
632 { &hf_exported_pdu_dst_port,
633 { "Dst Port", "exported_pdu.dst_port",
634 FT_UINT32, BASE_DEC, NULL, 0,
635 NULL, HFILL }
637 { &hf_exported_pdu_ss7_opc,
638 { "SS7 OPC", "exported_pdu.ss7_opc",
639 FT_UINT32, BASE_DEC, NULL, 0,
640 NULL, HFILL }
642 { &hf_exported_pdu_ss7_dpc,
643 { "SS7 DPC", "exported_pdu.ss7_dpc",
644 FT_UINT32, BASE_DEC, NULL, 0,
645 NULL, HFILL }
647 { &hf_exported_pdu_orig_fno,
648 { "Original Frame Number", "exported_pdu.orig_fno",
649 FT_UINT32, BASE_DEC, NULL, 0,
650 NULL, HFILL }
652 { &hf_exported_pdu_dvbci_evt,
653 { "DVB-CI event", "exported_pdu.dvb-ci.event",
654 FT_UINT8, BASE_HEX, VALS(dvbci_event), 0,
655 NULL, HFILL }
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,
660 NULL, HFILL }
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,
665 NULL, HFILL }
667 { &hf_exported_pdu_col_proto_str,
668 { "Column protocol string", "exported_pdu.col_proto_str",
669 FT_STRINGZPAD, BASE_NONE, NULL, 0,
670 NULL, HFILL }
672 { &hf_exported_pdu_col_info_str,
673 { "Column information string", "exported_pdu.col_info_str",
674 FT_STRINGZPAD, BASE_NONE, NULL, 0,
675 NULL, HFILL }
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,
680 NULL, HFILL }
682 { &hf_exported_pdu_3gpp_lac,
683 { "LAC", "exported_pdu.3gpp.lac",
684 FT_UINT16, BASE_HEX_DEC, NULL, 0,
685 NULL, HFILL }
687 { &hf_exported_pdu_3gpp_ci,
688 { "CI", "exported_pdu.3gpp.ci",
689 FT_UINT16, BASE_HEX_DEC, NULL, 0,
690 NULL, HFILL }
692 { &hf_exported_pdu_3gpp_eci,
693 { "E-UTRAN CI", "exported_pdu.3gpp.eci",
694 FT_UINT32, BASE_HEX_DEC, NULL, 0,
695 NULL, HFILL }
697 { &hf_exported_pdu_3gpp_nci,
698 { "NR CI", "exported_pdu.3gpp.nci",
699 FT_UINT64, BASE_HEX_DEC, NULL, 0,
700 NULL, HFILL }
702 { &hf_exported_pdu_3gpp_cgi,
703 { "Cell Global Identifier", "exported_pdu.3gpp.cgi",
704 FT_UINT64, BASE_HEX, NULL, 0,
705 NULL, HFILL }
707 { &hf_exported_pdu_3gpp_ecgi,
708 { "E-UTRAN Cell Global Identifier", "exported_pdu.3gpp.ecgi",
709 FT_UINT64, BASE_HEX, NULL, 0,
710 NULL, HFILL }
712 { &hf_exported_pdu_3gpp_ncgi,
713 { "NR Cell Global Identifier", "exported_pdu.3gpp.ncgi",
714 FT_UINT64, BASE_HEX, NULL, 0,
715 NULL, HFILL }
719 /* Setup protocol subtree array */
720 static int *ett[] = {
721 &ett_exported_pdu,
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);
770 void
771 proto_reg_handoff_exported_pdu(void)
773 static bool initialized = false;
775 if (!initialized) {
776 dissector_add_uint("wtap_encap", WTAP_ENCAP_WIRESHARK_UPPER_PDU, exported_pdu_handle);
777 initialized = true;
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
795 * Local variables:
796 * c-basic-offset: 4
797 * tab-width: 8
798 * indent-tabs-mode: nil
799 * End:
801 * vi: set shiftwidth=4 tabstop=8 expandtab:
802 * :indentSize=4:tabSize=8:noTabs=true: