regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / plugins / epan / transum / decoders.c
bloba67db053f08eaecc869ca4ed9bd137d29aa5de8b
1 /* decoders.c
2 * Routines for the TRANSUM response time analyzer post-dissector
3 * By Paul Offord <paul.offord@advance7.com>
4 * Copyright 2016 Advance Seven Limited
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <stdio.h>
16 #include <epan/packet.h>
17 #include <epan/prefs.h>
18 #include <epan/dissectors/packet-tcp.h>
19 #include "packet-transum.h"
20 #include "preferences.h"
21 #include "extractors.h"
22 #include "decoders.h"
24 extern TSUM_PREFERENCES preferences;
27 /* Returns the number of sub-packets of interest */
28 int decode_syn(packet_info *pinfo _U_, proto_tree *tree _U_, PKT_INFO* pkt_info)
30 if (pkt_info->tcp_flags_ack)
31 pkt_info->rrpd.c2s = false;
32 else
34 pkt_info->rrpd.c2s = true;
35 add_detected_tcp_svc(pkt_info->dstport);
38 pkt_info->rrpd.session_id = 1; /* Fake session ID */
39 pkt_info->rrpd.msg_id = 1; /* Fake message ID */
40 pkt_info->rrpd.decode_based = true;
41 pkt_info->rrpd.calculation = RTE_CALC_SYN;
42 pkt_info->pkt_of_interest = true;
44 return 1;
48 This function sets basic information in the sub_packet entry.
49 Because we don't expect multiple DCE-RPC messages in a single packet
50 we only use single PKT_INFO
52 Returns the number of sub-packets of interest, which in this case is always 1.
54 int decode_dcerpc(packet_info *pinfo _U_, proto_tree *tree, PKT_INFO* pkt_info)
56 uint32_t field_uint[MAX_RETURNED_ELEMENTS]; /* An extracted field array for unsigned integers */
57 size_t field_value_count; /* How many entries are there in the extracted field array */
58 uint32_t dcerpc_cn_ctx_id = 0;
60 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_DCERPC_VER].hf, field_uint, &field_value_count))
62 if (field_value_count)
63 pkt_info->dcerpc_ver = field_uint[0];
66 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_DCERPC_PKT_TYPE].hf, field_uint, &field_value_count))
68 if (field_value_count)
69 pkt_info->dcerpc_pkt_type = field_uint[0];
72 if (field_value_count)
74 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_DCERPC_CN_CTX_ID].hf, field_uint, &field_value_count))
76 if (field_value_count)
77 dcerpc_cn_ctx_id = field_uint[0];
80 if (is_dcerpc_context_zero(pkt_info->dcerpc_pkt_type))
81 { /* This is needed to overcome an apparent Wireshark bug
82 found in the Lua code - is this still true in C? */
83 pkt_info->rrpd.session_id = 1;
85 else
87 if (dcerpc_cn_ctx_id)
88 pkt_info->rrpd.session_id = dcerpc_cn_ctx_id;
89 else
90 pkt_info->rrpd.session_id = 1;
92 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_DCERPC_CN_CALL_ID].hf, field_uint, &field_value_count))
94 if (field_value_count)
95 pkt_info->rrpd.msg_id = field_uint[0];
98 else
101 we don't have header information and so by setting the session_id and msg_id to zero
102 the rrpd functions will either create a new rrpd_list (or temp_rsp_rrpd_list) entry
103 or update the last entry for this ip_proto:stream_no.
105 pkt_info->rrpd.session_id = 0;
106 pkt_info->rrpd.msg_id = 0;
110 if (is_dcerpc_req_pkt_type(pkt_info->dcerpc_pkt_type))
112 pkt_info->rrpd.c2s = true;
113 wmem_map_insert(preferences.tcp_svc_ports, GUINT_TO_POINTER(pkt_info->dstport), GUINT_TO_POINTER(RTE_CALC_DCERPC)); /* make sure we have this DCE-RPC service port set */
115 else
117 pkt_info->rrpd.c2s = false;
118 wmem_map_insert(preferences.tcp_svc_ports, GUINT_TO_POINTER(pkt_info->srcport), GUINT_TO_POINTER(RTE_CALC_DCERPC)); /* make sure we have this DCE-RPC service port set */
121 pkt_info->rrpd.decode_based = true;
122 pkt_info->rrpd.calculation = RTE_CALC_DCERPC;
123 pkt_info->pkt_of_interest = true;
125 return 1;
128 /* Returns the number of sub-packets of interest */
129 int decode_smb(packet_info *pinfo _U_, proto_tree *tree, PKT_INFO* pkt_info, PKT_INFO* subpackets)
131 uint32_t field_uint[MAX_RETURNED_ELEMENTS]; /* An extracted field array for unsigned integers */
132 size_t field_value_count; /* How many entries are there in the extracted field array */
134 uint64_t ses_id[MAX_RETURNED_ELEMENTS];
135 size_t ses_id_count;
136 uint64_t msg_id[MAX_RETURNED_ELEMENTS];
137 size_t msg_id_count;
139 /* set the direction information */
140 if (pkt_info->dstport == 445)
141 pkt_info->rrpd.c2s = true;
142 else
143 pkt_info->rrpd.c2s = false;
145 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_SMB_MID].hf, field_uint, &field_value_count))
147 if (field_value_count)
149 pkt_info->rrpd.calculation = RTE_CALC_SMB1;
150 pkt_info->pkt_of_interest = false; /* can't process SMB1 at the moment */
151 return 0;
154 /* Default in case we don't have header information */
155 pkt_info->rrpd.session_id = 0;
156 pkt_info->rrpd.msg_id = 0;
157 pkt_info->rrpd.decode_based = true;
158 pkt_info->rrpd.calculation = RTE_CALC_SMB2;
159 pkt_info->pkt_of_interest = true;
161 extract_ui64(tree, hf_of_interest[HF_INTEREST_SMB2_MSG_ID].hf, msg_id, &msg_id_count);
162 if (msg_id_count) /* test for header information */
164 extract_ui64(tree, hf_of_interest[HF_INTEREST_SMB2_SES_ID].hf, ses_id, &ses_id_count);
166 for (size_t i = 0; (i < msg_id_count) && (i < MAX_SUBPKTS_PER_PACKET); i++)
168 subpackets[i].rrpd.c2s = pkt_info->rrpd.c2s;
169 subpackets[i].rrpd.ip_proto = pkt_info->rrpd.ip_proto;
170 subpackets[i].rrpd.stream_no = pkt_info->rrpd.stream_no;
172 subpackets[i].rrpd.session_id = ses_id[i];
173 subpackets[i].rrpd.msg_id = msg_id[i];
175 subpackets[i].rrpd.decode_based = true;
176 subpackets[i].rrpd.calculation = RTE_CALC_SMB2;
177 subpackets[i].pkt_of_interest = true;
179 return (int)msg_id_count;
182 return 1;
185 /* Returns the number of sub-packets of interest */
186 int decode_gtcp(packet_info *pinfo, proto_tree *tree, PKT_INFO* pkt_info)
188 uint32_t field_uint[MAX_RETURNED_ELEMENTS]; /* An extracted field array for unsigned integers */
189 bool field_bool[MAX_RETURNED_ELEMENTS]; /* An extracted field array for unsigned integers */
190 size_t field_value_count; /* How many entries are there in the extracted field array */
192 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_TCP_STREAM].hf, field_uint, &field_value_count)) {
193 if (field_value_count)
194 pkt_info->rrpd.stream_no = field_uint[0];
197 pkt_info->srcport = pinfo->srcport;
198 pkt_info->dstport = pinfo->destport;
200 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_TCP_LEN].hf, field_uint, &field_value_count)) {
201 if (field_value_count)
202 pkt_info->len = field_uint[0];
205 if (!extract_bool(tree, hf_of_interest[HF_INTEREST_TCP_FLAGS_SYN].hf, field_bool, &field_value_count)) {
206 if (field_value_count)
207 pkt_info->tcp_flags_syn = field_bool[0];
210 if (!extract_bool(tree, hf_of_interest[HF_INTEREST_TCP_FLAGS_ACK].hf, field_bool, &field_value_count)) {
211 if (field_value_count)
212 pkt_info->tcp_flags_ack = field_bool[0];
215 if (!extract_bool(tree, hf_of_interest[HF_INTEREST_TCP_FLAGS_RESET].hf, field_bool, &field_value_count)) {
216 if (field_value_count)
217 pkt_info->tcp_flags_reset = field_bool[0];
221 * This is an expert info, not a field with a value, so it's either
222 * present or not; if present, it's a retransmission.
224 if (!extract_instance_count(tree, hf_of_interest[HF_INTEREST_TCP_RETRAN].hf, &field_value_count)) {
225 if (field_value_count)
226 pkt_info->tcp_retran = true;
227 else
228 pkt_info->tcp_retran = false;
232 * Another expert info.
234 if (!extract_instance_count(tree, hf_of_interest[HF_INTEREST_TCP_KEEP_ALIVE].hf, &field_value_count)) {
235 if (field_value_count)
236 pkt_info->tcp_retran = true;
237 else
238 pkt_info->tcp_retran = false;
241 /* we use the SSL Content Type to detect SSL Alerts */
242 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_SSL_CONTENT_TYPE].hf, field_uint, &field_value_count))
244 if (field_value_count)
245 pkt_info->ssl_content_type = field_uint[0];
246 else
247 pkt_info->ssl_content_type = 0;
250 if (wmem_map_lookup(preferences.tcp_svc_ports, GUINT_TO_POINTER(pkt_info->dstport)) != NULL ||
251 wmem_map_lookup(preferences.tcp_svc_ports, GUINT_TO_POINTER(pkt_info->srcport)) != NULL)
253 if (wmem_map_lookup(preferences.tcp_svc_ports, GUINT_TO_POINTER(pkt_info->dstport)) != NULL)
254 pkt_info->rrpd.c2s = true;
256 pkt_info->rrpd.is_retrans = pkt_info->tcp_retran;
257 pkt_info->rrpd.session_id = 0;
258 pkt_info->rrpd.msg_id = 0;
259 pkt_info->rrpd.calculation = RTE_CALC_GTCP;
260 pkt_info->rrpd.decode_based = false;
261 if (pkt_info->len > 0)
262 pkt_info->pkt_of_interest = true;
264 return 1;
267 return 0;
270 /* Returns the number of sub-packets of interest */
271 int decode_dns(packet_info *pinfo _U_, proto_tree *tree, PKT_INFO* pkt_info)
273 uint32_t field_uint[MAX_RETURNED_ELEMENTS]; /* An extracted field array for unsigned integers */
274 size_t field_value_count; /* How many entries are there in the extracted field array */
276 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_DNS_ID].hf, field_uint, &field_value_count)) {
277 if (field_value_count)
278 pkt_info->rrpd.msg_id = field_uint[0];
281 pkt_info->rrpd.session_id = 1;
282 pkt_info->rrpd.decode_based = true;
283 pkt_info->rrpd.calculation = RTE_CALC_DNS;
284 pkt_info->pkt_of_interest = true;
286 return 1;
289 /* Returns the number of sub-packets of interest */
290 int decode_gudp(packet_info *pinfo, proto_tree *tree, PKT_INFO* pkt_info)
292 uint32_t field_uint[MAX_RETURNED_ELEMENTS]; /* An extracted field array for unsigned integers */
293 size_t field_value_count; /* How many entries are there in the extracted field array */
295 pkt_info->srcport = pinfo->srcport;
296 pkt_info->dstport = pinfo->destport;
298 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_UDP_STREAM].hf, field_uint, &field_value_count)) {
299 if (field_value_count)
300 pkt_info->rrpd.stream_no = field_uint[0];
303 if (!extract_uint(tree, hf_of_interest[HF_INTEREST_UDP_LENGTH].hf, field_uint, &field_value_count)) {
304 if (field_value_count)
305 pkt_info->len = field_uint[0];
308 if ((wmem_map_lookup(preferences.udp_svc_ports, GUINT_TO_POINTER(pkt_info->dstport)) != NULL) ||
309 (wmem_map_lookup(preferences.udp_svc_ports, GUINT_TO_POINTER(pkt_info->srcport)) != NULL))
311 if (wmem_map_lookup(preferences.udp_svc_ports, GUINT_TO_POINTER(pkt_info->dstport)) != NULL)
312 pkt_info->rrpd.c2s = true;
314 pkt_info->rrpd.session_id = 0;
315 pkt_info->rrpd.msg_id = 0;
316 pkt_info->rrpd.decode_based = false;
317 pkt_info->rrpd.calculation = RTE_CALC_GUDP;
318 pkt_info->pkt_of_interest = true;
321 return 1;
325 * Editor modelines - https://www.wireshark.org/tools/modelines.html
327 * Local variables:
328 * c-basic-offset: 4
329 * tab-width: 8
330 * indent-tabs-mode: nil
331 * End:
333 * vi: set shiftwidth=4 tabstop=8 expandtab:
334 * :indentSize=4:tabSize=8:noTabs=true: