Bug Summary

File:epan/frame_data.c
Warning:line 50, column 19
Value stored to 'prev_abs_ts' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name frame_data.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-20/lib/clang/20 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-09-14-100349-3933-1 -x c /builds/wireshark/wireshark/epan/frame_data.c
1/* frame_data.c
2 * Routines for packet disassembly
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12#include "config.h"
13
14#include <glib.h>
15
16#include <epan/epan.h>
17#include <epan/frame_data.h>
18#include <epan/column-utils.h>
19#include <epan/timestamp.h>
20#include <wiretap/wtap.h>
21#include <wsutil/ws_assert.h>
22
23#define COMPARE_FRAME_NUM()((fdata1->num < fdata2->num) ? -1 : (fdata1->num >
fdata2->num) ? 1 : 0)
((fdata1->num < fdata2->num) ? -1 : \
24 (fdata1->num > fdata2->num) ? 1 : \
25 0)
26
27#define COMPARE_NUM(f)((fdata1->f < fdata2->f) ? -1 : (fdata1->f > fdata2
->f) ? 1 : ((fdata1->num < fdata2->num) ? -1 : (fdata1
->num > fdata2->num) ? 1 : 0))
((fdata1->f < fdata2->f) ? -1 : \
28 (fdata1->f > fdata2->f) ? 1 : \
29 COMPARE_FRAME_NUM()((fdata1->num < fdata2->num) ? -1 : (fdata1->num >
fdata2->num) ? 1 : 0)
)
30
31/* Compare time stamps.
32 A packet whose time is a reference time is considered to have
33 a lower time stamp than any frame with a non-reference time;
34 if both packets' times are reference times, we compare the
35 times of the packets. */
36#define COMPARE_TS_REAL(time1, time2)((fdata1->ref_time && !fdata2->ref_time) ? -1 :
(!fdata1->ref_time && fdata2->ref_time) ? 1 : (
(time1).secs < (time2).secs) ? -1 : ((time1).secs > (time2
).secs) ? 1 : ((time1).nsecs < (time2).nsecs) ? -1 : ((time1
).nsecs > (time2).nsecs) ? 1 : ((fdata1->num < fdata2
->num) ? -1 : (fdata1->num > fdata2->num) ? 1 : 0
))
\
37 ((fdata1->ref_time && !fdata2->ref_time) ? -1 : \
38 (!fdata1->ref_time && fdata2->ref_time) ? 1 : \
39 ((time1).secs < (time2).secs) ? -1 : \
40 ((time1).secs > (time2).secs) ? 1 : \
41 ((time1).nsecs < (time2).nsecs) ? -1 :\
42 ((time1).nsecs > (time2).nsecs) ? 1 : \
43 COMPARE_FRAME_NUM()((fdata1->num < fdata2->num) ? -1 : (fdata1->num >
fdata2->num) ? 1 : 0)
)
44
45#define COMPARE_TS(ts)((fdata1->ref_time && !fdata2->ref_time) ? -1 :
(!fdata1->ref_time && fdata2->ref_time) ? 1 : (
(fdata1->ts).secs < (fdata2->ts).secs) ? -1 : ((fdata1
->ts).secs > (fdata2->ts).secs) ? 1 : ((fdata1->ts
).nsecs < (fdata2->ts).nsecs) ? -1 : ((fdata1->ts).nsecs
> (fdata2->ts).nsecs) ? 1 : ((fdata1->num < fdata2
->num) ? -1 : (fdata1->num > fdata2->num) ? 1 : 0
))
COMPARE_TS_REAL(fdata1->ts, fdata2->ts)((fdata1->ref_time && !fdata2->ref_time) ? -1 :
(!fdata1->ref_time && fdata2->ref_time) ? 1 : (
(fdata1->ts).secs < (fdata2->ts).secs) ? -1 : ((fdata1
->ts).secs > (fdata2->ts).secs) ? 1 : ((fdata1->ts
).nsecs < (fdata2->ts).nsecs) ? -1 : ((fdata1->ts).nsecs
> (fdata2->ts).nsecs) ? 1 : ((fdata1->num < fdata2
->num) ? -1 : (fdata1->num > fdata2->num) ? 1 : 0
))
46
47static bool_Bool
48frame_delta_abs_time(const struct epan_session *epan, const frame_data *fdata, uint32_t prev_num, nstime_t *delta)
49{
50 const nstime_t *prev_abs_ts = (prev_num) ? epan_get_frame_ts(epan, prev_num) : NULL((void*)0);
Value stored to 'prev_abs_ts' during its initialization is never read
51
52 if (!fdata->has_ts) {
53 /* We don't have a time stamp for this packet. Set the delta time
54 to zero, and return false. */
55 nstime_set_zero(delta);
56 return false0;
57 }
58
59 if (prev_num == 0) {
60 /* The previous frame doesn't exist. Set the delta time to zero,
61 and return false. */
62 nstime_set_zero(delta);
63 return false0;
64 }
65
66 /* Ge the previous frame's time stamp, if it has one. */
67 prev_abs_ts = epan_get_frame_ts(epan, prev_num);
68 if (prev_abs_ts == NULL((void*)0)) {
69 /* The previous frame doesn't have a time stamp. Set the delta
70 time to zero, and return false. */
71 nstime_set_zero(delta);
72 return false0;
73 }
74
75 /* This frame has a time stamp, the previous frame exists and has a
76 time stamp; compute the delta between this frame's time stamp and
77 the previous frame's time stamp, and return true. */
78 nstime_delta(delta, &fdata->abs_ts, prev_abs_ts);
79 return true1;
80}
81
82static int
83frame_compare_time_deltas(const frame_data *fdata1, bool_Bool have_ts1, const nstime_t *ts1,
84 const frame_data *fdata2, bool_Bool have_ts2, const nstime_t *ts2)
85{
86 if (!have_ts1) {
87 if (!have_ts2) {
88 /* We don't have either delta time; sort them the same. */
89 return 0;
90 }
91
92 /*
93 * We don't have ts1 but do have ts2; treat the first
94 * as sorting lower than the second.
95 */
96 return -1;
97 }
98 if (!have_ts2) {
99 /*
100 * We have ts1 but don't have ts2; treat the first as
101 * sorting greater than the second.
102 */
103 return 1;
104 }
105
106 /*
107 * We have ts1 and ts2; compare them.
108 */
109 return COMPARE_TS_REAL(*ts1, *ts2)((fdata1->ref_time && !fdata2->ref_time) ? -1 :
(!fdata1->ref_time && fdata2->ref_time) ? 1 : (
(*ts1).secs < (*ts2).secs) ? -1 : ((*ts1).secs > (*ts2)
.secs) ? 1 : ((*ts1).nsecs < (*ts2).nsecs) ? -1 : ((*ts1).
nsecs > (*ts2).nsecs) ? 1 : ((fdata1->num < fdata2->
num) ? -1 : (fdata1->num > fdata2->num) ? 1 : 0))
;
110}
111
112bool_Bool
113frame_rel_first_frame_time(const struct epan_session *epan,
114 const frame_data *fdata, nstime_t *delta)
115{
116 /*
117 * Time relative to the first frame in the capture.
118 */
119 return frame_delta_abs_time(epan, fdata, 1, delta);
120}
121
122bool_Bool
123frame_rel_time(const struct epan_session *epan, const frame_data *fdata,
124 nstime_t *delta)
125{
126 /*
127 * Time relative to the previous reference frame or, if there is no
128 * previous reference frame, the first frame in the capture.
129 */
130 return frame_delta_abs_time(epan, fdata,
131 fdata->frame_ref_num == 0 ? 1 : fdata->frame_ref_num,
132 delta);
133}
134
135bool_Bool
136frame_rel_start_time(const struct epan_session *epan, const frame_data *fdata,
137 nstime_t *delta)
138{
139 if (!fdata->has_ts) {
140 /* We don't have a time stamp for this packet. Set the delta time
141 to zero, and return false. */
142 /* XXX - Would it make more sense to set the delta time to "unset"
143 * rather than zero here and in similar functions when returning
144 * false? */
145 nstime_set_zero(delta);
146 return false0;
147 }
148
149 const nstime_t *start_ts = epan_get_start_ts(epan);
150
151 if (start_ts == NULL((void*)0) || nstime_is_unset(start_ts)) {
152 /* There isn't an explicit start time. Set the delta
153 time to zero, and return false. */
154 nstime_set_zero(delta);
155 return false0;
156 }
157
158 /* This frame has a time stamp and the start time stamp exists;
159 compute the delta between this frame's time stamp and
160 the start time stamp, and return true. */
161 nstime_delta(delta, &fdata->abs_ts, start_ts);
162 return true1;
163}
164
165static int
166frame_compare_rel_times(const struct epan_session *epan,
167 const frame_data *fdata1, const frame_data *fdata2)
168{
169 nstime_t del_rel_ts1, del_rel_ts2;
170 bool_Bool have_del_rel_ts1, have_del_rel_ts2;
171
172 have_del_rel_ts1 = frame_rel_time(epan, fdata1, &del_rel_ts1);
173 have_del_rel_ts2 = frame_rel_time(epan, fdata2, &del_rel_ts2);
174
175 return frame_compare_time_deltas(fdata1, have_del_rel_ts1, &del_rel_ts1,
176 fdata2, have_del_rel_ts2, &del_rel_ts2);
177}
178
179bool_Bool
180frame_delta_time_prev_captured(const struct epan_session *epan,
181 const frame_data *fdata, nstime_t *delta)
182{
183 return frame_delta_abs_time(epan, fdata, fdata->num - 1, delta);
184}
185
186static int
187frame_compare_delta_times_prev_captured(const struct epan_session *epan,
188 const frame_data *fdata1,
189 const frame_data *fdata2)
190{
191 nstime_t del_cap_ts1, del_cap_ts2;
192 bool_Bool have_del_cap_ts1, have_del_cap_ts2;
193
194 have_del_cap_ts1 = frame_delta_time_prev_captured(epan, fdata1, &del_cap_ts1);
195 have_del_cap_ts2 = frame_delta_time_prev_captured(epan, fdata2, &del_cap_ts2);
196
197 return frame_compare_time_deltas(fdata1, have_del_cap_ts1, &del_cap_ts1,
198 fdata2, have_del_cap_ts2, &del_cap_ts2);
199}
200
201bool_Bool
202frame_delta_time_prev_displayed(const struct epan_session *epan,
203 const frame_data *fdata, nstime_t *delta)
204{
205 return frame_delta_abs_time(epan, fdata, fdata->prev_dis_num, delta);
206}
207
208static int
209frame_compare_delta_times_prev_displayed(const struct epan_session *epan, const frame_data *fdata1, const frame_data *fdata2)
210{
211 nstime_t del_dis_ts1, del_dis_ts2;
212 bool_Bool have_del_dis_ts1, have_del_dis_ts2;
213
214 have_del_dis_ts1 = frame_delta_time_prev_displayed(epan, fdata1, &del_dis_ts1);
215 have_del_dis_ts2 = frame_delta_time_prev_displayed(epan, fdata2, &del_dis_ts2);
216
217 return frame_compare_time_deltas(fdata1, have_del_dis_ts1, &del_dis_ts1,
218 fdata2, have_del_dis_ts2, &del_dis_ts2);
219}
220
221static int
222frame_data_aggregation_values_compare(GSList* list1, GSList* list2) {
223 GHashTable* set = g_hash_table_new(g_str_hash, g_str_equal);
224 for (GSList* node = list1; node; node = node->next)
225 g_hash_table_add(set, node->data);
226
227 for (GSList* node = list2; node; node = node->next) {
228 if (g_hash_table_contains(set, node->data)) {
229 g_hash_table_destroy(set);
230 return 0;
231 }
232 }
233 g_hash_table_destroy(set);
234 return 1;
235}
236
237void
238free_aggregation_key(gpointer data) {
239 aggregation_key* key = (aggregation_key*)data;
240 if (!key) return;
241
242 if (key->field) {
243 g_free(key->field);
244 key->field = NULL((void*)0);
245 }
246
247 if (key->values) {
248 g_slist_free_full(key->values, g_free);
249 key->values = NULL((void*)0);
250 }
251
252 g_free(key);
253}
254
255int
256frame_data_compare(const struct epan_session *epan, const frame_data *fdata1, const frame_data *fdata2, int field)
257{
258 switch (field) {
259 case COL_NUMBER:
260 return COMPARE_FRAME_NUM()((fdata1->num < fdata2->num) ? -1 : (fdata1->num >
fdata2->num) ? 1 : 0)
;
261
262 case COL_NUMBER_DIS:
263 return COMPARE_NUM(dis_num)((fdata1->dis_num < fdata2->dis_num) ? -1 : (fdata1->
dis_num > fdata2->dis_num) ? 1 : ((fdata1->num < fdata2
->num) ? -1 : (fdata1->num > fdata2->num) ? 1 : 0
))
;
264
265 case COL_CLS_TIME:
266 switch (timestamp_get_type()) {
267 case TS_ABSOLUTE:
268 case TS_ABSOLUTE_WITH_YMD:
269 case TS_ABSOLUTE_WITH_YDOY:
270 case TS_UTC:
271 case TS_UTC_WITH_YMD:
272 case TS_UTC_WITH_YDOY:
273 case TS_EPOCH:
274 return COMPARE_TS(abs_ts)((fdata1->ref_time && !fdata2->ref_time) ? -1 :
(!fdata1->ref_time && fdata2->ref_time) ? 1 : (
(fdata1->abs_ts).secs < (fdata2->abs_ts).secs) ? -1 :
((fdata1->abs_ts).secs > (fdata2->abs_ts).secs) ? 1
: ((fdata1->abs_ts).nsecs < (fdata2->abs_ts).nsecs)
? -1 : ((fdata1->abs_ts).nsecs > (fdata2->abs_ts).nsecs
) ? 1 : ((fdata1->num < fdata2->num) ? -1 : (fdata1->
num > fdata2->num) ? 1 : 0))
;
275
276 case TS_RELATIVE:
277 return frame_compare_rel_times(epan, fdata1, fdata2);
278
279 case TS_DELTA:
280 return frame_compare_delta_times_prev_captured(epan, fdata1, fdata2);
281
282 case TS_DELTA_DIS:
283 return frame_compare_delta_times_prev_displayed(epan, fdata1, fdata2);
284
285 case TS_NOT_SET:
286 return 0;
287 }
288 return 0;
289
290 case COL_ABS_TIME:
291 case COL_ABS_YMD_TIME:
292 case COL_ABS_YDOY_TIME:
293 case COL_UTC_TIME:
294 case COL_UTC_YMD_TIME:
295 case COL_UTC_YDOY_TIME:
296 return COMPARE_TS(abs_ts)((fdata1->ref_time && !fdata2->ref_time) ? -1 :
(!fdata1->ref_time && fdata2->ref_time) ? 1 : (
(fdata1->abs_ts).secs < (fdata2->abs_ts).secs) ? -1 :
((fdata1->abs_ts).secs > (fdata2->abs_ts).secs) ? 1
: ((fdata1->abs_ts).nsecs < (fdata2->abs_ts).nsecs)
? -1 : ((fdata1->abs_ts).nsecs > (fdata2->abs_ts).nsecs
) ? 1 : ((fdata1->num < fdata2->num) ? -1 : (fdata1->
num > fdata2->num) ? 1 : 0))
;
297
298 case COL_REL_TIME:
299 return frame_compare_rel_times(epan, fdata1, fdata2);
300
301 case COL_DELTA_TIME:
302 return frame_compare_delta_times_prev_captured(epan, fdata1, fdata2);
303
304 case COL_DELTA_TIME_DIS:
305 return frame_compare_delta_times_prev_displayed(epan, fdata1, fdata2);
306
307 case COL_PACKET_LENGTH:
308 return COMPARE_NUM(pkt_len)((fdata1->pkt_len < fdata2->pkt_len) ? -1 : (fdata1->
pkt_len > fdata2->pkt_len) ? 1 : ((fdata1->num < fdata2
->num) ? -1 : (fdata1->num > fdata2->num) ? 1 : 0
))
;
309
310 case COL_CUMULATIVE_BYTES:
311 return COMPARE_NUM(cum_bytes)((fdata1->cum_bytes < fdata2->cum_bytes) ? -1 : (fdata1
->cum_bytes > fdata2->cum_bytes) ? 1 : ((fdata1->
num < fdata2->num) ? -1 : (fdata1->num > fdata2->
num) ? 1 : 0))
;
312
313 }
314 g_return_val_if_reached(0)do { g_log (((gchar*) 0), G_LOG_LEVEL_CRITICAL, "file %s: line %d (%s): should not be reached"
, "epan/frame_data.c", 314, ((const char*) (__func__))); return
(0); } while (0)
;
315}
316
317int
318frame_data_aggregation_compare(const frame_data* fdata1, const frame_data* fdata2)
319{
320 unsigned length = g_slist_length(fdata1->aggregation_keys);
321 if (length != g_slist_length(fdata2->aggregation_keys)) {
322 return 1;
323 }
324 unsigned i = 0;
325 while (i < length) {
326 const aggregation_key* key1 = (aggregation_key*)g_slist_nth_data(fdata1->aggregation_keys, i);
327 const aggregation_key* key2 = (aggregation_key*)g_slist_nth_data(fdata2->aggregation_keys, i);
328 if (g_strcmp0(key1->field, key2->field) != 0 ||
329 frame_data_aggregation_values_compare(key1->values, key2->values) == 1) {
330 return 1;
331 }
332 i++;
333 }
334 return 0;
335}
336
337void
338frame_data_init(frame_data *fdata, uint32_t num, const wtap_rec *rec,
339 int64_t offset, uint32_t cum_bytes)
340{
341 fdata->pfd = NULL((void*)0);
342 fdata->num = num;
343 fdata->dis_num = num;
344 fdata->file_off = offset;
345 fdata->passed_dfilter = 1;
346 fdata->dependent_of_displayed = 0;
347 fdata->dependent_frames = NULL((void*)0);
348 fdata->encoding = PACKET_CHAR_ENC_CHAR_ASCII;
349 fdata->visited = 0;
350 fdata->marked = 0;
351 fdata->ref_time = 0;
352 fdata->ignored = 0;
353 fdata->has_ts = (rec->presence_flags & WTAP_HAS_TS0x00000001) ? 1 : 0;
354 fdata->tcp_snd_manual_analysis = 0;
355 switch (rec->rec_type) {
356
357 case REC_TYPE_PACKET0:
358 fdata->pkt_len = rec->rec_header.packet_header.len;
359 fdata->cum_bytes = cum_bytes + rec->rec_header.packet_header.len;
360 fdata->cap_len = rec->rec_header.packet_header.caplen;
361 break;
362
363 case REC_TYPE_FT_SPECIFIC_EVENT1:
364 case REC_TYPE_FT_SPECIFIC_REPORT2:
365 /*
366 * XXX
367 */
368 fdata->pkt_len = rec->rec_header.ft_specific_header.record_len;
369 fdata->cum_bytes = cum_bytes + rec->rec_header.ft_specific_header.record_len;
370 fdata->cap_len = rec->rec_header.ft_specific_header.record_len;
371 break;
372
373 case REC_TYPE_SYSCALL3:
374 /*
375 * XXX - is cum_bytes supposed to count non-packet bytes?
376 */
377 fdata->pkt_len = rec->rec_header.syscall_header.event_data_len;
378 fdata->cum_bytes = cum_bytes + rec->rec_header.syscall_header.event_data_len;
379 fdata->cap_len = rec->rec_header.syscall_header.event_data_len;
380 break;
381
382 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT4:
383 /*
384 * XXX - is cum_bytes supposed to count non-packet bytes?
385 */
386 fdata->pkt_len = rec->rec_header.systemd_journal_export_header.record_len;
387 fdata->cum_bytes = cum_bytes + rec->rec_header.systemd_journal_export_header.record_len;
388 fdata->cap_len = rec->rec_header.systemd_journal_export_header.record_len;
389 break;
390
391 case REC_TYPE_CUSTOM_BLOCK5:
392 /*
393 * XXX - is cum_bytes supposed to count non-packet bytes?
394 */
395 fdata->pkt_len = rec->rec_header.custom_block_header.length;
396 fdata->cum_bytes = cum_bytes + rec->rec_header.custom_block_header.length;
397 fdata->cap_len = rec->rec_header.custom_block_header.length;
398 break;
399
400 }
401
402 /* To save some memory, we coerce it into 4 bits */
403 ws_assert(rec->tsprec <= 0xF)do { if ((1) && !(rec->tsprec <= 0xF)) ws_log_fatal_full
("", LOG_LEVEL_ERROR, "epan/frame_data.c", 403, __func__, "assertion failed: %s"
, "rec->tsprec <= 0xF"); } while (0)
;
404 fdata->tsprec = (unsigned int)rec->tsprec;
405 fdata->abs_ts = rec->ts;
406 fdata->has_modified_block = 0;
407 fdata->need_colorize = 0;
408 fdata->color_filter = NULL((void*)0);
409 fdata->shift_offset.secs = 0;
410 fdata->shift_offset.nsecs = 0;
411 fdata->frame_ref_num = 0;
412 fdata->prev_dis_num = 0;
413 fdata->aggregation_keys = NULL((void*)0);
414}
415
416void
417frame_data_set_before_dissect(frame_data *fdata,
418 nstime_t *elapsed_time,
419 const frame_data **frame_ref,
420 const frame_data *prev_dis)
421{
422 nstime_t rel_ts;
423
424 /* If this frame doesn't have a time stamp, don't set it as the
425 * reference frame used for calculating time deltas, set elapsed
426 * time, etc. We also won't need to calculate the delta of this
427 * frame's timestamp to any other frame.
428 */
429 if (!fdata->has_ts) {
430 /* If it was marked as a reference time frame anyway (should we
431 * allow that?), clear the existing reference frame so that the
432 * next frame with a time stamp will become the reference frame.
433 */
434 if(fdata->ref_time) {
435 *frame_ref = NULL((void*)0);
436 }
437 return;
438 }
439
440 /* Don't have the reference frame, set to current */
441 if (*frame_ref == NULL((void*)0))
442 *frame_ref = fdata;
443
444 /* if this frames is marked as a reference time frame,
445 set reference frame this frame */
446 if(fdata->ref_time)
447 *frame_ref = fdata;
448
449 /* Get the time elapsed between the first packet and this packet. */
450 nstime_delta(&rel_ts, &fdata->abs_ts, &(*frame_ref)->abs_ts);
451
452 /* If it's greater than the current elapsed time, set the elapsed time
453 to it (we check for "greater than" so as not to be confused by
454 time moving backwards). */
455 if (nstime_cmp(elapsed_time, &rel_ts) < 0) {
456 *elapsed_time = rel_ts;
457 }
458
459 fdata->frame_ref_num = (*frame_ref)->num;
460 fdata->prev_dis_num = (prev_dis) ? prev_dis->num : 0;
461}
462
463void
464frame_data_set_after_dissect(frame_data *fdata,
465 uint32_t *cum_bytes)
466{
467 /* This frame either passed the display filter list or is marked as
468 a time reference frame. All time reference frames are displayed
469 even if they don't pass the display filter */
470 if(fdata->ref_time){
471 /* if this was a TIME REF frame we should reset the cul bytes field */
472 *cum_bytes = fdata->pkt_len;
473 fdata->cum_bytes = *cum_bytes;
474 } else {
475 /* increase cum_bytes with this packets length */
476 *cum_bytes += fdata->pkt_len;
477 fdata->cum_bytes = *cum_bytes;
478 }
479}
480
481void
482frame_data_reset(frame_data *fdata)
483{
484 fdata->visited = 0;
485
486 frame_data_destroy(fdata);
487}
488
489void
490frame_data_destroy(frame_data *fdata)
491{
492 if (fdata->pfd) {
493 g_slist_free(fdata->pfd);
494 fdata->pfd = NULL((void*)0);
495 }
496
497 if (fdata->dependent_frames) {
498 g_hash_table_destroy(fdata->dependent_frames);
499 fdata->dependent_frames = NULL((void*)0);
500 }
501
502 frame_data_aggregation_free(fdata);
503}
504
505void frame_data_aggregation_free(frame_data* fdata)
506{
507 if (fdata->aggregation_keys) {
508 g_slist_free_full(fdata->aggregation_keys, free_aggregation_key);
509 fdata->aggregation_keys = NULL((void*)0);
510 }
511}
512
513/*
514 * Editor modelines - https://www.wireshark.org/tools/modelines.html
515 *
516 * Local variables:
517 * c-basic-offset: 2
518 * tab-width: 8
519 * indent-tabs-mode: nil
520 * End:
521 *
522 * vi: set shiftwidth=2 tabstop=8 expandtab:
523 * :indentSize=2:tabSize=8:noTabs=true:
524 */