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
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"
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;
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;
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;
88 pkt_info
->rrpd
.session_id
= dcerpc_cn_ctx_id
;
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];
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 */
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;
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
];
136 uint64_t msg_id
[MAX_RETURNED_ELEMENTS
];
139 /* set the direction information */
140 if (pkt_info
->dstport
== 445)
141 pkt_info
->rrpd
.c2s
= true;
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 */
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
;
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;
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;
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];
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;
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;
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;
325 * Editor modelines - https://www.wireshark.org/tools/modelines.html
330 * indent-tabs-mode: nil
333 * vi: set shiftwidth=4 tabstop=8 expandtab:
334 * :indentSize=4:tabSize=8:noTabs=true: