1 /* frame_data_sequence.c
2 * Implements a sequence of frame_data structures
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
17 #include "frame_data_sequence.h"
20 * We store the frame_data structures in a radix tree, with 1024
21 * elements per level. The leaf nodes are arrays of 1024 frame_data
22 * structures; the nodes above them are arrays of 1024 pointers to
23 * the nodes below them. The capture_file structure has a pointer
26 * As frame numbers are 32 bits, and as 1024 is 2^10, that gives us
27 * up to 4 levels of tree.
29 #define LOG2_NODES_PER_LEVEL 10
30 #define NODES_PER_LEVEL (1<<LOG2_NODES_PER_LEVEL)
32 struct _frame_data_sequence
{
33 uint32_t count
; /* Total number of frames */
34 void *ptree_root
; /* Pointer to the root node */
38 * For a given frame number, calculate the indices into a level 3
39 * node, a level 2 node, a level 1 node, and a leaf node.
41 #define LEVEL_3_INDEX(framenum) \
42 ((framenum) >> (3*LOG2_NODES_PER_LEVEL))
43 #define LEVEL_2_INDEX(framenum) \
44 (((framenum) >> (2*LOG2_NODES_PER_LEVEL)) & (NODES_PER_LEVEL - 1))
45 #define LEVEL_1_INDEX(framenum) \
46 (((framenum) >> (1*LOG2_NODES_PER_LEVEL)) & (NODES_PER_LEVEL - 1))
47 #define LEAF_INDEX(framenum) \
48 (((framenum) >> (0*LOG2_NODES_PER_LEVEL)) & (NODES_PER_LEVEL - 1))
51 new_frame_data_sequence(void)
53 frame_data_sequence
*fds
;
55 fds
= (frame_data_sequence
*)g_malloc(sizeof *fds
);
57 fds
->ptree_root
= NULL
;
62 * Add a new frame_data structure to a frame_data_sequence.
65 frame_data_sequence_add(frame_data_sequence
*fds
, frame_data
*fdata
)
70 frame_data
****level3
;
74 * The current value of fds->count is the index value for the new frame,
75 * because the index value for a frame is the frame number - 1, and
76 * if we currently have fds->count frames, the the frame number of
77 * the last frame in the collection is fds->count, so its index value
80 if (fds
->count
== 0) {
81 /* The tree is empty; allocate the first leaf node, which will be
83 leaf
= (frame_data
*)g_malloc((sizeof *leaf
)*NODES_PER_LEVEL
);
85 fds
->ptree_root
= leaf
;
86 } else if (fds
->count
< NODES_PER_LEVEL
) {
87 /* It's a 1-level tree, and is going to stay that way for now. */
88 leaf
= (frame_data
*)fds
->ptree_root
;
89 node
= &leaf
[fds
->count
];
90 } else if (fds
->count
== NODES_PER_LEVEL
) {
91 /* It's a 1-level tree that will turn into a 2-level tree. */
92 level1
= (frame_data
**)g_malloc0((sizeof *level1
)*NODES_PER_LEVEL
);
93 level1
[0] = (frame_data
*)fds
->ptree_root
;
94 leaf
= (frame_data
*)g_malloc((sizeof *leaf
)*NODES_PER_LEVEL
);
97 fds
->ptree_root
= level1
;
98 } else if (fds
->count
< NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
99 /* It's a 2-level tree, and is going to stay that way for now. */
100 level1
= (frame_data
**)fds
->ptree_root
;
101 leaf
= level1
[fds
->count
>> LOG2_NODES_PER_LEVEL
];
103 leaf
= (frame_data
*)g_malloc((sizeof *leaf
)*NODES_PER_LEVEL
);
104 level1
[fds
->count
>> LOG2_NODES_PER_LEVEL
] = leaf
;
106 node
= &leaf
[LEAF_INDEX(fds
->count
)];
107 } else if (fds
->count
== NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
108 /* It's a 2-level tree that will turn into a 3-level tree */
109 level2
= (frame_data
***)g_malloc0((sizeof *level2
)*NODES_PER_LEVEL
);
110 level2
[0] = (frame_data
**)fds
->ptree_root
;
111 level1
= (frame_data
**)g_malloc0((sizeof *level1
)*NODES_PER_LEVEL
);
113 leaf
= (frame_data
*)g_malloc((sizeof *leaf
)*NODES_PER_LEVEL
);
116 fds
->ptree_root
= level2
;
117 } else if (fds
->count
< NODES_PER_LEVEL
*NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
118 /* It's a 3-level tree, and is going to stay that way for now. */
119 level2
= (frame_data
***)fds
->ptree_root
;
120 level1
= level2
[fds
->count
>> (LOG2_NODES_PER_LEVEL
+LOG2_NODES_PER_LEVEL
)];
121 if (level1
== NULL
) {
122 level1
= (frame_data
**)g_malloc0((sizeof *level1
)*NODES_PER_LEVEL
);
123 level2
[fds
->count
>> (LOG2_NODES_PER_LEVEL
+LOG2_NODES_PER_LEVEL
)] = level1
;
125 leaf
= level1
[LEVEL_1_INDEX(fds
->count
)];
127 leaf
= (frame_data
*)g_malloc((sizeof *leaf
)*NODES_PER_LEVEL
);
128 level1
[LEVEL_1_INDEX(fds
->count
)] = leaf
;
130 node
= &leaf
[LEAF_INDEX(fds
->count
)];
131 } else if (fds
->count
== NODES_PER_LEVEL
*NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
132 /* It's a 3-level tree that will turn into a 4-level tree */
133 level3
= (frame_data
****)g_malloc0((sizeof *level3
)*NODES_PER_LEVEL
);
134 level3
[0] = (frame_data
***)fds
->ptree_root
;
135 level2
= (frame_data
***)g_malloc0((sizeof *level2
)*NODES_PER_LEVEL
);
137 level1
= (frame_data
**)g_malloc0((sizeof *level1
)*NODES_PER_LEVEL
);
139 leaf
= (frame_data
*)g_malloc((sizeof *leaf
)*NODES_PER_LEVEL
);
142 fds
->ptree_root
= level3
;
144 /* fds->count is 2^32-1 at most, and NODES_PER_LEVEL^4
145 2^(LOG2_NODES_PER_LEVEL*4), and LOG2_NODES_PER_LEVEL is 10,
146 so fds->count is always less < NODES_PER_LEVEL^4.
148 XXX - we should fail if fds->count is 2^31-1, or should
149 make the frame numbers 64-bit and just let users run
150 themselves out of address space or swap space. :-) */
151 /* It's a 4-level tree, and is going to stay that way forever. */
152 level3
= (frame_data
****)fds
->ptree_root
;
153 level2
= level3
[LEVEL_3_INDEX(fds
->count
)];
154 if (level2
== NULL
) {
155 level2
= (frame_data
***)g_malloc0((sizeof *level2
)*NODES_PER_LEVEL
);
156 level3
[LEVEL_3_INDEX(fds
->count
)] = level2
;
158 level1
= level2
[LEVEL_2_INDEX(fds
->count
)];
159 if (level1
== NULL
) {
160 level1
= (frame_data
**)g_malloc0((sizeof *level1
)*NODES_PER_LEVEL
);
161 level2
[LEVEL_2_INDEX(fds
->count
)] = level1
;
163 leaf
= level1
[LEVEL_1_INDEX(fds
->count
)];
165 leaf
= (frame_data
*)g_malloc((sizeof *leaf
)*NODES_PER_LEVEL
);
166 level1
[LEVEL_1_INDEX(fds
->count
)] = leaf
;
168 node
= &leaf
[LEAF_INDEX(fds
->count
)];
176 * Find the frame_data for the specified frame number.
179 frame_data_sequence_find(frame_data_sequence
*fds
, uint32_t num
)
183 frame_data
***level2
;
184 frame_data
****level3
;
186 if (num
== 0 || fds
== NULL
) {
187 /* There is no frame number 0 */
191 /* Convert it into an index number. */
193 if (num
>= fds
->count
) {
194 /* There aren't that many frames. */
198 if (fds
->count
<= NODES_PER_LEVEL
) {
199 /* It's a 1-level tree. */
200 leaf
= (frame_data
*)fds
->ptree_root
;
203 if (fds
->count
<= NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
204 /* It's a 2-level tree. */
205 level1
= (frame_data
**)fds
->ptree_root
;
206 leaf
= level1
[num
>> LOG2_NODES_PER_LEVEL
];
207 return &leaf
[LEAF_INDEX(num
)];
209 if (fds
->count
<= NODES_PER_LEVEL
*NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
210 /* It's a 3-level tree. */
211 level2
= (frame_data
***)fds
->ptree_root
;
212 level1
= level2
[num
>> (LOG2_NODES_PER_LEVEL
+LOG2_NODES_PER_LEVEL
)];
213 leaf
= level1
[(num
>> LOG2_NODES_PER_LEVEL
) & (NODES_PER_LEVEL
- 1)];
214 return &leaf
[LEAF_INDEX(num
)];
216 /* fds->count is 2^32-1 at most, and NODES_PER_LEVEL^4
217 2^(LOG2_NODES_PER_LEVEL*4), and LOG2_NODES_PER_LEVEL is 10,
218 so fds->count is always less < NODES_PER_LEVEL^4. */
219 /* It's a 4-level tree, and is going to stay that way forever. */
220 level3
= (frame_data
****)fds
->ptree_root
;
221 level2
= level3
[num
>> (LOG2_NODES_PER_LEVEL
+LOG2_NODES_PER_LEVEL
+LOG2_NODES_PER_LEVEL
)];
222 level1
= level2
[(num
>> (LOG2_NODES_PER_LEVEL
+LOG2_NODES_PER_LEVEL
)) & (NODES_PER_LEVEL
- 1)];
223 leaf
= level1
[(num
>> LOG2_NODES_PER_LEVEL
) & (NODES_PER_LEVEL
- 1)];
224 return &leaf
[LEAF_INDEX(num
)];
227 /* recursively frees a frame_data radix level */
229 // NOLINTNEXTLINE(misc-no-recursion)
230 free_frame_data_array(void *array
, unsigned count
, unsigned level
, bool last
)
232 unsigned i
, level_count
;
235 /* if we are the last in our given parent's row, we may not have
236 * exactly a full row, so do the bit twiddling to figure out exactly
237 * how many fields we have */
238 level_count
= (count
>> ((level
- 1) * LOG2_NODES_PER_LEVEL
)) &
239 (NODES_PER_LEVEL
- 1);
240 /* the above calculation rounds down, so make sure we count correctly
241 * if count is not an even multiple of NODES_PER_LEVEL */
242 if (count
& ((1 << ((level
- 1) * LOG2_NODES_PER_LEVEL
)) - 1)) {
247 /* if we're not the last in our parent, then we're guaranteed to have
249 level_count
= NODES_PER_LEVEL
;
254 /* recurse on every sub-array, passing on our own 'last' value
255 * specially to our last child */
256 frame_data
**real_array
= (frame_data
**) array
;
258 for (i
=0; i
< level_count
-1; i
++) {
259 // We recurse here, but we're limited to four levels.
260 free_frame_data_array(real_array
[i
], count
, level
-1, false);
263 // We recurse here, but we're limited to four levels.
264 free_frame_data_array(real_array
[level_count
-1], count
, level
-1, last
);
266 else if (level
== 1) {
267 /* bottom level, so just clean up all the frame data */
268 frame_data
*real_array
= (frame_data
*) array
;
270 for (i
=0; i
< level_count
; i
++) {
271 frame_data_destroy(&real_array
[i
]);
275 /* free the array itself */
280 * Free a frame_data_sequence and all the frame_data structures in it.
283 free_frame_data_sequence(frame_data_sequence
*fds
)
287 /* calculate how many levels we have */
288 if (fds
->count
== 0) {
289 /* The tree is empty; there are no levels. */
291 } else if (fds
->count
<= NODES_PER_LEVEL
) {
292 /* It's a 1-level tree. */
294 } else if (fds
->count
<= NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
295 /* It's a 2-level tree. */
297 } else if (fds
->count
<= NODES_PER_LEVEL
*NODES_PER_LEVEL
*NODES_PER_LEVEL
) {
298 /* It's a 3-level tree. */
301 /* fds->count is 2^32-1 at most, and NODES_PER_LEVEL^4
302 2^(LOG2_NODES_PER_LEVEL*4), and LOG2_NODES_PER_LEVEL is 10,
303 so fds->count is always less < NODES_PER_LEVEL^4. */
304 /* It's a 4-level tree. */
308 /* call the recursive free function */
310 free_frame_data_array(fds
->ptree_root
, fds
->count
, levels
, true);
313 /* free the header struct */
318 find_and_mark_frame_depended_upon(void *key
, void *value _U_
, void *user_data
)
320 frame_data
*dependent_fd
;
321 uint32_t dependent_frame
= GPOINTER_TO_UINT(key
);
322 frame_data_sequence
*frames
= (frame_data_sequence
*)user_data
;
324 if (dependent_frame
&& frames
) {
325 dependent_fd
= frame_data_sequence_find(frames
, dependent_frame
);
326 /* Don't recurse for packets we've already marked. Note we assume that no
327 * packet depends on a future packet; we assume that in other places too.
329 if (!(dependent_fd
->dependent_of_displayed
|| dependent_fd
->passed_dfilter
)) {
330 dependent_fd
->dependent_of_displayed
= 1;
331 if (dependent_fd
->dependent_frames
) {
332 g_hash_table_foreach(dependent_fd
->dependent_frames
, find_and_mark_frame_depended_upon
, frames
);
339 * Editor modelines - https://www.wireshark.org/tools/modelines.html
344 * indent-tabs-mode: nil
347 * vi: set shiftwidth=2 tabstop=8 expandtab:
348 * :indentSize=2:tabSize=8:noTabs=true: