Bug Summary

File:builds/wireshark/wireshark/epan/reassemble.c
Warning:line 1506, column 6
Potential leak of memory pointed to by 'data'

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 reassemble.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-18/lib/clang/18 -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/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-18/lib/clang/18/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 -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 -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -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 -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/libxml2 -isystem /usr/include/lua5.4 -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/epan/reassemble.c -o /builds/wireshark/wireshark/sbout/2024-11-20-100252-3912-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-11-20-100252-3912-1 -x c /builds/wireshark/wireshark/epan/reassemble.c
1/* reassemble.c
2 * Routines for {fragment,segment} reassembly
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12
13#include <string.h>
14
15#include <epan/packet.h>
16#include <epan/exceptions.h>
17#include <epan/reassemble.h>
18#include <epan/tvbuff-int.h>
19
20#include <wsutil/str_util.h>
21#include <wsutil/ws_assert.h>
22
23/*
24 * Functions for reassembly tables where the endpoint addresses, and a
25 * fragment ID, are used as the key.
26 */
27typedef struct _fragment_addresses_key {
28 address src;
29 address dst;
30 uint32_t id;
31} fragment_addresses_key;
32
33GList* reassembly_table_list;
34
35static unsigned
36fragment_addresses_hash(const void *k)
37{
38 const fragment_addresses_key* key = (const fragment_addresses_key*) k;
39 unsigned hash_val;
40/*
41 int i;
42*/
43
44 hash_val = 0;
45
46/* More than likely: in most captures src and dst addresses are the
47 same, and would hash the same.
48 We only use id as the hash as an optimization.
49
50 for (i = 0; i < key->src.len; i++)
51 hash_val += key->src.data[i];
52 for (i = 0; i < key->dst.len; i++)
53 hash_val += key->dst.data[i];
54*/
55
56 hash_val += key->id;
57
58 return hash_val;
59}
60
61static int
62fragment_addresses_equal(const void *k1, const void *k2)
63{
64 const fragment_addresses_key* key1 = (const fragment_addresses_key*) k1;
65 const fragment_addresses_key* key2 = (const fragment_addresses_key*) k2;
66
67 /*
68 * key.id is the first item to compare since it's the item most
69 * likely to differ between sessions, thus short-circuiting
70 * the comparison of addresses.
71 */
72 return (key1->id == key2->id) &&
73 (addresses_equal(&key1->src, &key2->src)) &&
74 (addresses_equal(&key1->dst, &key2->dst));
75}
76
77/*
78 * Create a fragment key for temporary use; it can point to non-
79 * persistent data, and so must only be used to look up and
80 * delete entries, not to add them.
81 */
82static void *
83fragment_addresses_temporary_key(const packet_info *pinfo, const uint32_t id,
84 const void *data _U___attribute__((unused)))
85{
86 fragment_addresses_key *key = g_slice_new(fragment_addresses_key)((fragment_addresses_key*) g_slice_alloc (sizeof (fragment_addresses_key
)))
;
87
88 /*
89 * Do a shallow copy of the addresses.
90 */
91 copy_address_shallow(&key->src, &pinfo->src);
92 copy_address_shallow(&key->dst, &pinfo->dst);
93 key->id = id;
94
95 return (void *)key;
96}
97
98/*
99 * Create a fragment key for permanent use; it must point to persistent
100 * data, so that it can be used to add entries.
101 */
102static void *
103fragment_addresses_persistent_key(const packet_info *pinfo, const uint32_t id,
104 const void *data _U___attribute__((unused)))
105{
106 fragment_addresses_key *key = g_slice_new(fragment_addresses_key)((fragment_addresses_key*) g_slice_alloc (sizeof (fragment_addresses_key
)))
;
107
108 /*
109 * Do a deep copy of the addresses.
110 */
111 copy_address(&key->src, &pinfo->src);
112 copy_address(&key->dst, &pinfo->dst);
113 key->id = id;
114
115 return (void *)key;
116}
117
118static void
119fragment_addresses_free_temporary_key(void *ptr)
120{
121 fragment_addresses_key *key = (fragment_addresses_key *)ptr;
122 g_slice_free(fragment_addresses_key, key)do { if (1) g_slice_free1 (sizeof (fragment_addresses_key), (
key)); else (void) ((fragment_addresses_key*) 0 == (key)); } while
(0)
;
123}
124
125static void
126fragment_addresses_free_persistent_key(void *ptr)
127{
128 fragment_addresses_key *key = (fragment_addresses_key *)ptr;
129
130 if(key){
131 /*
132 * Free up the copies of the addresses from the old key.
133 */
134 free_address(&key->src);
135 free_address(&key->dst);
136
137 g_slice_free(fragment_addresses_key, key)do { if (1) g_slice_free1 (sizeof (fragment_addresses_key), (
key)); else (void) ((fragment_addresses_key*) 0 == (key)); } while
(0)
;
138 }
139}
140
141const reassembly_table_functions
142addresses_reassembly_table_functions = {
143 fragment_addresses_hash,
144 fragment_addresses_equal,
145 fragment_addresses_temporary_key,
146 fragment_addresses_persistent_key,
147 fragment_addresses_free_temporary_key,
148 fragment_addresses_free_persistent_key
149};
150
151/*
152 * Functions for reassembly tables where the endpoint addresses and ports,
153 * and a fragment ID, are used as the key.
154 */
155typedef struct _fragment_addresses_ports_key {
156 address src_addr;
157 address dst_addr;
158 uint32_t src_port;
159 uint32_t dst_port;
160 uint32_t id;
161} fragment_addresses_ports_key;
162
163static unsigned
164fragment_addresses_ports_hash(const void *k)
165{
166 const fragment_addresses_ports_key* key = (const fragment_addresses_ports_key*) k;
167 unsigned hash_val;
168/*
169 int i;
170*/
171
172 hash_val = 0;
173
174/* More than likely: in most captures src and dst addresses and ports
175 are the same, and would hash the same.
176 We only use id as the hash as an optimization.
177
178 for (i = 0; i < key->src.len; i++)
179 hash_val += key->src_addr.data[i];
180 for (i = 0; i < key->dst.len; i++)
181 hash_val += key->dst_addr.data[i];
182 hash_val += key->src_port;
183 hash_val += key->dst_port;
184*/
185
186 hash_val += key->id;
187
188 return hash_val;
189}
190
191static int
192fragment_addresses_ports_equal(const void *k1, const void *k2)
193{
194 const fragment_addresses_ports_key* key1 = (const fragment_addresses_ports_key*) k1;
195 const fragment_addresses_ports_key* key2 = (const fragment_addresses_ports_key*) k2;
196
197 /*
198 * key.id is the first item to compare since it's the item most
199 * likely to differ between sessions, thus short-circuiting
200 * the comparison of addresses and ports.
201 */
202 return (key1->id == key2->id) &&
203 (addresses_equal(&key1->src_addr, &key2->src_addr)) &&
204 (addresses_equal(&key1->dst_addr, &key2->dst_addr)) &&
205 (key1->src_port == key2->src_port) &&
206 (key1->dst_port == key2->dst_port);
207}
208
209/*
210 * Create a fragment key for temporary use; it can point to non-
211 * persistent data, and so must only be used to look up and
212 * delete entries, not to add them.
213 */
214static void *
215fragment_addresses_ports_temporary_key(const packet_info *pinfo, const uint32_t id,
216 const void *data _U___attribute__((unused)))
217{
218 fragment_addresses_ports_key *key = g_slice_new(fragment_addresses_ports_key)((fragment_addresses_ports_key*) g_slice_alloc (sizeof (fragment_addresses_ports_key
)))
;
219
220 /*
221 * Do a shallow copy of the addresses.
222 */
223 copy_address_shallow(&key->src_addr, &pinfo->src);
224 copy_address_shallow(&key->dst_addr, &pinfo->dst);
225 key->src_port = pinfo->srcport;
226 key->dst_port = pinfo->destport;
227 key->id = id;
228
229 return (void *)key;
230}
231
232/*
233 * Create a fragment key for permanent use; it must point to persistent
234 * data, so that it can be used to add entries.
235 */
236static void *
237fragment_addresses_ports_persistent_key(const packet_info *pinfo,
238 const uint32_t id, const void *data _U___attribute__((unused)))
239{
240 fragment_addresses_ports_key *key = g_slice_new(fragment_addresses_ports_key)((fragment_addresses_ports_key*) g_slice_alloc (sizeof (fragment_addresses_ports_key
)))
;
241
242 /*
243 * Do a deep copy of the addresses.
244 */
245 copy_address(&key->src_addr, &pinfo->src);
246 copy_address(&key->dst_addr, &pinfo->dst);
247 key->src_port = pinfo->srcport;
248 key->dst_port = pinfo->destport;
249 key->id = id;
250
251 return (void *)key;
252}
253
254static void
255fragment_addresses_ports_free_temporary_key(void *ptr)
256{
257 fragment_addresses_ports_key *key = (fragment_addresses_ports_key *)ptr;
258 g_slice_free(fragment_addresses_ports_key, key)do { if (1) g_slice_free1 (sizeof (fragment_addresses_ports_key
), (key)); else (void) ((fragment_addresses_ports_key*) 0 == (
key)); } while (0)
;
259}
260
261static void
262fragment_addresses_ports_free_persistent_key(void *ptr)
263{
264 fragment_addresses_ports_key *key = (fragment_addresses_ports_key *)ptr;
265
266 if(key){
267 /*
268 * Free up the copies of the addresses from the old key.
269 */
270 free_address(&key->src_addr);
271 free_address(&key->dst_addr);
272
273 g_slice_free(fragment_addresses_ports_key, key)do { if (1) g_slice_free1 (sizeof (fragment_addresses_ports_key
), (key)); else (void) ((fragment_addresses_ports_key*) 0 == (
key)); } while (0)
;
274 }
275}
276
277const reassembly_table_functions
278addresses_ports_reassembly_table_functions = {
279 fragment_addresses_ports_hash,
280 fragment_addresses_ports_equal,
281 fragment_addresses_ports_temporary_key,
282 fragment_addresses_ports_persistent_key,
283 fragment_addresses_ports_free_temporary_key,
284 fragment_addresses_ports_free_persistent_key
285};
286
287typedef struct _reassembled_key {
288 uint32_t id;
289 uint32_t frame;
290} reassembled_key;
291
292static int
293reassembled_equal(const void *k1, const void *k2)
294{
295 const reassembled_key* key1 = (const reassembled_key*) k1;
296 const reassembled_key* key2 = (const reassembled_key*) k2;
297
298 /*
299 * We assume that the frame numbers are unlikely to be equal,
300 * so we check them first.
301 */
302 return key1->frame == key2->frame && key1->id == key2->id;
303}
304
305static unsigned
306reassembled_hash(const void *k)
307{
308 const reassembled_key* key = (const reassembled_key*) k;
309
310 return key->frame;
311}
312
313static void
314reassembled_key_free(void *ptr)
315{
316 g_slice_free(reassembled_key, (reassembled_key *)ptr)do { if (1) g_slice_free1 (sizeof (reassembled_key), ((reassembled_key
*)ptr)); else (void) ((reassembled_key*) 0 == ((reassembled_key
*)ptr)); } while (0)
;
317}
318
319/*
320 * For a fragment hash table entry, free the associated fragments.
321 * The entry value (fd_chain) is freed herein and the entry is freed
322 * when the key freeing routine is called (as a consequence of returning
323 * true from this function).
324 */
325static gboolean
326free_all_fragments(void *key_arg _U___attribute__((unused)), void *value, void *user_data _U___attribute__((unused)))
327{
328 fragment_head *fd_head;
329 fragment_item *fd_i = NULL((void*)0), *tmp_fd;
330
331 /* g_hash_table_new_full() was used to supply a function
332 * to free the key and anything to which it points
333 */
334 fd_head = (fragment_head *)value;
335 if (fd_head != NULL((void*)0)) {
336 fd_i = fd_head->next;
337 if(fd_head->tvb_data && !(fd_head->flags&FD_SUBSET_TVB0x0020))
338 tvb_free(fd_head->tvb_data);
339 g_slice_free(fragment_head, fd_head)do { if (1) g_slice_free1 (sizeof (fragment_head), (fd_head))
; else (void) ((fragment_head*) 0 == (fd_head)); } while (0)
;
340 }
341
342 for (; fd_i != NULL((void*)0); fd_i = tmp_fd) {
343 tmp_fd=fd_i->next;
344
345 if(fd_i->tvb_data && !(fd_i->flags&FD_SUBSET_TVB0x0020))
346 tvb_free(fd_i->tvb_data);
347 g_slice_free(fragment_item, fd_i)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd_i)); else
(void) ((fragment_item*) 0 == (fd_i)); } while (0)
;
348 }
349
350 return TRUE(!(0));
351}
352
353/* ------------------------- */
354static fragment_head *new_head(const uint32_t flags)
355{
356 fragment_head *fd_head;
357 /* If head/first structure in list only holds no other data than
358 * 'datalen' then we don't have to change the head of the list
359 * even if we want to keep it sorted
360 */
361 fd_head=g_slice_new0(fragment_head)((fragment_head*) g_slice_alloc0 (sizeof (fragment_head)));
362
363 fd_head->flags=flags;
364 return fd_head;
365}
366
367/*
368 * For a reassembled-packet hash table entry, free the fragment data
369 * to which the value refers. (The key is freed by reassembled_key_free.)
370 */
371static void
372free_fd_head(fragment_head *fd_head)
373{
374 fragment_item *fd_i, *tmp;
375
376 if (fd_head->flags & FD_SUBSET_TVB0x0020)
377 fd_head->tvb_data = NULL((void*)0);
378 if (fd_head->tvb_data)
379 tvb_free(fd_head->tvb_data);
380 for (fd_i = fd_head->next; fd_i; fd_i = tmp) {
381 tmp = fd_i->next;
382 if (fd_i->flags & FD_SUBSET_TVB0x0020)
383 fd_i->tvb_data = NULL((void*)0);
384 if (fd_i->tvb_data) {
385 tvb_free(fd_i->tvb_data);
386 }
387 g_slice_free(fragment_item, fd_i)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd_i)); else
(void) ((fragment_item*) 0 == (fd_i)); } while (0)
;
388 }
389 g_slice_free(fragment_head, fd_head)do { if (1) g_slice_free1 (sizeof (fragment_head), (fd_head))
; else (void) ((fragment_head*) 0 == (fd_head)); } while (0)
;
390}
391
392static void
393unref_fd_head(void *data)
394{
395 fragment_head *fd_head = (fragment_head *) data;
396 fd_head->ref_count--;
397
398 if (fd_head->ref_count == 0) {
399 free_fd_head(fd_head);
400 }
401}
402
403static void
404reassembled_table_insert(GHashTable *reassembled_table, reassembled_key *key, fragment_head *fd_head)
405{
406 fragment_head *old_fd_head;
407 fd_head->ref_count++;
408 if ((old_fd_head = g_hash_table_lookup(reassembled_table, key)) != NULL((void*)0)) {
409 if (old_fd_head->ref_count == 1) {
410 /* We're replacing the last entry in the reassembled
411 * table for an old reassembly. Does it have a tvb?
412 * We might still be using that tvb's memory for an
413 * address via set_address_tvb(). (See #19094.)
414 */
415 if (old_fd_head->tvb_data && fd_head->tvb_data) {
416 /* Free it when the new tvb is freed */
417 tvb_set_child_real_data_tvbuff(fd_head->tvb_data, old_fd_head->tvb_data);
418 }
419 /* XXX: Set the old data to NULL regardless. If we
420 * have old data but not new data, that is odd (we're
421 * replacing a reassembly with tvb data with something
422 * with no tvb data, possibly because a zero length or
423 * null tvb was passed into a defragment function,
424 * which is a dissector bug.)
425 * This leaks the tvb data if we couldn't add it to
426 * a new tvb's chain, but we might not be able to free
427 * it yet if set_address_tvb() was used.
428 */
429 old_fd_head->tvb_data = NULL((void*)0);
430 }
431 }
432 g_hash_table_insert(reassembled_table, key, fd_head);
433}
434
435typedef struct register_reassembly_table {
436 reassembly_table *table;
437 const reassembly_table_functions *funcs;
438} register_reassembly_table_t;
439
440/*
441 * Register a reassembly table.
442 */
443void
444reassembly_table_register(reassembly_table *table,
445 const reassembly_table_functions *funcs)
446{
447 register_reassembly_table_t* reg_table;
448
449 DISSECTOR_ASSERT(table)((void) ((table) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/reassemble.c", 449, "table"))))
;
450 DISSECTOR_ASSERT(funcs)((void) ((funcs) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/reassemble.c", 450, "funcs"))))
;
451
452 reg_table = g_new(register_reassembly_table_t,1)((register_reassembly_table_t *) g_malloc_n ((1), sizeof (register_reassembly_table_t
)))
;
453
454 reg_table->table = table;
455 reg_table->funcs = funcs;
456
457 reassembly_table_list = g_list_prepend(reassembly_table_list, reg_table);
458}
459
460/*
461 * Initialize a reassembly table, with specified functions.
462 */
463void
464reassembly_table_init(reassembly_table *table,
465 const reassembly_table_functions *funcs)
466{
467 if (table->temporary_key_func == NULL((void*)0))
468 table->temporary_key_func = funcs->temporary_key_func;
469 if (table->persistent_key_func == NULL((void*)0))
470 table->persistent_key_func = funcs->persistent_key_func;
471 if (table->free_temporary_key_func == NULL((void*)0))
472 table->free_temporary_key_func = funcs->free_temporary_key_func;
473 if (table->fragment_table != NULL((void*)0)) {
474 /*
475 * The fragment hash table exists.
476 *
477 * Remove all entries and free fragment data for each entry.
478 *
479 * The keys, and anything to which they point, are freed by
480 * calling the table's key freeing function. The values
481 * are freed in free_all_fragments().
482 */
483 g_hash_table_foreach_remove(table->fragment_table,
484 free_all_fragments, NULL((void*)0));
485 } else {
486 /* The fragment table does not exist. Create it */
487 table->fragment_table = g_hash_table_new_full(funcs->hash_func,
488 funcs->equal_func, funcs->free_persistent_key_func, NULL((void*)0));
489 }
490
491 if (table->reassembled_table != NULL((void*)0)) {
492 /*
493 * The reassembled-packet hash table exists.
494 *
495 * Remove all entries and free reassembled packet
496 * data and key for each entry.
497 */
498 g_hash_table_remove_all(table->reassembled_table);
499 } else {
500 /* The fragment table does not exist. Create it */
501 table->reassembled_table = g_hash_table_new_full(reassembled_hash,
502 reassembled_equal, reassembled_key_free, unref_fd_head);
503 }
504}
505
506/*
507 * Destroy a reassembly table.
508 */
509void
510reassembly_table_destroy(reassembly_table *table)
511{
512 /*
513 * Clear the function pointers.
514 */
515 table->temporary_key_func = NULL((void*)0);
516 table->persistent_key_func = NULL((void*)0);
517 table->free_temporary_key_func = NULL((void*)0);
518 if (table->fragment_table != NULL((void*)0)) {
519 /*
520 * The fragment hash table exists.
521 *
522 * Remove all entries and free fragment data for each entry.
523 *
524 * The keys, and anything to which they point, are freed by
525 * calling the table's key freeing function. The values
526 * are freed in free_all_fragments().
527 */
528 g_hash_table_foreach_remove(table->fragment_table,
529 free_all_fragments, NULL((void*)0));
530
531 /*
532 * Now destroy the hash table.
533 */
534 g_hash_table_destroy(table->fragment_table);
535 table->fragment_table = NULL((void*)0);
536 }
537 if (table->reassembled_table != NULL((void*)0)) {
538 /*
539 * The reassembled-packet hash table exists.
540 *
541 * Remove all entries and free reassembled packet
542 * data and key for each entry.
543 */
544
545 g_hash_table_remove_all(table->reassembled_table);
546
547 /*
548 * Now destroy the hash table.
549 */
550 g_hash_table_destroy(table->reassembled_table);
551 table->reassembled_table = NULL((void*)0);
552 }
553}
554
555/*
556 * Look up an fd_head in the fragment table, optionally returning the key
557 * for it.
558 */
559static fragment_head *
560lookup_fd_head(reassembly_table *table, const packet_info *pinfo,
561 const uint32_t id, const void *data, void * *orig_keyp)
562{
563 void *key;
564 void *value;
565
566 /* Create key to search hash with */
567 key = table->temporary_key_func(pinfo, id, data);
568
569 /*
570 * Look up the reassembly in the fragment table.
571 */
572 if (!g_hash_table_lookup_extended(table->fragment_table, key, orig_keyp,
573 &value))
574 value = NULL((void*)0);
575 /* Free the key */
576 table->free_temporary_key_func(key);
577
578 return (fragment_head *)value;
579}
580
581/*
582 * Insert an fd_head into the fragment table, and return the key used.
583 */
584static void *
585insert_fd_head(reassembly_table *table, fragment_head *fd_head,
586 const packet_info *pinfo, const uint32_t id, const void *data)
587{
588 void *key;
589
590 /*
591 * We're going to use the key to insert the fragment,
592 * so make a persistent version of it.
593 */
594 key = table->persistent_key_func(pinfo, id, data);
595 g_hash_table_insert(table->fragment_table, key, fd_head);
596 return key;
597}
598
599/* This function cleans up the stored state and removes the reassembly data and
600 * (with one exception) all allocated memory for matching reassembly.
601 *
602 * The exception is :
603 * If the PDU was already completely reassembled, then the tvbuff containing the
604 * reassembled data WILL NOT be free()d, and the pointer to that tvbuff will be
605 * returned.
606 * Othervise the function will return NULL.
607 *
608 * So, if you call fragment_delete and it returns non-NULL, YOU are responsible
609 * to tvb_free() that tvbuff.
610 */
611tvbuff_t *
612fragment_delete(reassembly_table *table, const packet_info *pinfo,
613 const uint32_t id, const void *data)
614{
615 fragment_head *fd_head;
616 fragment_item *fd;
617 tvbuff_t *fd_tvb_data=NULL((void*)0);
618 void *key;
619
620 fd_head = lookup_fd_head(table, pinfo, id, data, &key);
621 if(fd_head==NULL((void*)0)){
622 /* We do not recognize this as a PDU we have seen before. return */
623 return NULL((void*)0);
624 }
625
626 fd_tvb_data=fd_head->tvb_data;
627 /* loop over all partial fragments and free any tvbuffs */
628 for(fd=fd_head->next;fd;){
629 fragment_item *tmp_fd;
630 tmp_fd=fd->next;
631
632 if (fd->tvb_data && !(fd->flags & FD_SUBSET_TVB0x0020))
633 tvb_free(fd->tvb_data);
634 g_slice_free(fragment_item, fd)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd)); else
(void) ((fragment_item*) 0 == (fd)); } while (0)
;
635 fd=tmp_fd;
636 }
637 g_slice_free(fragment_head, fd_head)do { if (1) g_slice_free1 (sizeof (fragment_head), (fd_head))
; else (void) ((fragment_head*) 0 == (fd_head)); } while (0)
;
638 g_hash_table_remove(table->fragment_table, key);
639
640 return fd_tvb_data;
641}
642
643/* This function is used to check if there is partial or completed reassembly state
644 * matching this packet. I.e. Is there reassembly going on or not for this packet?
645 */
646fragment_head *
647fragment_get(reassembly_table *table, const packet_info *pinfo,
648 const uint32_t id, const void *data)
649{
650 return lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
651}
652
653fragment_head *
654fragment_get_reassembled_id(reassembly_table *table, const packet_info *pinfo,
655 const uint32_t id)
656{
657 fragment_head *fd_head;
658 reassembled_key key;
659
660 /* create key to search hash with */
661 key.frame = pinfo->num;
662 key.id = id;
663 fd_head = (fragment_head *)g_hash_table_lookup(table->reassembled_table, &key);
664
665 return fd_head;
666}
667
668/* To specify the offset for the fragment numbering, the first fragment is added with 0, and
669 * afterwards this offset is set. All additional calls to off_seq_check will calculate
670 * the number in sequence in regards to the offset */
671void
672fragment_add_seq_offset(reassembly_table *table, const packet_info *pinfo, const uint32_t id,
673 const void *data, const uint32_t fragment_offset)
674{
675 fragment_head *fd_head;
676
677 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
678 if (!fd_head)
679 return;
680
681 /* Resetting the offset is not allowed */
682 if ( fd_head->fragment_nr_offset != 0 )
683 return;
684
685 fd_head->fragment_nr_offset = fragment_offset;
686}
687
688static void
689update_first_gap(fragment_head *fd_head, fragment_item *inserted, bool_Bool multi_insert)
690{
691 uint32_t frag_end = inserted->offset + inserted->len;
692 fragment_item *iter;
693 uint32_t contiguous;
694
695 if (inserted->offset > fd_head->contiguous_len) {
696 /* first inserted node is after first gap */
697 return;
698 } else if (fd_head->first_gap == NULL((void*)0)) {
699 /* we haven't seen first fragment yet */
700 if (inserted->offset != 0) {
701 /* inserted node is not first fragment */
702 return;
703 }
704 contiguous = inserted->len;
705 iter = inserted;
706 } else {
707 contiguous = MAX(fd_head->contiguous_len, frag_end)(((fd_head->contiguous_len) > (frag_end)) ? (fd_head->
contiguous_len) : (frag_end))
;
708 iter = multi_insert ? inserted : fd_head->first_gap;
709 }
710
711 while (iter->next) {
712 if (iter->next->offset > contiguous) {
713 break;
714 }
715 iter = iter->next;
716 contiguous = MAX(contiguous, iter->offset + iter->len)(((contiguous) > (iter->offset + iter->len)) ? (contiguous
) : (iter->offset + iter->len))
;
717 }
718
719 /* iter is either pointing to last fragment before gap or tail */
720 fd_head->first_gap = iter;
721 fd_head->contiguous_len = contiguous;
722}
723
724/*
725 * Keeping first gap and contiguous length in sync significantly speeds up
726 * LINK_FRAG() when fragments in capture file are mostly ordered. However, when
727 * fragments are removed from the list, the first gap can point to fragments
728 * that were either moved to another list or freed. Therefore when any fragment
729 * before first gap is removed, the first gap (and contiguous length) must be
730 * invalidated.
731 */
732static void fragment_reset_first_gap(fragment_head *fd_head)
733{
734 fd_head->first_gap = NULL((void*)0);
735 fd_head->contiguous_len = 0;
736 if (fd_head->next) {
737 bool_Bool multi_insert = (fd_head->next->next != NULL((void*)0));
738 update_first_gap(fd_head, fd_head->next, multi_insert);
739 }
740}
741
742/*
743 * Determines whether list modification requires first gap reset. On entry
744 * modified is NULL if all elements were removed, otherwise it points to
745 * element (reachable from fd_head) whose next pointer was changed.
746 */
747static void fragment_items_removed(fragment_head *fd_head, fragment_item *modified)
748{
749 if ((fd_head->first_gap == modified) ||
750 ((modified != NULL((void*)0)) && (modified->offset > fd_head->contiguous_len))) {
751 /* Removed elements were after first gap */
752 return;
753 }
754 fragment_reset_first_gap(fd_head);
755}
756
757/*
758 * For use with fragment_add (and not the fragment_add_seq functions).
759 * When the reassembled result is wrong (perhaps it needs to be extended), this
760 * function clears any previous reassembly result, allowing the new reassembled
761 * length to be set again.
762 */
763static void
764fragment_reset_defragmentation(fragment_head *fd_head)
765{
766 /* Caller must ensure that this function is only called when
767 * defragmentation is safe to undo. */
768 DISSECTOR_ASSERT(fd_head->flags & FD_DEFRAGMENTED)((void) ((fd_head->flags & 0x0001) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 768, "fd_head->flags & 0x0001"
))))
;
769
770 for (fragment_item *fd_i = fd_head->next; fd_i; fd_i = fd_i->next) {
771 if (!fd_i->tvb_data) {
772 fd_i->tvb_data = tvb_new_subset_remaining(fd_head->tvb_data, fd_i->offset);
773 fd_i->flags |= FD_SUBSET_TVB0x0020;
774 }
775 fd_i->flags &= (~FD_TOOLONGFRAGMENT0x0010) & (~FD_MULTIPLETAILS0x0008);
776 }
777 fd_head->flags &= ~(FD_DEFRAGMENTED0x0001|FD_PARTIAL_REASSEMBLY0x0040|FD_DATALEN_SET0x0400);
778 fd_head->flags &= ~(FD_TOOLONGFRAGMENT0x0010|FD_MULTIPLETAILS0x0008);
779 fd_head->datalen = 0;
780 fd_head->reassembled_in = 0;
781 fd_head->reas_in_layer_num = 0;
782}
783
784/* This function can be used to explicitly set the total length (if known)
785 * for reassembly of a PDU.
786 * This is useful for reassembly of PDUs where one may have the total length specified
787 * in the first fragment instead of as for, say, IPv4 where a flag indicates which
788 * is the last fragment.
789 *
790 * Such protocols might fragment_add with a more_frags==true for every fragment
791 * and just tell the reassembly engine the expected total length of the reassembled data
792 * using fragment_set_tot_len immediately after doing fragment_add for the first packet.
793 *
794 * Note that for FD_BLOCKSEQUENCE tot_len is the index for the tail fragment.
795 * i.e. since the block numbers start at 0, if we specify tot_len==2, that
796 * actually means we want to defragment 3 blocks, block 0, 1 and 2.
797 */
798void
799fragment_set_tot_len(reassembly_table *table, const packet_info *pinfo,
800 const uint32_t id, const void *data, const uint32_t tot_len)
801{
802 fragment_head *fd_head;
803 fragment_item *fd;
804 uint32_t max_offset = 0;
805
806 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
807 if (!fd_head)
808 return;
809
810 /* If we're setting a block sequence number, verify that it
811 * doesn't conflict with values set by existing fragments.
812 * XXX - eliminate this check?
813 */
814 if (fd_head->flags & FD_BLOCKSEQUENCE0x0100) {
815 for (fd = fd_head->next; fd; fd = fd->next) {
816 if (fd->offset > max_offset) {
817 max_offset = fd->offset;
818 if (max_offset > tot_len) {
819 fd_head->error = "Bad total reassembly block count";
820 THROW_MESSAGE(ReassemblyError, fd_head->error)except_throw(1, (9), (fd_head->error));
821 }
822 }
823 }
824 }
825
826 if (fd_head->flags & FD_DEFRAGMENTED0x0001) {
827 if (max_offset != tot_len) {
828 fd_head->error = "Defragmented complete but total length not satisfied";
829 THROW_MESSAGE(ReassemblyError, fd_head->error)except_throw(1, (9), (fd_head->error));
830 }
831 }
832
833 /* We got this far so the value is sane. */
834 fd_head->datalen = tot_len;
835 fd_head->flags |= FD_DATALEN_SET0x0400;
836}
837
838void
839fragment_reset_tot_len(reassembly_table *table, const packet_info *pinfo,
840 const uint32_t id, const void *data, const uint32_t tot_len)
841{
842 fragment_head *fd_head;
843
844 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
845 if (!fd_head)
846 return;
847
848 /*
849 * If FD_PARTIAL_REASSEMBLY is set, it would make the next fragment_add
850 * call set the reassembled length based on the fragment offset and
851 * length. As the length is known now, be sure to disable that magic.
852 */
853 fd_head->flags &= ~FD_PARTIAL_REASSEMBLY0x0040;
854
855 /* If the length is already as expected, there is nothing else to do. */
856 if (tot_len == fd_head->datalen)
857 return;
858
859 if (fd_head->flags & FD_DEFRAGMENTED0x0001) {
860 /*
861 * Fragments were reassembled before, clear it to allow
862 * increasing the reassembled length.
863 */
864 fragment_reset_defragmentation(fd_head);
865 }
866
867 fd_head->datalen = tot_len;
868 fd_head->flags |= FD_DATALEN_SET0x0400;
869}
870
871void
872fragment_truncate(reassembly_table *table, const packet_info *pinfo,
873 const uint32_t id, const void *data, const uint32_t tot_len)
874
875{
876 tvbuff_t *old_tvb_data;
877 fragment_head *fd_head;
878
879 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
880 if (!fd_head)
881 return;
882
883 /* Caller must ensure that this function is only called when
884 * we are defragmented. */
885 DISSECTOR_ASSERT(fd_head->flags & FD_DEFRAGMENTED)((void) ((fd_head->flags & 0x0001) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 885, "fd_head->flags & 0x0001"
))))
;
886
887 /*
888 * If FD_PARTIAL_REASSEMBLY is set, it would make the next fragment_add
889 * call set the reassembled length based on the fragment offset and
890 * length. As the length is known now, be sure to disable that magic.
891 */
892 fd_head->flags &= ~FD_PARTIAL_REASSEMBLY0x0040;
893
894 /* If the length is already as expected, there is nothing else to do. */
895 if (tot_len == fd_head->datalen)
896 return;
897
898 DISSECTOR_ASSERT(fd_head->datalen > tot_len)((void) ((fd_head->datalen > tot_len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 898, "fd_head->datalen > tot_len"
))))
;
899
900 old_tvb_data=fd_head->tvb_data;
901 fd_head->tvb_data = tvb_clone_offset_len(old_tvb_data, 0, tot_len);
902 tvb_set_free_cb(fd_head->tvb_data, g_free);
903
904 if (old_tvb_data)
905 tvb_add_to_chain(fd_head->tvb_data, old_tvb_data);
906 fd_head->datalen = tot_len;
907
908 /* Keep the fragments before the split point, dividing any if
909 * necessary.
910 * XXX: In rare cases, there might be fragments marked as overlap that
911 * have data both before and after the split point, and which only
912 * overlap after the split point. In that case, after dividing the
913 * fragments the first part no longer overlap.
914 * However, at this point we can't test for overlap conflicts,
915 * so we'll just leave the overlap flags as-is.
916 */
917 fd_head->flags &= ~(FD_OVERLAP0x0002|FD_OVERLAPCONFLICT0x0004|FD_TOOLONGFRAGMENT0x0010|FD_MULTIPLETAILS0x0008);
918 fragment_item *fd_i, *prev_fd = NULL((void*)0);
919 for (fd_i = fd_head->next; fd_i && (fd_i->offset < tot_len); fd_i = fd_i->next) {
920 fd_i->flags &= ~(FD_TOOLONGFRAGMENT0x0010|FD_MULTIPLETAILS0x0008);
921 /* Check for the split point occurring in the middle of the
922 * fragment. */
923 if (fd_i->offset + fd_i->len > tot_len) {
924 fd_i->len = tot_len - fd_i->offset;
925 }
926 fd_head->flags |= fd_i->flags & (FD_OVERLAP0x0002|FD_OVERLAPCONFLICT0x0004);
927 prev_fd = fd_i;
928
929 /* Below should do nothing since this is already defragmented */
930 if (fd_i->flags & FD_SUBSET_TVB0x0020)
931 fd_i->flags &= ~FD_SUBSET_TVB0x0020;
932 else if (fd_i->tvb_data)
933 tvb_free(fd_i->tvb_data);
934
935 fd_i->tvb_data=NULL((void*)0);
936 }
937
938 /* Remove all the other fragments, as they are past the split point. */
939 if (prev_fd) {
940 prev_fd->next = NULL((void*)0);
941 } else {
942 fd_head->next = NULL((void*)0);
943 }
944 fd_head->contiguous_len = MIN(fd_head->contiguous_len, tot_len)(((fd_head->contiguous_len) < (tot_len)) ? (fd_head->
contiguous_len) : (tot_len))
;
945 fragment_items_removed(fd_head, prev_fd);
946 fragment_item *tmp_fd;
947 for (; fd_i; fd_i = tmp_fd) {
948 tmp_fd=fd_i->next;
949
950 if (fd_i->tvb_data && !(fd_i->flags & FD_SUBSET_TVB0x0020))
951 tvb_free(fd_i->tvb_data);
952 g_slice_free(fragment_item, fd_i)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd_i)); else
(void) ((fragment_item*) 0 == (fd_i)); } while (0)
;
953 }
954}
955
956uint32_t
957fragment_get_tot_len(reassembly_table *table, const packet_info *pinfo,
958 const uint32_t id, const void *data)
959{
960 fragment_head *fd_head;
961
962 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
963
964 if(fd_head){
965 return fd_head->datalen;
966 }
967
968 return 0;
969}
970
971/* This function will set the partial reassembly flag for a fh.
972 When this function is called, the fh MUST already exist, i.e.
973 the fh MUST be created by the initial call to fragment_add() before
974 this function is called.
975 Also note that this function MUST be called to indicate a fh will be
976 extended (increase the already stored data)
977*/
978
979void
980fragment_set_partial_reassembly(reassembly_table *table,
981 const packet_info *pinfo, const uint32_t id,
982 const void *data)
983{
984 fragment_head *fd_head;
985
986 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
987
988 /*
989 * XXX - why not do all the stuff done early in "fragment_add_work()",
990 * turning off FD_DEFRAGMENTED and pointing the fragments' data
991 * pointers to the appropriate part of the already-reassembled
992 * data, and clearing the data length and "reassembled in" frame
993 * number, here? We currently have a hack in the TCP dissector
994 * not to set the "reassembled in" value if the "partial reassembly"
995 * flag is set, so that in the first pass through the packets
996 * we don't falsely set a packet as reassembled in that packet
997 * if the dissector decided that even more reassembly was needed.
998 */
999 if(fd_head){
1000 fd_head->flags |= FD_PARTIAL_REASSEMBLY0x0040;
1001 }
1002}
1003
1004/*
1005 * This function gets rid of an entry from a fragment table, given
1006 * a pointer to the key for that entry.
1007 *
1008 * The key freeing routine will be called by g_hash_table_remove().
1009 */
1010static void
1011fragment_unhash(reassembly_table *table, void *key)
1012{
1013 /*
1014 * Remove the entry from the fragment table.
1015 */
1016 g_hash_table_remove(table->fragment_table, key);
1017}
1018
1019/*
1020 * This function adds fragment_head structure to a reassembled-packet
1021 * hash table, using the frame numbers of each of the frames from
1022 * which it was reassembled as keys, and sets the "reassembled_in"
1023 * frame number.
1024 */
1025static void
1026fragment_reassembled(reassembly_table *table, fragment_head *fd_head,
1027 const packet_info *pinfo, const uint32_t id)
1028{
1029 reassembled_key *new_key;
1030 fragment_item *fd;
1031
1032 fd_head->ref_count = 0;
1033 if (fd_head->next == NULL((void*)0)) {
1034 /*
1035 * This was not fragmented, so there's no fragment
1036 * table; just hash it using the current frame number.
1037 */
1038 new_key = g_slice_new(reassembled_key)((reassembled_key*) g_slice_alloc (sizeof (reassembled_key)));
1039 new_key->frame = pinfo->num;
1040 new_key->id = id;
1041 reassembled_table_insert(table->reassembled_table, new_key, fd_head);
1042 } else {
1043 /*
1044 * Hash it with the frame numbers for all the frames.
1045 */
1046 for (fd = fd_head->next; fd != NULL((void*)0); fd = fd->next){
1047 new_key = g_slice_new(reassembled_key)((reassembled_key*) g_slice_alloc (sizeof (reassembled_key)));
1048 new_key->frame = fd->frame;
1049 new_key->id = id;
1050 reassembled_table_insert(table->reassembled_table, new_key, fd_head);
1051 }
1052 }
1053 fd_head->flags |= FD_DEFRAGMENTED0x0001;
1054 fd_head->reassembled_in = pinfo->num;
1055 fd_head->reas_in_layer_num = pinfo->curr_layer_num;
1056}
1057
1058/*
1059 * This function is a variant of the above for the single sequence
1060 * case, using id+offset (i.e., the original sequence number) for the id
1061 * in the key.
1062 */
1063static void
1064fragment_reassembled_single(reassembly_table *table, fragment_head *fd_head,
1065 const packet_info *pinfo, const uint32_t id)
1066{
1067 reassembled_key *new_key;
1068 fragment_item *fd;
1069
1070 fd_head->ref_count = 0;
1071 if (fd_head->next == NULL((void*)0)) {
1072 /*
1073 * This was not fragmented, so there's no fragment
1074 * table; just hash it using the current frame number.
1075 */
1076 new_key = g_slice_new(reassembled_key)((reassembled_key*) g_slice_alloc (sizeof (reassembled_key)));
1077 new_key->frame = pinfo->num;
1078 new_key->id = id;
1079 reassembled_table_insert(table->reassembled_table, new_key, fd_head);
1080 } else {
1081 /*
1082 * Hash it with the frame numbers for all the frames.
1083 */
1084 for (fd = fd_head->next; fd != NULL((void*)0); fd = fd->next){
1085 new_key = g_slice_new(reassembled_key)((reassembled_key*) g_slice_alloc (sizeof (reassembled_key)));
1086 new_key->frame = fd->frame;
1087 new_key->id = id + fd->offset;
1088 reassembled_table_insert(table->reassembled_table, new_key, fd_head);
1089 }
1090 }
1091 fd_head->flags |= FD_DEFRAGMENTED0x0001;
1092 fd_head->reassembled_in = pinfo->num;
1093 fd_head->reas_in_layer_num = pinfo->curr_layer_num;
1094}
1095
1096static void
1097LINK_FRAG(fragment_head *fd_head,fragment_item *fd)
1098{
1099 fragment_item *fd_i;
1100
1101 /* add fragment to list, keep list sorted */
1102 if (fd_head->next == NULL((void*)0) || fd->offset < fd_head->next->offset) {
1103 /* New first fragment */
1104 fd->next = fd_head->next;
1105 fd_head->next = fd;
1106 } else {
1107 fd_i = fd_head->next;
1108 if (fd_head->first_gap != NULL((void*)0)) {
1109 if (fd->offset >= fd_head->first_gap->offset) {
1110 /* fragment is after first gap */
1111 fd_i = fd_head->first_gap;
1112 }
1113 }
1114 for(; fd_i->next; fd_i=fd_i->next) {
1115 if (fd->offset < fd_i->next->offset )
1116 break;
1117 }
1118 fd->next = fd_i->next;
1119 fd_i->next = fd;
1120 }
1121
1122 update_first_gap(fd_head, fd, false0);
1123}
1124
1125static void
1126MERGE_FRAG(fragment_head *fd_head, fragment_item *fd)
1127{
1128 fragment_item *fd_i, *tmp, *inserted = fd;
1129 bool_Bool multi_insert;
1130
1131 if (fd == NULL((void*)0)) return;
1132
1133 multi_insert = (fd->next != NULL((void*)0));
1134
1135 if (fd_head->next == NULL((void*)0)) {
1136 fd_head->next = fd;
1137 update_first_gap(fd_head, fd, multi_insert);
1138 return;
1139 }
1140
1141 if ((fd_head->first_gap != NULL((void*)0)) &&
1142 (fd->offset >= fd_head->first_gap->offset)) {
1143 /* all new fragments go after first gap */
1144 fd_i = fd_head->first_gap;
1145 } else {
1146 /* at least one new fragment goes before first gap */
1147 if (fd->offset < fd_head->next->offset) {
1148 /* inserted fragment is new head, "swap" the lists */
1149 tmp = fd_head->next;
1150 fd_head->next = fd;
1151 fd = tmp;
1152 }
1153 fd_i = fd_head->next;
1154 }
1155
1156 /* Traverse the list linked to fragment head ("main" list), checking if
1157 * fd pointer ("merge" list) should go before or after fd_i->next. Swap
1158 * fd_i->next ("main") and fd pointers ("merge") if "merge" list should
1159 * go before iterated element (fd_i). After the swap what formerly was
1160 * "merge" list essentially becomes part of "main" list (just detached
1161 * element, i.e. fd, is now head of new "merge list").
1162 */
1163 for(; fd_i->next; fd_i=fd_i->next) {
1164 if (fd->offset < fd_i->next->offset) {
1165 tmp = fd_i->next;
1166 fd_i->next = fd;
1167 fd = tmp;
1168 }
1169 }
1170 /* Reached "main" list end, attach remaining elements */
1171 fd_i->next = fd;
1172
1173 update_first_gap(fd_head, inserted, multi_insert);
1174}
1175
1176/*
1177 * This function adds a new fragment to the fragment hash table.
1178 * If this is the first fragment seen for this datagram, a new entry
1179 * is created in the hash table, otherwise this fragment is just added
1180 * to the linked list of fragments for this packet.
1181 * The list of fragments for a specific datagram is kept sorted for
1182 * easier handling.
1183 *
1184 * Returns a pointer to the head of the fragment data list if we have all the
1185 * fragments, NULL otherwise.
1186 *
1187 * This function assumes frag_offset being a byte offset into the defragment
1188 * packet.
1189 *
1190 * 01-2002
1191 * Once the fh is defragmented (= FD_DEFRAGMENTED set), it can be
1192 * extended using the FD_PARTIAL_REASSEMBLY flag. This flag should be set
1193 * using fragment_set_partial_reassembly() before calling fragment_add
1194 * with the new fragment. FD_TOOLONGFRAGMENT and FD_MULTIPLETAILS flags
1195 * are lowered when a new extension process is started.
1196 */
1197static bool_Bool
1198fragment_add_work(fragment_head *fd_head, tvbuff_t *tvb, const int offset,
1199 const packet_info *pinfo, const uint32_t frag_offset,
1200 const uint32_t frag_data_len, const bool_Bool more_frags,
1201 const uint32_t frag_frame, const bool_Bool allow_overlaps)
1202{
1203 fragment_item *fd;
1204 fragment_item *fd_i;
1205 uint32_t dfpos, fraglen, overlap;
1206 tvbuff_t *old_tvb_data;
1207 uint8_t *data;
1208
1209 /* create new fd describing this fragment */
1210 fd = g_slice_new(fragment_item)((fragment_item*) g_slice_alloc (sizeof (fragment_item)));
1211 fd->next = NULL((void*)0);
1212 fd->flags = 0;
1213 fd->frame = frag_frame;
1214 fd->offset = frag_offset;
1215 fd->len = frag_data_len;
1216 fd->tvb_data = NULL((void*)0);
1217
1218 /*
1219 * Are we adding to an already-completed reassembly?
1220 */
1221 if (fd_head->flags & FD_DEFRAGMENTED0x0001) {
39
Assuming the condition is false
40
Taking false branch
1222 /*
1223 * Yes. Does this fragment go past the end of the results
1224 * of that reassembly?
1225 */
1226 if (frag_offset + frag_data_len > fd_head->datalen) {
1227 /*
1228 * Yes. Have we been requested to continue reassembly?
1229 */
1230 if (fd_head->flags & FD_PARTIAL_REASSEMBLY0x0040) {
1231 /*
1232 * Yes. Set flag in already empty fds &
1233 * point old fds to malloc'ed data.
1234 */
1235 fragment_reset_defragmentation(fd_head);
1236 } else if (!allow_overlaps) {
1237 /*
1238 * No. Bail out since we have no idea what to
1239 * do with this fragment (and if we keep going
1240 * we'll run past the end of a buffer sooner
1241 * or later).
1242 */
1243 g_slice_free(fragment_item, fd)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd)); else
(void) ((fragment_item*) 0 == (fd)); } while (0)
;
1244
1245 /*
1246 * This is an attempt to add a fragment to a
1247 * reassembly that had already completed.
1248 * If it had no error, we don't want to
1249 * mark it with an error, and if it had an
1250 * error, we don't want to overwrite it, so
1251 * we don't set fd_head->error.
1252 */
1253 if (frag_offset >= fd_head->datalen) {
1254 /*
1255 * The fragment starts past the end
1256 * of the reassembled data.
1257 */
1258 THROW_MESSAGE(ReassemblyError, "New fragment past old data limits")except_throw(1, (9), ("New fragment past old data limits"));
1259 } else {
1260 /*
1261 * The fragment starts before the end
1262 * of the reassembled data, but
1263 * runs past the end. That could
1264 * just be a retransmission with extra
1265 * data, but the calling dissector
1266 * didn't set FD_PARTIAL_REASSEMBLY
1267 * so it won't be handled correctly.
1268 *
1269 * XXX: We could set FD_TOOLONGFRAGMENT
1270 * below instead.
1271 */
1272 THROW_MESSAGE(ReassemblyError, "New fragment overlaps old data (retransmission?)")except_throw(1, (9), ("New fragment overlaps old data (retransmission?)"
))
;
1273 }
1274 }
1275 } else {
1276 /*
1277 * No. That means it overlaps the completed reassembly.
1278 * This is probably a retransmission and normal
1279 * behavior. (If not, it's because the dissector
1280 * doesn't handle reused sequence numbers correctly,
1281 * e.g. #10503). Handle below.
1282 */
1283 }
1284 }
1285
1286 /* Do this after we may have bailed out (above) so that we don't leave
1287 * fd_head->frame in a bad state if we do */
1288 if (fd->frame > fd_head->frame)
41
Assuming 'fd->frame' is <= 'fd_head->frame'
42
Taking false branch
1289 fd_head->frame = fd->frame;
1290
1291 if (!more_frags
42.1
'more_frags' is true
) {
43
Taking false branch
1292 /*
1293 * This is the tail fragment in the sequence.
1294 */
1295 if (fd_head->flags & FD_DATALEN_SET0x0400) {
1296 /* ok we have already seen other tails for this packet
1297 * it might be a duplicate.
1298 */
1299 if (fd_head->datalen != (fd->offset + fd->len) ){
1300 /* Oops, this tail indicates a different packet
1301 * len than the previous ones. Something's wrong.
1302 */
1303 fd->flags |= FD_MULTIPLETAILS0x0008;
1304 fd_head->flags |= FD_MULTIPLETAILS0x0008;
1305 }
1306 } else {
1307 /* This was the first tail fragment; now we know
1308 * what the length of the packet should be.
1309 */
1310 fd_head->datalen = fd->offset + fd->len;
1311 fd_head->flags |= FD_DATALEN_SET0x0400;
1312 }
1313 }
1314
1315
1316
1317 /* If the packet is already defragmented, this MUST be an overlap.
1318 * The entire defragmented packet is in fd_head->data.
1319 * Even if we have previously defragmented this packet, we still
1320 * check it. Someone might play overlap and TTL games.
1321 */
1322 if (fd_head->flags & FD_DEFRAGMENTED0x0001) {
44
Taking false branch
1323 uint32_t end_offset = fd->offset + fd->len;
1324 fd->flags |= FD_OVERLAP0x0002;
1325 fd_head->flags |= FD_OVERLAP0x0002;
1326 /* make sure it's not too long */
1327 /* XXX: We probably don't call this, unlike the _seq()
1328 * functions, because we throw an exception above.
1329 */
1330 if (end_offset > fd_head->datalen || end_offset < fd->offset || end_offset < fd->len) {
1331 fd->flags |= FD_TOOLONGFRAGMENT0x0010;
1332 fd_head->flags |= FD_TOOLONGFRAGMENT0x0010;
1333 }
1334 /* make sure it doesn't conflict with previous data */
1335 else if ( tvb_memeql(fd_head->tvb_data, fd->offset,
1336 tvb_get_ptr(tvb,offset,fd->len),fd->len) ){
1337 fd->flags |= FD_OVERLAPCONFLICT0x0004;
1338 fd_head->flags |= FD_OVERLAPCONFLICT0x0004;
1339 }
1340 /* it was just an overlap, link it and return */
1341 LINK_FRAG(fd_head,fd);
1342 return true1;
1343 }
1344
1345
1346
1347 /* If we have reached this point, the packet is not defragmented yet.
1348 * Save all payload in a buffer until we can defragment.
1349 */
1350 if (!tvb_bytes_exist(tvb, offset, fd->len)) {
45
Assuming the condition is false
46
Taking false branch
1351 g_slice_free(fragment_item, fd)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd)); else
(void) ((fragment_item*) 0 == (fd)); } while (0)
;
1352 THROW(BoundsError)except_throw(1, (1), ((void*)0));
1353 }
1354 fd->tvb_data = tvb_clone_offset_len(tvb, offset, fd->len);
1355 LINK_FRAG(fd_head,fd);
1356
1357
1358 if( !(fd_head->flags & FD_DATALEN_SET0x0400) ){
47
Assuming the condition is false
48
Taking false branch
1359 /* if we don't know the datalen, there are still missing
1360 * packets. Cheaper than the check below.
1361 */
1362 return false0;
1363 }
1364
1365 /* Check if we have received the entire fragment. */
1366 if (fd_head->contiguous_len < fd_head->datalen) {
49
Assuming field 'contiguous_len' is >= field 'datalen'
50
Taking false branch
1367 /*
1368 * The amount of contiguous data we have is less than the
1369 * amount of data we're trying to reassemble, so we haven't
1370 * received all packets yet.
1371 */
1372 return false0;
1373 }
1374
1375 /* we have received an entire packet, defragment it and
1376 * free all fragments
1377 */
1378 /* store old data just in case */
1379 old_tvb_data=fd_head->tvb_data;
1380 data = (uint8_t *) g_malloc(fd_head->datalen);
51
Memory is allocated
1381 fd_head->tvb_data = tvb_new_real_data(data, fd_head->datalen, fd_head->datalen);
1382 tvb_set_free_cb(fd_head->tvb_data, g_free);
1383
1384 /* add all data fragments */
1385 for (dfpos=0,fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
52
Loop condition is false. Execution continues on line 1506
1386 if (fd_i->len) {
1387 /*
1388 * The contiguous length check above also
1389 * ensures that the only gaps that exist here
1390 * are ones where a fragment starts past the
1391 * end of the reassembled datagram, and there's
1392 * a gap between the previous fragment and
1393 * that fragment.
1394 *
1395 * A "DESEGMENT_UNTIL_FIN" was involved wherein the
1396 * FIN packet had an offset less than the highest
1397 * fragment offset seen. [Seen from a fuzz-test:
1398 * bug #2470]).
1399 *
1400 * Note that the "overlap" compare must only be
1401 * done for fragments with (offset+len) <= fd_head->datalen
1402 * and thus within the newly g_malloc'd buffer.
1403 */
1404
1405 if (fd_i->offset >= fd_head->datalen) {
1406 /*
1407 * Fragment starts after the end
1408 * of the reassembled packet.
1409 *
1410 * This can happen if the length was
1411 * set after the offending fragment
1412 * was added to the reassembly.
1413 *
1414 * Flag this fragment, but don't
1415 * try to extract any data from
1416 * it, as there's no place to put
1417 * it.
1418 *
1419 * XXX - add different flag value
1420 * for this.
1421 */
1422 fd_i->flags |= FD_TOOLONGFRAGMENT0x0010;
1423 fd_head->flags |= FD_TOOLONGFRAGMENT0x0010;
1424 } else if (fd_i->offset + fd_i->len < fd_i->offset) {
1425 /* Integer overflow, unhandled by rest of
1426 * code so error out. This check handles
1427 * all possible remaining overflows.
1428 */
1429 fd_head->error = "offset + len < offset";
1430 } else if (!fd_i->tvb_data) {
1431 fd_head->error = "no data";
1432 } else {
1433 fraglen = fd_i->len;
1434 if (fd_i->offset + fraglen > fd_head->datalen) {
1435 /*
1436 * Fragment goes past the end
1437 * of the packet, as indicated
1438 * by the last fragment.
1439 *
1440 * This can happen if the
1441 * length was set after the
1442 * offending fragment was
1443 * added to the reassembly.
1444 *
1445 * Mark it as such, and only
1446 * copy from it what fits in
1447 * the packet.
1448 */
1449 fd_i->flags |= FD_TOOLONGFRAGMENT0x0010;
1450 fd_head->flags |= FD_TOOLONGFRAGMENT0x0010;
1451 fraglen = fd_head->datalen - fd_i->offset;
1452 }
1453 overlap = dfpos - fd_i->offset;
1454 /* Guaranteed to be >= 0, previous code
1455 * has checked for gaps. */
1456 if (overlap) {
1457 /* duplicate/retransmission/overlap */
1458 uint32_t cmp_len = MIN(fd_i->len,overlap)(((fd_i->len) < (overlap)) ? (fd_i->len) : (overlap)
)
;
1459
1460 fd_i->flags |= FD_OVERLAP0x0002;
1461 fd_head->flags |= FD_OVERLAP0x0002;
1462 if ( memcmp(data + fd_i->offset,
1463 tvb_get_ptr(fd_i->tvb_data, 0, cmp_len),
1464 cmp_len)
1465 ) {
1466 fd_i->flags |= FD_OVERLAPCONFLICT0x0004;
1467 fd_head->flags |= FD_OVERLAPCONFLICT0x0004;
1468 }
1469 }
1470 /* XXX: As in the fragment_add_seq funcs
1471 * like fragment_defragment_and_free() the
1472 * existing behavior does not overwrite
1473 * overlapping bytes even if there is a
1474 * conflict. It only adds new bytes.
1475 *
1476 * Since we only add fragments to a reassembly
1477 * if the reassembly isn't complete, the most
1478 * common case for overlap conflicts is when
1479 * an earlier reassembly isn't fully contained
1480 * in the capture, and we've reused an
1481 * indentification number / wrapped around
1482 * offset sequence numbers much later in the
1483 * capture. In that case, we probably *do*
1484 * want to overwrite conflicting bytes, since
1485 * the earlier fragments didn't form a complete
1486 * reassembly and should be effectively thrown
1487 * out rather than mixed with the new ones?
1488 */
1489 if (fd_i->offset + fraglen > dfpos) {
1490 memcpy(data+dfpos,
1491 tvb_get_ptr(fd_i->tvb_data, overlap, fraglen-overlap),
1492 fraglen-overlap);
1493 dfpos = fd_i->offset + fraglen;
1494 }
1495 }
1496
1497 if (fd_i->flags & FD_SUBSET_TVB0x0020)
1498 fd_i->flags &= ~FD_SUBSET_TVB0x0020;
1499 else if (fd_i->tvb_data)
1500 tvb_free(fd_i->tvb_data);
1501
1502 fd_i->tvb_data=NULL((void*)0);
1503 }
1504 }
1505
1506 if (old_tvb_data)
53
Potential leak of memory pointed to by 'data'
1507 tvb_add_to_chain(tvb, old_tvb_data);
1508 /* mark this packet as defragmented.
1509 allows us to skip any trailing fragments */
1510 fd_head->flags |= FD_DEFRAGMENTED0x0001;
1511 fd_head->reassembled_in=pinfo->num;
1512 fd_head->reas_in_layer_num = pinfo->curr_layer_num;
1513
1514 /* we don't throw until here to avoid leaking old_data and others */
1515 if (fd_head->error) {
1516 THROW_MESSAGE(ReassemblyError, fd_head->error)except_throw(1, (9), (fd_head->error));
1517 }
1518
1519 return true1;
1520}
1521
1522static fragment_head *
1523fragment_add_common(reassembly_table *table, tvbuff_t *tvb, const int offset,
1524 const packet_info *pinfo, const uint32_t id,
1525 const void *data, const uint32_t frag_offset,
1526 const uint32_t frag_data_len, const bool_Bool more_frags,
1527 const bool_Bool check_already_added,
1528 const uint32_t frag_frame)
1529{
1530 fragment_head *fd_head;
1531 fragment_item *fd_item;
1532 bool_Bool already_added;
1533
1534
1535 /*
1536 * Dissector shouldn't give us garbage tvb info.
1537 *
1538 * XXX - should this code take responsibility for preventing
1539 * reassembly if data is missing due to the packets being
1540 * sliced, rather than leaving it up to dissectors?
1541 */
1542 DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, frag_data_len))((void) ((tvb_bytes_exist(tvb, offset, frag_data_len)) ? (void
)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/reassemble.c", 1542, "tvb_bytes_exist(tvb, offset, frag_data_len)"
))))
;
28
Assuming the condition is true
29
'?' condition is true
1543
1544 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
1545
1546#if 0
1547 /* debug output of associated fragments. */
1548 /* leave it here for future debugging sessions */
1549 if(strcmp(pinfo->current_proto, "DCERPC") == 0) {
1550 printf("proto:%s num:%u id:%u offset:%u len:%u more:%u visited:%u\n",
1551 pinfo->current_proto, pinfo->num, id, frag_offset, frag_data_len, more_frags, pinfo->fd->visited);
1552 if(fd_head != NULL((void*)0)) {
1553 for(fd_item=fd_head->next;fd_item;fd_item=fd_item->next){
1554 printf("fd_frame:%u fd_offset:%u len:%u datalen:%u\n",
1555 fd_item->frame, fd_item->offset, fd_item->len, fd_item->datalen);
1556 }
1557 }
1558 }
1559#endif
1560
1561 /*
1562 * Is this the first pass through the capture?
1563 */
1564 if (!pinfo->fd->visited) {
30
Assuming field 'visited' is 0
1565 /*
1566 * Yes, so we could be doing reassembly. If
1567 * "check_already_added" is true, and fd_head is non-null,
1568 * meaning that this fragment would be added to an
1569 * in-progress reassembly, check if we have seen this
1570 * fragment before, i.e., if we have already added it to
1571 * that reassembly. That can be true even on the first pass
1572 * since we sometimes might call a subdissector multiple
1573 * times.
1574 *
1575 * We check both the frame number and the fragment offset,
1576 * so that we support multiple fragments from the same
1577 * frame being added to the same reassembled PDU.
1578 */
1579 if (check_already_added
30.1
'check_already_added' is true
&& fd_head != NULL((void*)0)) {
31
Assuming 'fd_head' is not equal to NULL
32
Taking true branch
1580 /*
1581 * fd_head->frame is the maximum of the frame
1582 * numbers of all the fragments added to this
1583 * reassembly; if this frame is later than that
1584 * frame, we know it hasn't been added yet.
1585 */
1586 if (frag_frame <= fd_head->frame) {
33
Assuming 'frag_frame' is <= field 'frame'
34
Taking true branch
1587 already_added = false0;
1588 /*
1589 * The first item in the reassembly list
1590 * is not a fragment, it's a data structure
1591 * for the reassembled packet, so we
1592 * start checking with the next item.
1593 */
1594 for (fd_item = fd_head->next; fd_item;
35
Loop condition is false. Execution continues on line 1602
1595 fd_item = fd_item->next) {
1596 if (frag_frame == fd_item->frame &&
1597 frag_offset == fd_item->offset) {
1598 already_added = true1;
1599 break;
1600 }
1601 }
1602 if (already_added
35.1
'already_added' is false
) {
36
Taking false branch
1603 /*
1604 * Have we already finished
1605 * reassembling?
1606 */
1607 if (fd_head->flags & FD_DEFRAGMENTED0x0001) {
1608 /*
1609 * Yes.
1610 * XXX - can this ever happen?
1611 */
1612 THROW_MESSAGE(ReassemblyError,except_throw(1, (9), ("Frame already added in first pass"))
1613 "Frame already added in first pass")except_throw(1, (9), ("Frame already added in first pass"));
1614 } else {
1615 /*
1616 * No.
1617 */
1618 return NULL((void*)0);
1619 }
1620 }
1621 }
1622 }
1623 } else {
1624 /*
1625 * No, so we've already done all the reassembly and added
1626 * all the fragments. Do we have a reassembly and, if so,
1627 * have we finished reassembling?
1628 */
1629 if (fd_head != NULL((void*)0) && fd_head->flags & FD_DEFRAGMENTED0x0001) {
1630 /*
1631 * Yes. This is probably being done after the
1632 * first pass, and we've already done the work
1633 * on the first pass.
1634 *
1635 * If the reassembly got a fatal error, throw that
1636 * error again.
1637 */
1638 if (fd_head->error)
1639 THROW_MESSAGE(ReassemblyError, fd_head->error)except_throw(1, (9), (fd_head->error));
1640
1641 /*
1642 * Is it later in the capture than all of the
1643 * fragments in the reassembly?
1644 */
1645 if (frag_frame > fd_head->frame) {
1646 /*
1647 * Yes, so report this as a problem,
1648 * possibly a retransmission.
1649 */
1650 THROW_MESSAGE(ReassemblyError, "New fragment overlaps old data (retransmission?)")except_throw(1, (9), ("New fragment overlaps old data (retransmission?)"
))
;
1651 }
1652
1653 /*
1654 * Does this fragment go past the end of the
1655 * results of that reassembly?
1656 */
1657 if (frag_offset + frag_data_len > fd_head->datalen) {
1658 /*
1659 * Yes.
1660 */
1661 if (frag_offset >= fd_head->datalen) {
1662 /*
1663 * The fragment starts past the
1664 * end of the reassembled data.
1665 */
1666 THROW_MESSAGE(ReassemblyError, "New fragment past old data limits")except_throw(1, (9), ("New fragment past old data limits"));
1667 } else {
1668 /*
1669 * The fragment starts before the end
1670 * of the reassembled data, but
1671 * runs past the end. That could
1672 * just be a retransmission.
1673 */
1674 THROW_MESSAGE(ReassemblyError, "New fragment overlaps old data (retransmission?)")except_throw(1, (9), ("New fragment overlaps old data (retransmission?)"
))
;
1675 }
1676 }
1677
1678 return fd_head;
1679 } else {
1680 /*
1681 * No.
1682 */
1683 return NULL((void*)0);
1684 }
1685 }
1686
1687 if (fd_head
36.1
'fd_head' is not equal to NULL
==NULL((void*)0)){
37
Taking false branch
1688 /* not found, this must be the first snooped fragment for this
1689 * packet. Create list-head.
1690 */
1691 fd_head = new_head(0);
1692
1693 /*
1694 * Insert it into the hash table.
1695 */
1696 insert_fd_head(table, fd_head, pinfo, id, data);
1697 }
1698
1699 if (fragment_add_work(fd_head, tvb, offset, pinfo, frag_offset,
38
Calling 'fragment_add_work'
1700 frag_data_len, more_frags, frag_frame, false0)) {
1701 /*
1702 * Reassembly is complete.
1703 */
1704 return fd_head;
1705 } else {
1706 /*
1707 * Reassembly isn't complete.
1708 */
1709 return NULL((void*)0);
1710 }
1711}
1712
1713fragment_head *
1714fragment_add(reassembly_table *table, tvbuff_t *tvb, const int offset,
1715 const packet_info *pinfo, const uint32_t id, const void *data,
1716 const uint32_t frag_offset, const uint32_t frag_data_len,
1717 const bool_Bool more_frags)
1718{
1719 return fragment_add_common(table, tvb, offset, pinfo, id, data,
27
Calling 'fragment_add_common'
1720 frag_offset, frag_data_len, more_frags, true1, pinfo->num);
1721}
1722
1723/*
1724 * For use when you can have multiple fragments in the same frame added
1725 * to the same reassembled PDU, e.g. with ONC RPC-over-TCP.
1726 */
1727fragment_head *
1728fragment_add_multiple_ok(reassembly_table *table, tvbuff_t *tvb,
1729 const int offset, const packet_info *pinfo,
1730 const uint32_t id, const void *data,
1731 const uint32_t frag_offset,
1732 const uint32_t frag_data_len, const bool_Bool more_frags)
1733{
1734 return fragment_add_common(table, tvb, offset, pinfo, id, data,
1735 frag_offset, frag_data_len, more_frags, false0, pinfo->num);
1736}
1737
1738/*
1739 * For use in protocols like TCP when you are adding an out of order segment
1740 * that arrived in an earlier frame because the correct fragment id could not
1741 * be determined until later. By allowing fd->frame to be different than
1742 * pinfo->num, show_fragment_tree will display the correct fragment numbers.
1743 *
1744 * Note that pinfo is still used to set reassembled_in if we have all the
1745 * fragments, so that results on subsequent passes can be the same as the
1746 * first pass.
1747 */
1748fragment_head *
1749fragment_add_out_of_order(reassembly_table *table, tvbuff_t *tvb,
1750 const int offset, const packet_info *pinfo,
1751 const uint32_t id, const void *data,
1752 const uint32_t frag_offset,
1753 const uint32_t frag_data_len,
1754 const bool_Bool more_frags, const uint32_t frag_frame)
1755{
1756 return fragment_add_common(table, tvb, offset, pinfo, id, data,
1757 frag_offset, frag_data_len, more_frags, true1, frag_frame);
1758}
1759
1760fragment_head *
1761fragment_add_check_with_fallback(reassembly_table *table, tvbuff_t *tvb, const int offset,
1762 const packet_info *pinfo, const uint32_t id,
1763 const void *data, const uint32_t frag_offset,
1764 const uint32_t frag_data_len, const bool_Bool more_frags,
1765 const uint32_t fallback_frame)
1766{
1767 reassembled_key reass_key;
1768 fragment_head *fd_head;
1769 void *orig_key;
1770 bool_Bool late_retransmission = false0;
1771
1772 /*
1773 * If this isn't the first pass, look for this frame in the table
1774 * of reassembled packets.
1775 */
1776 if (pinfo->fd->visited) {
1777 reass_key.frame = pinfo->num;
1778 reass_key.id = id;
1779 return (fragment_head *)g_hash_table_lookup(table->reassembled_table, &reass_key);
1780 }
1781
1782 /* Looks up a key in the GHashTable, returning the original key and the associated value
1783 * and a bool which is true if the key was found. This is useful if you need to free
1784 * the memory allocated for the original key, for example before calling g_hash_table_remove()
1785 */
1786 fd_head = lookup_fd_head(table, pinfo, id, data, &orig_key);
1787 if ((fd_head == NULL((void*)0)) && (fallback_frame != pinfo->num)) {
1788 /* Check if there is completed reassembly reachable from fallback frame */
1789 reass_key.frame = fallback_frame;
1790 reass_key.id = id;
1791 fd_head = (fragment_head *)g_hash_table_lookup(table->reassembled_table, &reass_key);
1792 if (fd_head != NULL((void*)0)) {
1793 /* Found completely reassembled packet, hash it with current frame number */
1794 reassembled_key *new_key = g_slice_new(reassembled_key)((reassembled_key*) g_slice_alloc (sizeof (reassembled_key)));
1795 new_key->frame = pinfo->num;
1796 new_key->id = id;
1797 reassembled_table_insert(table->reassembled_table, new_key, fd_head);
1798 late_retransmission = true1;
1799 }
1800 }
1801 if (fd_head == NULL((void*)0)) {
1802 /* not found, this must be the first snooped fragment for this
1803 * packet. Create list-head.
1804 */
1805 fd_head = new_head(0);
1806
1807 /*
1808 * Save the key, for unhashing it later.
1809 */
1810 orig_key = insert_fd_head(table, fd_head, pinfo, id, data);
1811 }
1812
1813 /*
1814 * If this is a short frame, then we can't, and don't, do
1815 * reassembly on it. We just give up.
1816 */
1817 if (!tvb_bytes_exist(tvb, offset, frag_data_len)) {
1818 return NULL((void*)0);
1819 }
1820
1821 if (fragment_add_work(fd_head, tvb, offset, pinfo, frag_offset,
1822 frag_data_len, more_frags, pinfo->num, late_retransmission)) {
1823 /* Nothing left to do if it was a late retransmission */
1824 if (late_retransmission) {
1825 return fd_head;
1826 }
1827 /*
1828 * Reassembly is complete.
1829 * Remove this from the table of in-progress
1830 * reassemblies, add it to the table of
1831 * reassembled packets, and return it.
1832 */
1833
1834 /*
1835 * Remove this from the table of in-progress reassemblies,
1836 * and free up any memory used for it in that table.
1837 */
1838 fragment_unhash(table, orig_key);
1839
1840 /*
1841 * Add this item to the table of reassembled packets.
1842 */
1843 fragment_reassembled(table, fd_head, pinfo, id);
1844 return fd_head;
1845 } else {
1846 /*
1847 * Reassembly isn't complete.
1848 */
1849 return NULL((void*)0);
1850 }
1851}
1852
1853fragment_head *
1854fragment_add_check(reassembly_table *table, tvbuff_t *tvb, const int offset,
1855 const packet_info *pinfo, const uint32_t id,
1856 const void *data, const uint32_t frag_offset,
1857 const uint32_t frag_data_len, const bool_Bool more_frags)
1858{
1859 return fragment_add_check_with_fallback(table, tvb, offset, pinfo, id, data,
1860 frag_offset, frag_data_len, more_frags, pinfo->num);
1861}
1862
1863static void
1864fragment_defragment_and_free (fragment_head *fd_head, const packet_info *pinfo)
1865{
1866 fragment_item *fd_i = NULL((void*)0);
1867 fragment_item *last_fd = NULL((void*)0);
1868 uint32_t dfpos = 0, size = 0;
1869 tvbuff_t *old_tvb_data = NULL((void*)0);
1870 uint8_t *data;
1871
1872 for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
1873 if(!last_fd || last_fd->offset!=fd_i->offset){
1874 size+=fd_i->len;
1875 }
1876 last_fd=fd_i;
1877 }
1878
1879 /* store old data in case the fd_i->data pointers refer to it */
1880 old_tvb_data=fd_head->tvb_data;
1881 data = (uint8_t *) g_malloc(size);
1882 fd_head->tvb_data = tvb_new_real_data(data, size, size);
1883 tvb_set_free_cb(fd_head->tvb_data, g_free);
1884 fd_head->len = size; /* record size for caller */
1885
1886 /* add all data fragments */
1887 last_fd=NULL((void*)0);
1888 for (fd_i=fd_head->next; fd_i; fd_i=fd_i->next) {
1889 if (fd_i->len) {
1890 if(!last_fd || last_fd->offset != fd_i->offset) {
1891 /* First fragment or in-sequence fragment */
1892 memcpy(data+dfpos, tvb_get_ptr(fd_i->tvb_data, 0, fd_i->len), fd_i->len);
1893 dfpos += fd_i->len;
1894 } else {
1895 /* duplicate/retransmission/overlap */
1896 fd_i->flags |= FD_OVERLAP0x0002;
1897 fd_head->flags |= FD_OVERLAP0x0002;
1898 if(last_fd->len != fd_i->len
1899 || tvb_memeql(last_fd->tvb_data, 0, tvb_get_ptr(fd_i->tvb_data, 0, last_fd->len), last_fd->len) ) {
1900 fd_i->flags |= FD_OVERLAPCONFLICT0x0004;
1901 fd_head->flags |= FD_OVERLAPCONFLICT0x0004;
1902 }
1903 }
1904 }
1905 last_fd=fd_i;
1906 }
1907
1908 /* we have defragmented the pdu, now free all fragments*/
1909 for (fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
1910 if (fd_i->flags & FD_SUBSET_TVB0x0020)
1911 fd_i->flags &= ~FD_SUBSET_TVB0x0020;
1912 else if (fd_i->tvb_data)
1913 tvb_free(fd_i->tvb_data);
1914 fd_i->tvb_data=NULL((void*)0);
1915 }
1916 if (old_tvb_data)
1917 tvb_free(old_tvb_data);
1918
1919 /* mark this packet as defragmented.
1920 * allows us to skip any trailing fragments.
1921 */
1922 fd_head->flags |= FD_DEFRAGMENTED0x0001;
1923 fd_head->reassembled_in=pinfo->num;
1924 fd_head->reas_in_layer_num = pinfo->curr_layer_num;
1925}
1926
1927/*
1928 * This function adds a new fragment to the entry for a reassembly
1929 * operation.
1930 *
1931 * The list of fragments for a specific datagram is kept sorted for
1932 * easier handling.
1933 *
1934 * Returns true if we have all the fragments, false otherwise.
1935 *
1936 * This function assumes frag_number being a block sequence number.
1937 * The bsn for the first block is 0.
1938 */
1939static bool_Bool
1940fragment_add_seq_work(fragment_head *fd_head, tvbuff_t *tvb, const int offset,
1941 const packet_info *pinfo, const uint32_t frag_number,
1942 const uint32_t frag_data_len, const bool_Bool more_frags)
1943{
1944 fragment_item *fd;
1945 fragment_item *fd_i;
1946 fragment_item *last_fd;
1947 uint32_t max, dfpos;
1948 uint32_t frag_number_work;
1949
1950 /* Enables the use of fragment sequence numbers, which do not start with 0 */
1951 frag_number_work = frag_number;
1952 if ( fd_head->fragment_nr_offset != 0 )
1953 if ( frag_number_work >= fd_head->fragment_nr_offset )
1954 frag_number_work = frag_number - fd_head->fragment_nr_offset;
1955
1956 /* if the partial reassembly flag has been set, and we are extending
1957 * the pdu, un-reassemble the pdu. This means pointing old fds to malloc'ed data.
1958 */
1959 if(fd_head->flags & FD_DEFRAGMENTED0x0001 && frag_number_work >= fd_head->datalen &&
1960 fd_head->flags & FD_PARTIAL_REASSEMBLY0x0040){
1961 uint32_t lastdfpos = 0;
1962 dfpos = 0;
1963 for(fd_i=fd_head->next; fd_i; fd_i=fd_i->next){
1964 if( !fd_i->tvb_data ) {
1965 if( fd_i->flags & FD_OVERLAP0x0002 ) {
1966 /* this is a duplicate of the previous
1967 * fragment. */
1968 fd_i->tvb_data = tvb_new_subset_remaining(fd_head->tvb_data, lastdfpos);
1969 } else {
1970 fd_i->tvb_data = tvb_new_subset_remaining(fd_head->tvb_data, dfpos);
1971 lastdfpos = dfpos;
1972 dfpos += fd_i->len;
1973 }
1974 fd_i->flags |= FD_SUBSET_TVB0x0020;
1975 }
1976 fd_i->flags &= (~FD_TOOLONGFRAGMENT0x0010) & (~FD_MULTIPLETAILS0x0008);
1977 }
1978 fd_head->flags &= ~(FD_DEFRAGMENTED0x0001|FD_PARTIAL_REASSEMBLY0x0040|FD_DATALEN_SET0x0400);
1979 fd_head->flags &= (~FD_TOOLONGFRAGMENT0x0010) & (~FD_MULTIPLETAILS0x0008);
1980 fd_head->datalen=0;
1981 fd_head->reassembled_in=0;
1982 fd_head->reas_in_layer_num = 0;
1983 }
1984
1985
1986 /* create new fd describing this fragment */
1987 fd = g_slice_new(fragment_item)((fragment_item*) g_slice_alloc (sizeof (fragment_item)));
1988 fd->next = NULL((void*)0);
1989 fd->flags = 0;
1990 fd->frame = pinfo->num;
1991 fd->offset = frag_number_work;
1992 fd->len = frag_data_len;
1993 fd->tvb_data = NULL((void*)0);
1994
1995 /* fd_head->frame is the maximum of the frame numbers of all the
1996 * fragments added to the reassembly. */
1997 if (fd->frame > fd_head->frame)
1998 fd_head->frame = fd->frame;
1999
2000 if (!more_frags) {
2001 /*
2002 * This is the tail fragment in the sequence.
2003 */
2004 if (fd_head->flags&FD_DATALEN_SET0x0400) {
2005 /* ok we have already seen other tails for this packet
2006 * it might be a duplicate.
2007 */
2008 if (fd_head->datalen != fd->offset ){
2009 /* Oops, this tail indicates a different packet
2010 * len than the previous ones. Something's wrong.
2011 */
2012 fd->flags |= FD_MULTIPLETAILS0x0008;
2013 fd_head->flags |= FD_MULTIPLETAILS0x0008;
2014 }
2015 } else {
2016 /* this was the first tail fragment, now we know the
2017 * sequence number of that fragment (which is NOT
2018 * the length of the packet!)
2019 */
2020 fd_head->datalen = fd->offset;
2021 fd_head->flags |= FD_DATALEN_SET0x0400;
2022 }
2023 }
2024
2025 /* If the packet is already defragmented, this MUST be an overlap.
2026 * The entire defragmented packet is in fd_head->data
2027 * Even if we have previously defragmented this packet, we still check
2028 * check it. Someone might play overlap and TTL games.
2029 */
2030 if (fd_head->flags & FD_DEFRAGMENTED0x0001) {
2031 fd->flags |= FD_OVERLAP0x0002;
2032 fd_head->flags |= FD_OVERLAP0x0002;
2033
2034 /* make sure it's not past the end */
2035 if (fd->offset > fd_head->datalen) {
2036 /* new fragment comes after the end */
2037 fd->flags |= FD_TOOLONGFRAGMENT0x0010;
2038 fd_head->flags |= FD_TOOLONGFRAGMENT0x0010;
2039 LINK_FRAG(fd_head,fd);
2040 return true1;
2041 }
2042 /* make sure it doesn't conflict with previous data */
2043 dfpos=0;
2044 last_fd=NULL((void*)0);
2045 for (fd_i=fd_head->next;fd_i && (fd_i->offset!=fd->offset);fd_i=fd_i->next) {
2046 if (!last_fd || last_fd->offset!=fd_i->offset){
2047 dfpos += fd_i->len;
2048 }
2049 last_fd=fd_i;
2050 }
2051 if(fd_i){
2052 /* new fragment overlaps existing fragment */
2053 if(fd_i->len!=fd->len){
2054 /*
2055 * They have different lengths; this
2056 * is definitely a conflict.
2057 */
2058 fd->flags |= FD_OVERLAPCONFLICT0x0004;
2059 fd_head->flags |= FD_OVERLAPCONFLICT0x0004;
2060 LINK_FRAG(fd_head,fd);
2061 return true1;
2062 }
2063 DISSECTOR_ASSERT(fd_head->len >= dfpos + fd->len)((void) ((fd_head->len >= dfpos + fd->len) ? (void)0
: (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/reassemble.c", 2063, "fd_head->len >= dfpos + fd->len"
))))
;
2064 if (tvb_memeql(fd_head->tvb_data, dfpos,
2065 tvb_get_ptr(tvb,offset,fd->len),fd->len) ){
2066 /*
2067 * They have the same length, but the
2068 * data isn't the same.
2069 */
2070 fd->flags |= FD_OVERLAPCONFLICT0x0004;
2071 fd_head->flags |= FD_OVERLAPCONFLICT0x0004;
2072 LINK_FRAG(fd_head,fd);
2073 return true1;
2074 }
2075 /* it was just an overlap, link it and return */
2076 LINK_FRAG(fd_head,fd);
2077 return true1;
2078 } else {
2079 /*
2080 * New fragment doesn't overlap an existing
2081 * fragment - there was presumably a gap in
2082 * the sequence number space.
2083 *
2084 * XXX - what should we do here? Is it always
2085 * the case that there are no gaps, or are there
2086 * protcols using sequence numbers where there
2087 * can be gaps?
2088 *
2089 * If the former, the check below for having
2090 * received all the fragments should check for
2091 * holes in the sequence number space and for the
2092 * first sequence number being 0. If we do that,
2093 * the only way we can get here is if this fragment
2094 * is past the end of the sequence number space -
2095 * but the check for "fd->offset > fd_head->datalen"
2096 * would have caught that above, so it can't happen.
2097 *
2098 * If the latter, we don't have a good way of
2099 * knowing whether reassembly is complete if we
2100 * get packet out of order such that the "last"
2101 * fragment doesn't show up last - but, unless
2102 * in-order reliable delivery of fragments is
2103 * guaranteed, an implementation of the protocol
2104 * has no way of knowing whether reassembly is
2105 * complete, either.
2106 *
2107 * For now, we just link the fragment in and
2108 * return.
2109 */
2110 LINK_FRAG(fd_head,fd);
2111 return true1;
2112 }
2113 }
2114
2115 /* If we have reached this point, the packet is not defragmented yet.
2116 * Save all payload in a buffer until we can defragment.
2117 */
2118 /* check len, there may be a fragment with 0 len, that is actually the tail */
2119 if (fd->len) {
2120 if (!tvb_bytes_exist(tvb, offset, fd->len)) {
2121 /* abort if we didn't capture the entire fragment due
2122 * to a too-short snapshot length */
2123 g_slice_free(fragment_item, fd)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd)); else
(void) ((fragment_item*) 0 == (fd)); } while (0)
;
2124 return false0;
2125 }
2126
2127 fd->tvb_data = tvb_clone_offset_len(tvb, offset, fd->len);
2128 }
2129 LINK_FRAG(fd_head,fd);
2130
2131
2132 if( !(fd_head->flags & FD_DATALEN_SET0x0400) ){
2133 /* if we don't know the sequence number of the last fragment,
2134 * there are definitely still missing packets. Cheaper than
2135 * the check below.
2136 */
2137 return false0;
2138 }
2139
2140
2141 /* check if we have received the entire fragment
2142 * this is easy since the list is sorted and the head is faked.
2143 * common case the whole list is scanned.
2144 */
2145 max = 0;
2146 for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
2147 if ( fd_i->offset==max ){
2148 max++;
2149 }
2150 }
2151 /* max will now be datalen+1 if all fragments have been seen */
2152
2153 if (max <= fd_head->datalen) {
2154 /* we have not received all packets yet */
2155 return false0;
2156 }
2157
2158
2159 if (max > (fd_head->datalen+1)) {
2160 /* oops, too long fragment detected */
2161 fd->flags |= FD_TOOLONGFRAGMENT0x0010;
2162 fd_head->flags |= FD_TOOLONGFRAGMENT0x0010;
2163 }
2164
2165
2166 /* we have received an entire packet, defragment it and
2167 * free all fragments
2168 */
2169 fragment_defragment_and_free(fd_head, pinfo);
2170
2171 return true1;
2172}
2173
2174/*
2175 * This function adds a new fragment to the fragment hash table.
2176 * If this is the first fragment seen for this datagram, a new entry
2177 * is created in the hash table, otherwise this fragment is just added
2178 * to the linked list of fragments for this packet.
2179 *
2180 * Returns a pointer to the head of the fragment data list if we have all the
2181 * fragments, NULL otherwise.
2182 *
2183 * This function assumes frag_number being a block sequence number.
2184 * The bsn for the first block is 0.
2185 */
2186static fragment_head *
2187fragment_add_seq_common(reassembly_table *table, tvbuff_t *tvb,
2188 const int offset, const packet_info *pinfo,
2189 const uint32_t id, const void *data,
2190 uint32_t frag_number, const uint32_t frag_data_len,
2191 const bool_Bool more_frags, const uint32_t flags,
2192 void * *orig_keyp)
2193{
2194 fragment_head *fd_head;
2195 void *orig_key;
2196
2197 fd_head = lookup_fd_head(table, pinfo, id, data, &orig_key);
2198
2199 /* have we already seen this frame ?*/
2200 if (pinfo->fd->visited) {
2201 if (fd_head != NULL((void*)0) && fd_head->flags & FD_DEFRAGMENTED0x0001) {
2202 if (orig_keyp != NULL((void*)0))
2203 *orig_keyp = orig_key;
2204 return fd_head;
2205 } else {
2206 return NULL((void*)0);
2207 }
2208 }
2209
2210 if (fd_head==NULL((void*)0)){
2211 /* not found, this must be the first snooped fragment for this
2212 * packet. Create list-head.
2213 */
2214 fd_head= new_head(FD_BLOCKSEQUENCE0x0100);
2215
2216 if((flags & (REASSEMBLE_FLAGS_NO_FRAG_NUMBER0x0001|REASSEMBLE_FLAGS_802_11_HACK0x0002))
2217 && !more_frags) {
2218 /*
2219 * This is the last fragment for this packet, and
2220 * is the only one we've seen.
2221 *
2222 * Either we don't have sequence numbers, in which
2223 * case we assume this is the first fragment for
2224 * this packet, or we're doing special 802.11
2225 * processing, in which case we assume it's one
2226 * of those reassembled packets with a non-zero
2227 * fragment number (see packet-80211.c); just
2228 * return a pointer to the head of the list;
2229 * fragment_add_seq_check will then add it to the table
2230 * of reassembled packets.
2231 */
2232 if (orig_keyp != NULL((void*)0))
2233 *orig_keyp = NULL((void*)0);
2234 /* To save memory, we don't actually copy the
2235 * fragment from the tvbuff to the fragment, and in
2236 * process_reassembled_data just return back a subset
2237 * of the original tvbuff (which must be passed in).
2238 */
2239 fd_head->len = frag_data_len;
2240 fd_head->reassembled_in=pinfo->num;
2241 fd_head->reas_in_layer_num = pinfo->curr_layer_num;
2242 return fd_head;
2243 }
2244
2245 orig_key = insert_fd_head(table, fd_head, pinfo, id, data);
2246 if (orig_keyp != NULL((void*)0))
2247 *orig_keyp = orig_key;
2248
2249 /*
2250 * If we weren't given an initial fragment number,
2251 * make it 0.
2252 */
2253 if (flags & REASSEMBLE_FLAGS_NO_FRAG_NUMBER0x0001)
2254 frag_number = 0;
2255 } else {
2256 if (orig_keyp != NULL((void*)0))
2257 *orig_keyp = orig_key;
2258
2259 if (flags & REASSEMBLE_FLAGS_NO_FRAG_NUMBER0x0001) {
2260 fragment_item *fd;
2261 /*
2262 * If we weren't given an initial fragment number,
2263 * use the next expected fragment number as the fragment
2264 * number for this fragment.
2265 */
2266 for (fd = fd_head->next; fd != NULL((void*)0); fd = fd->next) {
2267 if (fd->next == NULL((void*)0))
2268 frag_number = fd->offset + 1;
2269 }
2270 }
2271 }
2272
2273 if (fragment_add_seq_work(fd_head, tvb, offset, pinfo,
2274 frag_number, frag_data_len, more_frags)) {
2275 /*
2276 * Reassembly is complete.
2277 */
2278 return fd_head;
2279 } else {
2280 /*
2281 * Reassembly isn't complete.
2282 */
2283 return NULL((void*)0);
2284 }
2285}
2286
2287fragment_head *
2288fragment_add_seq(reassembly_table *table, tvbuff_t *tvb, const int offset,
2289 const packet_info *pinfo, const uint32_t id, const void *data,
2290 const uint32_t frag_number, const uint32_t frag_data_len,
2291 const bool_Bool more_frags, const uint32_t flags)
2292{
2293 return fragment_add_seq_common(table, tvb, offset, pinfo, id, data,
2294 frag_number, frag_data_len,
2295 more_frags, flags, NULL((void*)0));
2296}
2297
2298/*
2299 * This does the work for "fragment_add_seq_check()" and
2300 * "fragment_add_seq_next()".
2301 *
2302 * This function assumes frag_number being a block sequence number.
2303 * The bsn for the first block is 0.
2304 *
2305 * If REASSEMBLE_FLAGS_NO_FRAG_NUMBER, it uses the next expected fragment number
2306 * as the fragment number if there is a reassembly in progress, otherwise
2307 * it uses 0.
2308 *
2309 * If not REASSEMBLE_FLAGS_NO_FRAG_NUMBER, it uses the "frag_number" argument as
2310 * the fragment number.
2311 *
2312 * If this is the first fragment seen for this datagram, a new
2313 * "fragment_head" structure is allocated to refer to the reassembled
2314 * packet.
2315 *
2316 * This fragment is added to the linked list of fragments for this packet.
2317 *
2318 * If "more_frags" is false and REASSEMBLE_FLAGS_802_11_HACK (as the name
2319 * implies, a special hack for 802.11) or REASSEMBLE_FLAGS_NO_FRAG_NUMBER
2320 * (implying messages must be in order since there's no sequence number) are
2321 * set in "flags", then this (one element) list is returned.
2322 *
2323 * If, after processing this fragment, we have all the fragments,
2324 * "fragment_add_seq_check_work()" removes that from the fragment hash
2325 * table if necessary and adds it to the table of reassembled fragments,
2326 * and returns a pointer to the head of the fragment list.
2327 *
2328 * Otherwise, it returns NULL.
2329 *
2330 * XXX - Should we simply return NULL for zero-length fragments?
2331 */
2332static fragment_head *
2333fragment_add_seq_check_work(reassembly_table *table, tvbuff_t *tvb,
2334 const int offset, const packet_info *pinfo,
2335 const uint32_t id, const void *data,
2336 const uint32_t frag_number,
2337 const uint32_t frag_data_len,
2338 const bool_Bool more_frags, const uint32_t flags)
2339{
2340 reassembled_key reass_key;
2341 fragment_head *fd_head;
2342 void *orig_key;
2343
2344 /*
2345 * Have we already seen this frame?
2346 * If so, look for it in the table of reassembled packets.
2347 */
2348 if (pinfo->fd->visited) {
2349 reass_key.frame = pinfo->num;
2350 reass_key.id = id;
2351 return (fragment_head *)g_hash_table_lookup(table->reassembled_table, &reass_key);
2352 }
2353
2354 fd_head = fragment_add_seq_common(table, tvb, offset, pinfo, id, data,
2355 frag_number, frag_data_len,
2356 more_frags,
2357 flags,
2358 &orig_key);
2359 if (fd_head) {
2360 /*
2361 * Reassembly is complete.
2362 *
2363 * If this is in the table of in-progress reassemblies,
2364 * remove it from that table. (It could be that this
2365 * was the first and last fragment, so that no
2366 * reassembly was done.)
2367 */
2368 if (orig_key != NULL((void*)0))
2369 fragment_unhash(table, orig_key);
2370
2371 /*
2372 * Add this item to the table of reassembled packets.
2373 */
2374 fragment_reassembled(table, fd_head, pinfo, id);
2375 return fd_head;
2376 } else {
2377 /*
2378 * Reassembly isn't complete.
2379 */
2380 return NULL((void*)0);
2381 }
2382}
2383
2384fragment_head *
2385fragment_add_seq_check(reassembly_table *table, tvbuff_t *tvb, const int offset,
2386 const packet_info *pinfo, const uint32_t id,
2387 const void *data,
2388 const uint32_t frag_number, const uint32_t frag_data_len,
2389 const bool_Bool more_frags)
2390{
2391 return fragment_add_seq_check_work(table, tvb, offset, pinfo, id, data,
2392 frag_number, frag_data_len,
2393 more_frags, 0);
2394}
2395
2396fragment_head *
2397fragment_add_seq_802_11(reassembly_table *table, tvbuff_t *tvb,
2398 const int offset, const packet_info *pinfo,
2399 const uint32_t id, const void *data,
2400 const uint32_t frag_number, const uint32_t frag_data_len,
2401 const bool_Bool more_frags)
2402{
2403 return fragment_add_seq_check_work(table, tvb, offset, pinfo, id, data,
2404 frag_number, frag_data_len,
2405 more_frags,
2406 REASSEMBLE_FLAGS_802_11_HACK0x0002);
2407}
2408
2409fragment_head *
2410fragment_add_seq_next(reassembly_table *table, tvbuff_t *tvb, const int offset,
2411 const packet_info *pinfo, const uint32_t id,
2412 const void *data, const uint32_t frag_data_len,
2413 const bool_Bool more_frags)
2414{
2415 /* Use a dummy frag_number (0), it is ignored since
2416 * REASSEMBLE_FLAGS_NO_FRAG_NUMBER is set. */
2417 return fragment_add_seq_check_work(table, tvb, offset, pinfo, id, data,
2418 0, frag_data_len, more_frags,
2419 REASSEMBLE_FLAGS_NO_FRAG_NUMBER0x0001);
2420}
2421
2422static void
2423fragment_add_seq_single_move(reassembly_table *table, const packet_info *pinfo,
2424 const uint32_t id, const void *data,
2425 const uint32_t offset)
2426{
2427 fragment_head *fh, *new_fh;
2428 fragment_item *fd, *prev_fd;
2429 tvbuff_t *old_tvb_data;
2430 if (offset == 0) {
2431 return;
2432 }
2433 fh = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
2434 if (fh == NULL((void*)0)) {
2435 /* Shouldn't be called this way.
2436 * Probably wouldn't hurt to just create fh in this case. */
2437 ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "epan/reassemble.c", 2437
, __func__, "assertion \"not reached\" failed")
;
2438 return;
2439 }
2440 if (fh->flags & FD_DATALEN_SET0x0400 && fh->datalen <= offset) {
2441 /* Don't take from past the end. <= because we don't
2442 * want to take a First fragment from the next one
2443 * either */
2444 return;
2445 }
2446 new_fh = lookup_fd_head(table, pinfo, id+offset, data, NULL((void*)0));
2447 if (new_fh != NULL((void*)0)) {
2448 /* Attach to the end of the sorted list. */
2449 prev_fd = NULL((void*)0);
2450 for(fd = fh->next; fd != NULL((void*)0); fd=fd->next) {
2451 prev_fd = fd;
2452 }
2453 /* Don't take a reassembly starting with a First fragment. */
2454 fd = new_fh->next;
2455 if (fd && fd->offset != 0) {
2456 fragment_item *inserted = fd;
2457 bool_Bool multi_insert = (inserted->next != NULL((void*)0));
2458 if (prev_fd) {
2459 prev_fd->next = fd;
2460 } else {
2461 fh->next = fd;
2462 }
2463 for (; fd; fd=fd->next) {
2464 fd->offset += offset;
2465 if (fh->frame < fd->frame) {
2466 fh->frame = fd->frame;
2467 }
2468 }
2469 update_first_gap(fh, inserted, multi_insert);
2470 /* If previously found a Last fragment,
2471 * transfer that info to the new one. */
2472 if (new_fh->flags & FD_DATALEN_SET0x0400) {
2473 fh->flags |= FD_DATALEN_SET0x0400;
2474 fh->datalen = new_fh->datalen + offset;
2475 }
2476 /* Now remove and delete */
2477 new_fh->next = NULL((void*)0);
2478 old_tvb_data = fragment_delete(table, pinfo, id+offset, data);
2479 if (old_tvb_data)
2480 tvb_free(old_tvb_data);
2481 }
2482 }
2483}
2484
2485static fragment_head *
2486fragment_add_seq_single_work(reassembly_table *table, tvbuff_t *tvb,
2487 const int offset, const packet_info *pinfo,
2488 const uint32_t id, const void* data,
2489 const uint32_t frag_data_len,
2490 const bool_Bool first, const bool_Bool last,
2491 const uint32_t max_frags, const uint32_t max_age,
2492 const uint32_t flags)
2493{
2494 reassembled_key reass_key;
2495 tvbuff_t *old_tvb_data;
2496 void *orig_key;
2497 fragment_head *fh, *new_fh;
2498 fragment_item *fd, *prev_fd;
2499 uint32_t frag_number, tmp_offset;
2500 /* Have we already seen this frame?
2501 * If so, look for it in the table of reassembled packets.
2502 * Note here we store in the reassembly table by the single sequence
2503 * number rather than the sequence number of the First fragment. */
2504 if (pinfo->fd->visited) {
2505 reass_key.frame = pinfo->num;
2506 reass_key.id = id;
2507 fh = (fragment_head *)g_hash_table_lookup(table->reassembled_table, &reass_key);
2508 return fh;
2509 }
2510 /* First let's figure out where we want to add our new fragment */
2511 fh = NULL((void*)0);
2512 if (first) {
2513 frag_number = 0;
2514 fh = lookup_fd_head(table, pinfo, id-frag_number, data, NULL((void*)0));
2515 if ((flags & REASSEMBLE_FLAGS_AGING0x0001) &&
2516 fh && ((fh->frame + max_age) < pinfo->num)) {
2517 old_tvb_data = fragment_delete(table, pinfo, id-frag_number, data);
2518 if (old_tvb_data)
2519 tvb_free(old_tvb_data);
2520 fh = NULL((void*)0);
2521 }
2522 if (fh == NULL((void*)0)) {
2523 /* Not found. Create list-head. */
2524 fh = new_head(FD_BLOCKSEQUENCE0x0100);
2525 insert_fd_head(table, fh, pinfo, id-frag_number, data);
2526 }
2527 /* As this is the first fragment, we might have added segments
2528 * for this reassembly to the previous one in-progress. */
2529 fd = NULL((void*)0);
2530 for (frag_number=1; frag_number < max_frags; frag_number++) {
2531 new_fh = lookup_fd_head(table, pinfo, id-frag_number, data, NULL((void*)0));
2532 if (new_fh != NULL((void*)0)) {
2533 prev_fd = NULL((void*)0);
2534 new_fh->frame = 0;
2535 for (fd=new_fh->next; fd && fd->offset < frag_number; fd=fd->next) {
2536 prev_fd = fd;
2537 if (new_fh->frame < fd->frame) {
2538 new_fh->frame = fd->frame;
2539 }
2540 }
2541 if (prev_fd) {
2542 prev_fd->next = NULL((void*)0);
2543 } else {
2544 new_fh->next = NULL((void*)0);
2545 }
2546 fragment_items_removed(new_fh, prev_fd);
2547 break;
2548 }
2549 }
2550 if (fd != NULL((void*)0)) {
2551 tmp_offset = 0;
2552 for (prev_fd = fd; prev_fd; prev_fd = prev_fd->next) {
2553 prev_fd->offset -= frag_number;
2554 tmp_offset = prev_fd->offset;
2555 if (fh->frame < prev_fd->frame) {
2556 fh->frame = prev_fd->frame;
2557 }
2558 }
2559 MERGE_FRAG(fh, fd);
2560 if (new_fh != NULL((void*)0)) {
2561 /* If we've moved a Last packet, change datalen.
2562 * Second part of this test prob. redundant? */
2563 if (new_fh->flags & FD_DATALEN_SET0x0400 &&
2564 new_fh->datalen >= frag_number) {
2565 fh->flags |= FD_DATALEN_SET0x0400;
2566 fh->datalen = new_fh->datalen - frag_number;
2567 new_fh->flags &= ~FD_DATALEN_SET0x0400;
2568 new_fh->datalen = 0;
2569 }
2570 /* If we've moved all the fragments,
2571 * delete the old head */
2572 if (new_fh->next == NULL((void*)0)) {
2573 old_tvb_data = fragment_delete(table, pinfo, id-frag_number, data);
2574 if (old_tvb_data)
2575 tvb_free(old_tvb_data);
2576 }
2577 } else {
2578 /* Look forward and take off the next (this is
2579 * necessary in some edge cases where max_frags
2580 * prevented some fragments from going on the
2581 * previous First, but they can go on this one. */
2582 fragment_add_seq_single_move(table, pinfo, id,
2583 data, tmp_offset);
2584 }
2585 }
2586 frag_number = 0; /* For the rest of the function */
2587 } else {
2588 for (frag_number=1; frag_number < max_frags; frag_number++) {
2589 fh = lookup_fd_head(table, pinfo, id-frag_number, data, NULL((void*)0));
2590 if ((flags & REASSEMBLE_FLAGS_AGING0x0001) &&
2591 fh && ((fh->frame + max_age) < pinfo->num)) {
2592 old_tvb_data = fragment_delete(table, pinfo, id-frag_number, data);
2593 if (old_tvb_data)
2594 tvb_free(old_tvb_data);
2595 fh = NULL((void*)0);
2596 }
2597 if (fh != NULL((void*)0)) {
2598 if (fh->flags & FD_DATALEN_SET0x0400 &&
2599 fh->datalen < frag_number) {
2600 /* This fragment is after the Last
2601 * fragment, so must go after here. */
2602 fh = NULL((void*)0);
2603 }
2604 break;
2605 }
2606 }
2607 if (fh == NULL((void*)0)) { /* Didn't find location, use default */
2608 frag_number = 1;
2609 /* Already looked for frag_number 1, so just create */
2610 fh = new_head(FD_BLOCKSEQUENCE0x0100);
2611 insert_fd_head(table, fh, pinfo, id-frag_number, data);
2612 }
2613 }
2614 if (last) {
2615 /* Look for fragments past the end set by this Last fragment. */
2616 prev_fd = NULL((void*)0);
2617 for (fd=fh->next; fd && fd->offset <= frag_number; fd=fd->next) {
2618 prev_fd = fd;
2619 }
2620 /* fd is now all fragments offset > frag_number (the Last).
2621 * It shouldn't have a fragment with offset frag_number+1,
2622 * as that would be a First fragment not marked as such.
2623 * However, this can happen if we had unreassembled fragments
2624 * (missing, or at the start of the capture) and we've also
2625 * looped around on the sequence numbers. It can also happen
2626 * if bit errors mess up Last or First. */
2627 if (fd != NULL((void*)0)) {
2628 if (prev_fd) {
2629 prev_fd->next = NULL((void*)0);
2630 } else {
2631 fh->next = NULL((void*)0);
2632 }
2633 fragment_items_removed(fh, prev_fd);
2634 fh->frame = 0;
2635 for (prev_fd=fh->next; prev_fd; prev_fd=prev_fd->next) {
2636 if (fh->frame < prev_fd->frame) {
2637 fh->frame = prev_fd->frame;
2638 }
2639 }
2640 while (fd && fd->offset == frag_number+1) {
2641 /* Definitely have bad data here. Best to
2642 * delete these and leave unreassembled. */
2643 fragment_item *tmp_fd;
2644 tmp_fd=fd->next;
2645
2646 if (fd->tvb_data && !(fd->flags & FD_SUBSET_TVB0x0020))
2647 tvb_free(fd->tvb_data);
2648 g_slice_free(fragment_item, fd)do { if (1) g_slice_free1 (sizeof (fragment_item), (fd)); else
(void) ((fragment_item*) 0 == (fd)); } while (0)
;
2649 fd=tmp_fd;
2650 }
2651 }
2652 if (fd != NULL((void*)0)) {
2653 /* Move these onto the next frame. */
2654 new_fh = lookup_fd_head(table, pinfo, id+1, data, NULL((void*)0));
2655 if (new_fh==NULL((void*)0)) {
2656 /* Not found. Create list-head. */
2657 new_fh = new_head(FD_BLOCKSEQUENCE0x0100);
2658 insert_fd_head(table, new_fh, pinfo, id+1, data);
2659 }
2660 tmp_offset = 0;
2661 for (prev_fd = fd; prev_fd; prev_fd = prev_fd->next) {
2662 prev_fd->offset -= (frag_number+1);
2663 tmp_offset = prev_fd->offset;
2664 if (new_fh->frame < fd->frame) {
2665 new_fh->frame = fd->frame;
2666 }
2667 }
2668 MERGE_FRAG(new_fh, fd);
2669 /* If we previously found a different Last fragment,
2670 * transfer that information to the new reassembly. */
2671 if (fh->flags & FD_DATALEN_SET0x0400 &&
2672 fh->datalen > frag_number) {
2673 new_fh->flags |= FD_DATALEN_SET0x0400;
2674 new_fh->datalen = fh->datalen - (frag_number+1);
2675 fh->flags &= ~FD_DATALEN_SET0x0400;
2676 fh->datalen = 0;
2677 } else {
2678 /* Look forward and take off the next (this is
2679 * necessary in some edge cases where max_frags
2680 * prevented some fragments from going on the
2681 * previous First, but they can go on this one. */
2682 fragment_add_seq_single_move(table, pinfo, id+1,
2683 data, tmp_offset);
2684 }
2685 }
2686 } else {
2687 fragment_add_seq_single_move(table, pinfo, id-frag_number, data,
2688 frag_number+1);
2689 }
2690 /* Having cleaned up everything, finally ready to add our new
2691 * fragment. Note that only this will ever complete a reassembly. */
2692 fh = fragment_add_seq_common(table, tvb, offset, pinfo,
2693 id-frag_number, data,
2694 frag_number, frag_data_len,
2695 !last, 0, &orig_key);
2696 if (fh) {
2697 /*
2698 * Reassembly is complete.
2699 *
2700 * If this is in the table of in-progress reassemblies,
2701 * remove it from that table. (It could be that this
2702 * was the first and last fragment, so that no
2703 * reassembly was done.)
2704 */
2705 if (orig_key != NULL((void*)0))
2706 fragment_unhash(table, orig_key);
2707
2708 /*
2709 * Add this item to the table of reassembled packets.
2710 */
2711 fragment_reassembled_single(table, fh, pinfo, id-frag_number);
2712 return fh;
2713 } else {
2714 /*
2715 * Reassembly isn't complete.
2716 */
2717 return NULL((void*)0);
2718 }
2719}
2720
2721fragment_head *
2722fragment_add_seq_single(reassembly_table *table, tvbuff_t *tvb,
2723 const int offset, const packet_info *pinfo,
2724 const uint32_t id, const void* data,
2725 const uint32_t frag_data_len,
2726 const bool_Bool first, const bool_Bool last,
2727 const uint32_t max_frags)
2728{
2729 return fragment_add_seq_single_work(table, tvb, offset, pinfo,
2730 id, data, frag_data_len,
2731 first, last, max_frags, 0, 0);
2732}
2733
2734fragment_head *
2735fragment_add_seq_single_aging(reassembly_table *table, tvbuff_t *tvb,
2736 const int offset, const packet_info *pinfo,
2737 const uint32_t id, const void* data,
2738 const uint32_t frag_data_len,
2739 const bool_Bool first, const bool_Bool last,
2740 const uint32_t max_frags, const uint32_t max_age)
2741{
2742 return fragment_add_seq_single_work(table, tvb, offset, pinfo,
2743 id, data, frag_data_len,
2744 first, last, max_frags, max_age,
2745 REASSEMBLE_FLAGS_AGING0x0001);
2746}
2747
2748void
2749fragment_start_seq_check(reassembly_table *table, const packet_info *pinfo,
2750 const uint32_t id, const void *data,
2751 const uint32_t tot_len)
2752{
2753 fragment_head *fd_head;
2754
2755 /* Have we already seen this frame ?*/
2756 if (pinfo->fd->visited) {
2757 return;
2758 }
2759
2760 /* Check if fragment data exists */
2761 fd_head = lookup_fd_head(table, pinfo, id, data, NULL((void*)0));
2762
2763 if (fd_head == NULL((void*)0)) {
2764 /* Create list-head. */
2765 fd_head = g_slice_new(fragment_head)((fragment_head*) g_slice_alloc (sizeof (fragment_head)));
2766 fd_head->next = NULL((void*)0);
2767 fd_head->first_gap = NULL((void*)0);
2768 fd_head->contiguous_len = 0;
2769 fd_head->frame = 0;
2770 fd_head->len = 0;
2771 fd_head->fragment_nr_offset = 0;
2772 fd_head->datalen = tot_len;
2773 fd_head->reassembled_in = 0;
2774 fd_head->reas_in_layer_num = 0;
2775 fd_head->flags = FD_BLOCKSEQUENCE0x0100|FD_DATALEN_SET0x0400;
2776 fd_head->tvb_data = NULL((void*)0);
2777 fd_head->error = NULL((void*)0);
2778
2779 insert_fd_head(table, fd_head, pinfo, id, data);
2780 }
2781}
2782
2783fragment_head *
2784fragment_end_seq_next(reassembly_table *table, const packet_info *pinfo,
2785 const uint32_t id, const void *data)
2786{
2787 reassembled_key reass_key;
2788 reassembled_key *new_key;
2789 fragment_head *fd_head;
2790 fragment_item *fd;
2791 void *orig_key;
2792 uint32_t max_offset = 0;
2793
2794 /*
2795 * Have we already seen this frame?
2796 * If so, look for it in the table of reassembled packets.
2797 */
2798 if (pinfo->fd->visited) {
2799 reass_key.frame = pinfo->num;
2800 reass_key.id = id;
2801 return (fragment_head *)g_hash_table_lookup(table->reassembled_table, &reass_key);
2802 }
2803
2804 fd_head = lookup_fd_head(table, pinfo, id, data, &orig_key);
2805
2806 if (fd_head) {
2807 for (fd = fd_head->next; fd; fd = fd->next) {
2808 if (fd->offset > max_offset) {
2809 max_offset = fd->offset;
2810 }
2811 }
2812 fd_head->datalen = max_offset;
2813 fd_head->flags |= FD_DATALEN_SET0x0400;
2814
2815 fragment_defragment_and_free (fd_head, pinfo);
2816
2817 /*
2818 * Remove this from the table of in-progress reassemblies,
2819 * and free up any memory used for it in that table.
2820 */
2821 fragment_unhash(table, orig_key);
2822
2823 /*
2824 * Add this item to the table of reassembled packets.
2825 */
2826 fragment_reassembled(table, fd_head, pinfo, id);
2827 if (fd_head->next != NULL((void*)0)) {
2828 new_key = g_slice_new(reassembled_key)((reassembled_key*) g_slice_alloc (sizeof (reassembled_key)));
2829 new_key->frame = pinfo->num;
2830 new_key->id = id;
2831 reassembled_table_insert(table->reassembled_table, new_key, fd_head);
2832 }
2833
2834 return fd_head;
2835 } else {
2836 /*
2837 * Fragment data not found.
2838 */
2839 return NULL((void*)0);
2840 }
2841}
2842
2843/*
2844 * Process reassembled data; if we're on the frame in which the data
2845 * was reassembled, put the fragment information into the protocol
2846 * tree, and construct a tvbuff with the reassembled data, otherwise
2847 * just put a "reassembled in" item into the protocol tree.
2848 * offset from start of tvb, result up to end of tvb
2849 */
2850tvbuff_t *
2851process_reassembled_data(tvbuff_t *tvb, const int offset, packet_info *pinfo,
2852 const char *name, fragment_head *fd_head, const fragment_items *fit,
2853 bool_Bool *update_col_infop, proto_tree *tree)
2854{
2855 tvbuff_t *next_tvb;
2856 bool_Bool update_col_info;
2857 proto_item *frag_tree_item;
2858
2859 if (fd_head != NULL((void*)0) && pinfo->num == fd_head->reassembled_in && pinfo->curr_layer_num == fd_head->reas_in_layer_num) {
2860 /*
2861 * OK, we've reassembled this.
2862 * Is this something that's been reassembled from more
2863 * than one fragment?
2864 */
2865 if (fd_head->next != NULL((void*)0)) {
2866 /*
2867 * Yes.
2868 * Allocate a new tvbuff, referring to the
2869 * reassembled payload, and set
2870 * the tvbuff to the list of tvbuffs to which
2871 * the tvbuff we were handed refers, so it'll get
2872 * cleaned up when that tvbuff is cleaned up.
2873 */
2874 next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
2875
2876 /* Add the defragmented data to the data source list. */
2877 add_new_data_source(pinfo, next_tvb, name);
2878
2879 /* show all fragments */
2880 if (fd_head->flags & FD_BLOCKSEQUENCE0x0100) {
2881 update_col_info = !show_fragment_seq_tree(
2882 fd_head, fit, tree, pinfo, next_tvb, &frag_tree_item);
2883 } else {
2884 update_col_info = !show_fragment_tree(fd_head,
2885 fit, tree, pinfo, next_tvb, &frag_tree_item);
2886 }
2887 } else {
2888 /*
2889 * No.
2890 * Return a tvbuff with the payload, a subset of the
2891 * tvbuff passed in. (The dissector SHOULD pass in
2892 * the correct tvbuff and offset.)
2893 */
2894 int len;
2895 /* For FD_BLOCKSEQUENCE, len is the length in bytes,
2896 * datalen is the number of fragments.
2897 */
2898 if (fd_head->flags & FD_BLOCKSEQUENCE0x0100) {
2899 len = fd_head->len;
2900 } else {
2901 // XXX Do the non-seq functions have this optimization?
2902 len = fd_head->datalen;
2903 }
2904 next_tvb = tvb_new_subset_length(tvb, offset, len);
2905 pinfo->fragmented = false0; /* one-fragment packet */
2906 update_col_info = true1;
2907 }
2908 if (update_col_infop != NULL((void*)0))
2909 *update_col_infop = update_col_info;
2910 } else {
2911 /*
2912 * We don't have the complete reassembled payload, or this
2913 * isn't the final frame of that payload.
2914 */
2915 next_tvb = NULL((void*)0);
2916
2917 /*
2918 * If we know what frame this was reassembled in,
2919 * and if there's a field to use for the number of
2920 * the frame in which the packet was reassembled,
2921 * add it to the protocol tree.
2922 */
2923 if (fd_head != NULL((void*)0) && fit->hf_reassembled_in != NULL((void*)0)) {
2924 proto_item *fei = proto_tree_add_uint(tree,
2925 *(fit->hf_reassembled_in), tvb,
2926 0, 0, fd_head->reassembled_in);
2927 proto_item_set_generated(fei);
2928 }
2929 }
2930 return next_tvb;
2931}
2932
2933/*
2934 * Show a single fragment in a fragment subtree, and put information about
2935 * it in the top-level item for that subtree.
2936 */
2937static void
2938show_fragment(fragment_item *fd, const int offset, const fragment_items *fit,
2939 proto_tree *ft, proto_item *fi, const bool_Bool first_frag,
2940 const uint32_t count, tvbuff_t *tvb, packet_info *pinfo)
2941{
2942 proto_item *fei=NULL((void*)0);
2943 int hf;
2944
2945 if (first_frag) {
2946 char *name;
2947 if (count == 1) {
2948 name = g_strdup(proto_registrar_get_name(*(fit->hf_fragment)))g_strdup_inline (proto_registrar_get_name(*(fit->hf_fragment
)))
;
2949 } else {
2950 name = g_strdup(proto_registrar_get_name(*(fit->hf_fragments)))g_strdup_inline (proto_registrar_get_name(*(fit->hf_fragments
)))
;
2951 }
2952 proto_item_set_text(fi, "%u %s (%u byte%s): ", count, name, tvb_captured_length(tvb),
2953 plurality(tvb_captured_length(tvb), "", "s")((tvb_captured_length(tvb)) == 1 ? ("") : ("s")));
2954 g_free(name);
2955 } else {
2956 proto_item_append_text(fi, ", ");
2957 }
2958 proto_item_append_text(fi, "#%u(%u)", fd->frame, fd->len);
2959
2960 if (fd->flags & (FD_OVERLAPCONFLICT0x0004
2961 |FD_MULTIPLETAILS0x0008|FD_TOOLONGFRAGMENT0x0010) ) {
2962 hf = *(fit->hf_fragment_error);
2963 } else {
2964 hf = *(fit->hf_fragment);
2965 }
2966 if (fd->len == 0) {
2967 fei = proto_tree_add_uint_format(ft, hf,
2968 tvb, offset, fd->len,
2969 fd->frame,
2970 "Frame: %u (no data)",
2971 fd->frame);
2972 } else {
2973 fei = proto_tree_add_uint_format(ft, hf,
2974 tvb, offset, fd->len,
2975 fd->frame,
2976 "Frame: %u, payload: %u-%u (%u byte%s)",
2977 fd->frame,
2978 offset,
2979 offset+fd->len-1,
2980 fd->len,
2981 plurality(fd->len, "", "s")((fd->len) == 1 ? ("") : ("s")));
2982 }
2983 proto_item_set_generated(fei);
2984 mark_frame_as_depended_upon(pinfo->fd, fd->frame);
2985 if (fd->flags & (FD_OVERLAP0x0002|FD_OVERLAPCONFLICT0x0004
2986 |FD_MULTIPLETAILS0x0008|FD_TOOLONGFRAGMENT0x0010) ) {
2987 /* this fragment has some flags set, create a subtree
2988 * for it and display the flags.
2989 */
2990 proto_tree *fet=NULL((void*)0);
2991
2992 fet = proto_item_add_subtree(fei, *(fit->ett_fragment));
2993 if (fd->flags&FD_OVERLAP0x0002) {
2994 fei=proto_tree_add_boolean(fet,
2995 *(fit->hf_fragment_overlap),
2996 tvb, 0, 0,
2997 true1);
2998 proto_item_set_generated(fei);
2999 }
3000 if (fd->flags&FD_OVERLAPCONFLICT0x0004) {
3001 fei=proto_tree_add_boolean(fet,
3002 *(fit->hf_fragment_overlap_conflict),
3003 tvb, 0, 0,
3004 true1);
3005 proto_item_set_generated(fei);
3006 }
3007 if (fd->flags&FD_MULTIPLETAILS0x0008) {
3008 fei=proto_tree_add_boolean(fet,
3009 *(fit->hf_fragment_multiple_tails),
3010 tvb, 0, 0,
3011 true1);
3012 proto_item_set_generated(fei);
3013 }
3014 if (fd->flags&FD_TOOLONGFRAGMENT0x0010) {
3015 fei=proto_tree_add_boolean(fet,
3016 *(fit->hf_fragment_too_long_fragment),
3017 tvb, 0, 0,
3018 true1);
3019 proto_item_set_generated(fei);
3020 }
3021 }
3022}
3023
3024static bool_Bool
3025show_fragment_errs_in_col(fragment_head *fd_head, const fragment_items *fit,
3026 packet_info *pinfo)
3027{
3028 if (fd_head->flags & (FD_OVERLAPCONFLICT0x0004
3029 |FD_MULTIPLETAILS0x0008|FD_TOOLONGFRAGMENT0x0010) ) {
3030 col_add_fstr(pinfo->cinfo, COL_INFO, "[Illegal %s]", fit->tag);
3031 return true1;
3032 }
3033
3034 return false0;
3035}
3036
3037/* This function will build the fragment subtree; it's for fragments
3038 reassembled with "fragment_add()".
3039
3040 It will return true if there were fragmentation errors
3041 or false if fragmentation was ok.
3042*/
3043bool_Bool
3044show_fragment_tree(fragment_head *fd_head, const fragment_items *fit,
3045 proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, proto_item **fi)
3046{
3047 fragment_item *fd;
3048 proto_tree *ft;
3049 bool_Bool first_frag;
3050 uint32_t count = 0;
3051 /* It's not fragmented. */
3052 pinfo->fragmented = false0;
3053
3054 *fi = proto_tree_add_item(tree, *(fit->hf_fragments), tvb, 0, -1, ENC_NA0x00000000);
3055 proto_item_set_generated(*fi);
3056
3057 ft = proto_item_add_subtree(*fi, *(fit->ett_fragments));
3058 first_frag = true1;
3059 for (fd = fd_head->next; fd != NULL((void*)0); fd = fd->next) {
3060 count++;
3061 }
3062 for (fd = fd_head->next; fd != NULL((void*)0); fd = fd->next) {
3063 show_fragment(fd, fd->offset, fit, ft, *fi, first_frag, count, tvb, pinfo);
3064 first_frag = false0;
3065 }
3066
3067 if (fit->hf_fragment_count) {
3068 proto_item *fli = proto_tree_add_uint(ft, *(fit->hf_fragment_count),
3069 tvb, 0, 0, count);
3070 proto_item_set_generated(fli);
3071 }
3072
3073 if (fit->hf_reassembled_length) {
3074 proto_item *fli = proto_tree_add_uint(ft, *(fit->hf_reassembled_length),
3075 tvb, 0, 0, tvb_captured_length (tvb));
3076 proto_item_set_generated(fli);
3077 }
3078
3079 if (fit->hf_reassembled_data) {
3080 proto_item *fli = proto_tree_add_item(ft, *(fit->hf_reassembled_data),
3081 tvb, 0, tvb_captured_length(tvb), ENC_NA0x00000000);
3082 proto_item_set_generated(fli);
3083 }
3084
3085 return show_fragment_errs_in_col(fd_head, fit, pinfo);
3086}
3087
3088/* This function will build the fragment subtree; it's for fragments
3089 reassembled with "fragment_add_seq()" or "fragment_add_seq_check()".
3090
3091 It will return true if there were fragmentation errors
3092 or false if fragmentation was ok.
3093*/
3094bool_Bool
3095show_fragment_seq_tree(fragment_head *fd_head, const fragment_items *fit,
3096 proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, proto_item **fi)
3097{
3098 uint32_t offset, next_offset, count = 0;
3099 fragment_item *fd, *last_fd;
3100 proto_tree *ft;
3101 bool_Bool first_frag;
3102
3103 /* It's not fragmented. */
3104 pinfo->fragmented = false0;
3105
3106 *fi = proto_tree_add_item(tree, *(fit->hf_fragments), tvb, 0, -1, ENC_NA0x00000000);
3107 proto_item_set_generated(*fi);
3108
3109 ft = proto_item_add_subtree(*fi, *(fit->ett_fragments));
3110 offset = 0;
3111 next_offset = 0;
3112 last_fd = NULL((void*)0);
3113 first_frag = true1;
3114 for (fd = fd_head->next; fd != NULL((void*)0); fd = fd->next){
3115 count++;
3116 }
3117 for (fd = fd_head->next; fd != NULL((void*)0); fd = fd->next){
3118 if (last_fd == NULL((void*)0) || last_fd->offset != fd->offset) {
3119 offset = next_offset;
3120 next_offset += fd->len;
3121 }
3122 last_fd = fd;
3123 show_fragment(fd, offset, fit, ft, *fi, first_frag, count, tvb, pinfo);
3124 first_frag = false0;
3125 }
3126
3127 if (fit->hf_fragment_count) {
3128 proto_item *fli = proto_tree_add_uint(ft, *(fit->hf_fragment_count),
3129 tvb, 0, 0, count);
3130 proto_item_set_generated(fli);
3131 }
3132
3133 if (fit->hf_reassembled_length) {
3134 proto_item *fli = proto_tree_add_uint(ft, *(fit->hf_reassembled_length),
3135 tvb, 0, 0, tvb_captured_length (tvb));
3136 proto_item_set_generated(fli);
3137 }
3138
3139 if (fit->hf_reassembled_data) {
3140 proto_item *fli = proto_tree_add_item(ft, *(fit->hf_reassembled_data),
3141 tvb, 0, tvb_captured_length(tvb), ENC_NA0x00000000);
3142 proto_item_set_generated(fli);
3143 }
3144
3145 return show_fragment_errs_in_col(fd_head, fit, pinfo);
3146}
3147
3148static void
3149reassembly_table_init_reg_table(void *p, void *user_data _U___attribute__((unused)))
3150{
3151 register_reassembly_table_t* reg_table = (register_reassembly_table_t*)p;
3152 reassembly_table_init(reg_table->table, reg_table->funcs);
3153}
3154
3155static void
3156reassembly_table_init_reg_tables(void)
3157{
3158 g_list_foreach(reassembly_table_list, reassembly_table_init_reg_table, NULL((void*)0));
3159}
3160
3161static void
3162reassembly_table_cleanup_reg_table(void *p, void *user_data _U___attribute__((unused)))
3163{
3164 register_reassembly_table_t* reg_table = (register_reassembly_table_t*)p;
3165 reassembly_table_destroy(reg_table->table);
3166}
3167
3168static void
3169reassembly_table_cleanup_reg_tables(void)
3170{
3171 g_list_foreach(reassembly_table_list, reassembly_table_cleanup_reg_table, NULL((void*)0));
3172}
3173
3174void reassembly_tables_init(void)
3175{
3176 register_init_routine(&reassembly_table_init_reg_tables);
3177 register_cleanup_routine(&reassembly_table_cleanup_reg_tables);
3178}
3179
3180static void
3181reassembly_table_free(void *p, void *user_data _U___attribute__((unused)))
3182{
3183 register_reassembly_table_t* reg_table = (register_reassembly_table_t*)p;
3184 reassembly_table_destroy(reg_table->table);
3185 g_free(reg_table);
3186}
3187
3188void
3189reassembly_table_cleanup(void)
3190{
3191 g_list_foreach(reassembly_table_list, reassembly_table_free, NULL((void*)0));
3192 g_list_free(reassembly_table_list);
3193}
3194
3195/* One instance of this structure is created for each pdu that spans across
3196 * multiple segments. (MSP) */
3197typedef struct _multisegment_pdu_t {
3198 uint64_t first_frame;
3199 uint64_t last_frame;
3200 unsigned start_offset_at_first_frame;
3201 unsigned end_offset_at_last_frame;
3202 int length; /* length of this MSP */
3203 uint32_t streaming_reassembly_id;
3204 /* pointer to previous multisegment_pdu */
3205 struct _multisegment_pdu_t* prev_msp;
3206} multisegment_pdu_t;
3207
3208/* struct for keeping the reassembly information of each stream */
3209struct streaming_reassembly_info_t {
3210 /* This map is keyed by frame num and keeps track of all MSPs for this
3211 * stream. Different frames will point to the same MSP if they contain
3212 * part data of this MSP. If a frame contains data that
3213 * belongs to two MSPs, it will point to the second MSP. */
3214 wmem_map_t* multisegment_pdus;
3215 /* This map is keyed by frame num and keeps track of the frag_offset
3216 * of the first byte of frames for fragment_add() after first scan. */
3217 wmem_map_t* frame_num_frag_offset_map;
3218 /* how many bytes the current uncompleted MSP still needs. (only valid for first scan) */
3219 int prev_deseg_len;
3220 /* the current uncompleted MSP (only valid for first scan) */
3221 multisegment_pdu_t* last_msp;
3222};
3223
3224static uint32_t
3225create_streaming_reassembly_id(void)
3226{
3227 static uint32_t global_streaming_reassembly_id = 0;
3228 return ++global_streaming_reassembly_id;
3229}
3230
3231streaming_reassembly_info_t*
3232streaming_reassembly_info_new(void)
3233{
3234 return wmem_new0(wmem_file_scope(), streaming_reassembly_info_t)((streaming_reassembly_info_t*)wmem_alloc0((wmem_file_scope()
), sizeof(streaming_reassembly_info_t)))
;
3235}
3236
3237/* Following is an example of ProtoA and ProtoB protocols from the declaration of this function in 'reassemble.h':
3238 *
3239 * +------------------ A Multisegment PDU of ProtoB ----------------------+
3240 * | |
3241 * +--- ProtoA payload1 ---+ +- payload2 -+ +- Payload3 -+ +- Payload4 -+ +- ProtoA payload5 -+
3242 * | EoMSP | OmNFP | BoMSP | | MoMSP | | MoMSP | | MoMSP | | EoMSP | BoMSP |
3243 * +-------+-------+-------+ +------------+ +------------+ +------------+ +---------+---------+
3244 * | |
3245 * +----------------------------------------------------------------------+
3246 *
3247 * For a ProtoA payload composed of EoMSP + OmNFP + BoMSP will call fragment_add() twice on EoMSP and BoMSP; and call
3248 * process_reassembled_data() once for generating tvb of a MSP to which EoMSP belongs; and call subdissector twice on
3249 * reassembled MSP of EoMSP and OmNFP + BoMSP. After that finds BoMSP is a beginning of a MSP at first scan.
3250 *
3251 * The rules are:
3252 *
3253 * - If a ProtoA payload contains EoMSP, we will need call fragment_add(), process_reassembled_data() and subdissector
3254 * once on it to end a MSP. (May run twice or more times at first scan, because subdissector may only return the
3255 * head length of message by pinfo->desegment_len. We need run second time for subdissector to determine the length
3256 * of entire message).
3257 *
3258 * - If a ProtoA payload contains OmNFP, we will need only call subdissector once on it. The subdissector need dissect
3259 * all non-fragment PDUs in it. (no desegment_len should output)
3260 *
3261 * - If a ProtoA payload contains BoMSP, we will need call subdissector once on BoMSP or OmNFP+BoMSP (because unknown
3262 * during first scan). The subdissector will output desegment_len (!= 0). Then we will call fragment_add()
3263 * with a new reassembly id on BoMSP for starting a new MSP.
3264 *
3265 * - If a ProtoA payload only contains MoMSP (entire payload is part of a MSP), we will only call fragment_add() once
3266 * or twice (at first scan) on it. The subdissector will not be called.
3267 *
3268 * In this implementation, only multisegment PDUs are recorded in multisegment_pdus map keyed by the numbers (uint64_t)
3269 * of frames belongs to MSPs. Each MSP in the map has a pointer referred to previous MSP, because we may need
3270 * two MSPs to dissect a ProtoA payload that contains EoMSP + BoMSP at the same time. The multisegment_pdus map is built
3271 * during first scan (pinfo->visited == false) with help of prev_deseg_len and last_msp fields of streaming_reassembly_info_t
3272 * for each direction of a ProtoA STREAM. The prev_deseg_len record how many bytes of subsequent ProtoA payloads belong to
3273 * previous PDU during first scan. The last_msp member of streaming_reassembly_info_t is always point to last MSP which
3274 * is created during scan previous or early ProtoA payloads. Since subdissector might return only the head length of entire
3275 * message (by pinfo->desegment_len) when there is not enough data to determine the message length, we need to reopen
3276 * reassembly fragments for adding more bytes during scanning the next ProtoA payload. We have to use fragment_add()
3277 * instead of fragment_add_check() or fragment_add_seq_next().
3278 *
3279 * Read more: please refer to comments of the declaration of this function in 'reassemble.h'.
3280 */
3281int
3282reassemble_streaming_data_and_call_subdissector(
3283 tvbuff_t* tvb, packet_info* pinfo, unsigned offset, int length,
3284 proto_tree* segment_tree, proto_tree* reassembled_tree, reassembly_table streaming_reassembly_table,
3285 streaming_reassembly_info_t* reassembly_info, uint64_t cur_frame_num,
3286 dissector_handle_t subdissector_handle, proto_tree* subdissector_tree, void* subdissector_data,
3287 const char* label, const fragment_items* frag_hf_items, int hf_segment_data
3288)
3289{
3290 int orig_length = length;
3291 int datalen = 0;
3292 int bytes_belong_to_prev_msp = 0; /* bytes belong to previous MSP */
3293 uint32_t reassembly_id = 0, frag_offset = 0;
3294 fragment_head* head = NULL((void*)0);
3295 bool_Bool need_more = false0;
3296 bool_Bool found_BoMSP = false0;
3297 multisegment_pdu_t* cur_msp = NULL((void*)0), * prev_msp = NULL((void*)0);
3298 uint16_t save_can_desegment;
3299 int save_desegment_offset;
3300 uint32_t save_desegment_len;
3301 uint64_t* frame_ptr;
3302
3303 save_can_desegment = pinfo->can_desegment;
3304 save_desegment_offset = pinfo->desegment_offset;
3305 save_desegment_len = pinfo->desegment_len;
3306
3307 /* calculate how many bytes of this payload belongs to previous MSP (EoMSP) */
3308 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
1
Assuming field 'visited' is not equal to 0
2
Taking false branch
3309 /* this is first scan */
3310 if (reassembly_info->prev_deseg_len == DESEGMENT_ONE_MORE_SEGMENT0x0fffffff) {
3311 /* assuming the entire tvb belongs to the previous MSP */
3312 bytes_belong_to_prev_msp = length;
3313 reassembly_info->prev_deseg_len = length;
3314 } else if (reassembly_info->prev_deseg_len > 0) {
3315 /* part or all of current payload belong to previous MSP */
3316 bytes_belong_to_prev_msp = MIN(reassembly_info->prev_deseg_len, length)(((reassembly_info->prev_deseg_len) < (length)) ? (reassembly_info
->prev_deseg_len) : (length))
;
3317 reassembly_info->prev_deseg_len -= bytes_belong_to_prev_msp;
3318 need_more = (reassembly_info->prev_deseg_len > 0);
3319 } /* else { beginning of a new PDU (might be a NFP or MSP) } */
3320
3321 if (bytes_belong_to_prev_msp > 0) {
3322 DISSECTOR_ASSERT(reassembly_info->last_msp != NULL)((void) ((reassembly_info->last_msp != ((void*)0)) ? (void
)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/reassemble.c", 3322, "reassembly_info->last_msp != ((void*)0)"
))))
;
3323 reassembly_id = reassembly_info->last_msp->streaming_reassembly_id;
3324 frag_offset = reassembly_info->last_msp->length;
3325 if (reassembly_info->frame_num_frag_offset_map == NULL((void*)0)) {
3326 reassembly_info->frame_num_frag_offset_map = wmem_map_new(wmem_file_scope(), g_int64_hash, g_int64_equal);
3327 }
3328 frame_ptr = (uint64_t*)wmem_memdup(wmem_file_scope(), &cur_frame_num, sizeof(uint64_t));
3329 wmem_map_insert(reassembly_info->frame_num_frag_offset_map, frame_ptr, GUINT_TO_POINTER(frag_offset)((gpointer) (gulong) (frag_offset)));
3330 /* This payload contains the data of previous msp, so we point to it. That may be overridden late. */
3331 wmem_map_insert(reassembly_info->multisegment_pdus, frame_ptr, reassembly_info->last_msp);
3332 }
3333 } else {
3334 /* not first scan, use information of multisegment_pdus built during first scan */
3335 if (reassembly_info->multisegment_pdus) {
3
Assuming field 'multisegment_pdus' is null
4
Taking false branch
3336 cur_msp = (multisegment_pdu_t*)wmem_map_lookup(reassembly_info->multisegment_pdus, &cur_frame_num);
3337 }
3338 if (cur_msp
4.1
'cur_msp' is null
) {
3339 if (cur_msp->first_frame == cur_frame_num) {
3340 /* Current payload contains a beginning of a MSP. (BoMSP)
3341 * The cur_msp contains information about the beginning MSP.
3342 * If prev_msp is not null, that means this payload also contains
3343 * the last part of previous MSP. (EoMSP) */
3344 prev_msp = cur_msp->prev_msp;
3345 } else {
3346 /* Current payload is not a first frame of a MSP (not include BoMSP). */
3347 prev_msp = cur_msp;
3348 cur_msp = NULL((void*)0);
3349 }
3350 }
3351
3352 if (prev_msp
4.2
'prev_msp' is null
&& prev_msp->last_frame >= cur_frame_num) {
3353 if (prev_msp->last_frame == cur_frame_num) {
3354 /* this payload contains part of previous MSP (contains EoMSP) */
3355 bytes_belong_to_prev_msp = prev_msp->end_offset_at_last_frame - offset;
3356 } else { /* if (prev_msp->last_frame > cur_frame_num) */
3357 /* this payload all belongs to previous MSP */
3358 bytes_belong_to_prev_msp = length;
3359 need_more = true1;
3360 }
3361 reassembly_id = prev_msp->streaming_reassembly_id;
3362 }
3363 if (reassembly_info->frame_num_frag_offset_map) {
5
Assuming field 'frame_num_frag_offset_map' is null
6
Taking false branch
3364 frag_offset = GPOINTER_TO_UINT(wmem_map_lookup(reassembly_info->frame_num_frag_offset_map, &cur_frame_num))((guint) (gulong) (wmem_map_lookup(reassembly_info->frame_num_frag_offset_map
, &cur_frame_num)))
;
3365 }
3366 }
3367
3368 /* handling EoMSP or MoMSP (entire payload being middle part of a MSP) */
3369 while (bytes_belong_to_prev_msp > 0) {
3370 tvbuff_t* reassembled_tvb = NULL((void*)0);
3371 DISSECTOR_ASSERT(reassembly_id > 0)((void) ((reassembly_id > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 3371,
"reassembly_id > 0"))))
;
3372 pinfo->can_desegment = 2; /* this will be decreased one while passing to subdissector */
3373 pinfo->desegment_offset = 0;
3374 pinfo->desegment_len = 0;
3375
3376 head = fragment_add(&streaming_reassembly_table, tvb, offset, pinfo, reassembly_id, NULL((void*)0),
3377 frag_offset, bytes_belong_to_prev_msp, need_more);
3378
3379 if (head) {
3380 if (frag_hf_items->hf_reassembled_in) {
3381 proto_item_set_generated(
3382 proto_tree_add_uint(segment_tree, *(frag_hf_items->hf_reassembled_in), tvb, offset,
3383 bytes_belong_to_prev_msp, head->reassembled_in)
3384 );
3385 }
3386
3387 if (!need_more) {
3388 reassembled_tvb = process_reassembled_data(tvb, offset, pinfo,
3389 wmem_strdup_printf(pinfo->pool, "Reassembled %s", label),
3390 head, frag_hf_items, NULL((void*)0), reassembled_tree);
3391 }
3392 }
3393
3394 proto_tree_add_bytes_format(segment_tree, hf_segment_data, tvb, offset,
3395 bytes_belong_to_prev_msp, NULL((void*)0), "%s Segment data (%u byte%s)", label,
3396 bytes_belong_to_prev_msp, plurality(bytes_belong_to_prev_msp, "", "s")((bytes_belong_to_prev_msp) == 1 ? ("") : ("s")));
3397
3398 if (reassembled_tvb) {
3399 /* normally, this stage will dissect one or more completed pdus */
3400 /* Note, don't call_dissector_with_data because sometime the pinfo->curr_layer_num will changed
3401 * after calling that will make reassembly failed! */
3402 call_dissector_only(subdissector_handle, reassembled_tvb, pinfo, subdissector_tree, subdissector_data);
3403 }
3404
3405 if (pinfo->desegment_len) {
3406 /* that must only happen during first scan the reassembly_info->prev_deseg_len might be only the
3407 * head length of entire message. */
3408 DISSECTOR_ASSERT(!PINFO_FD_VISITED(pinfo))((void) ((!((pinfo)->fd->visited)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 3408,
"!((pinfo)->fd->visited)"))))
;
3409 DISSECTOR_ASSERT_HINT(pinfo->desegment_len != DESEGMENT_UNTIL_FIN, "Subdissector MUST NOT "((void) ((pinfo->desegment_len != 0x0ffffffe) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3411, "pinfo->desegment_len != 0x0ffffffe"
, "Subdissector MUST NOT " "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "
" DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined."
))))
3410 "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "((void) ((pinfo->desegment_len != 0x0ffffffe) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3411, "pinfo->desegment_len != 0x0ffffffe"
, "Subdissector MUST NOT " "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "
" DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined."
))))
3411 " DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined.")((void) ((pinfo->desegment_len != 0x0ffffffe) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3411, "pinfo->desegment_len != 0x0ffffffe"
, "Subdissector MUST NOT " "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "
" DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined."
))))
;
3412
3413 if (pinfo->desegment_offset > 0) {
3414 DISSECTOR_ASSERT_HINT(pinfo->desegment_offset > reassembly_info->last_msp->length((void) ((pinfo->desegment_offset > reassembly_info->
last_msp->length && pinfo->desegment_offset <
reassembly_info->last_msp->length + bytes_belong_to_prev_msp
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3418, "pinfo->desegment_offset > reassembly_info->last_msp->length && pinfo->desegment_offset < reassembly_info->last_msp->length + bytes_belong_to_prev_msp"
, wmem_strdup_printf(pinfo->pool, "Subdissector MUST NOT set pinfo->desegment_offset(%d) in previous or next part of MSP, must between (%d, %d)."
, pinfo->desegment_offset, reassembly_info->last_msp->
length, reassembly_info->last_msp->length + bytes_belong_to_prev_msp
)))))
3415 && pinfo->desegment_offset < reassembly_info->last_msp->length + bytes_belong_to_prev_msp,((void) ((pinfo->desegment_offset > reassembly_info->
last_msp->length && pinfo->desegment_offset <
reassembly_info->last_msp->length + bytes_belong_to_prev_msp
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3418, "pinfo->desegment_offset > reassembly_info->last_msp->length && pinfo->desegment_offset < reassembly_info->last_msp->length + bytes_belong_to_prev_msp"
, wmem_strdup_printf(pinfo->pool, "Subdissector MUST NOT set pinfo->desegment_offset(%d) in previous or next part of MSP, must between (%d, %d)."
, pinfo->desegment_offset, reassembly_info->last_msp->
length, reassembly_info->last_msp->length + bytes_belong_to_prev_msp
)))))
3416 wmem_strdup_printf(pinfo->pool,((void) ((pinfo->desegment_offset > reassembly_info->
last_msp->length && pinfo->desegment_offset <
reassembly_info->last_msp->length + bytes_belong_to_prev_msp
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3418, "pinfo->desegment_offset > reassembly_info->last_msp->length && pinfo->desegment_offset < reassembly_info->last_msp->length + bytes_belong_to_prev_msp"
, wmem_strdup_printf(pinfo->pool, "Subdissector MUST NOT set pinfo->desegment_offset(%d) in previous or next part of MSP, must between (%d, %d)."
, pinfo->desegment_offset, reassembly_info->last_msp->
length, reassembly_info->last_msp->length + bytes_belong_to_prev_msp
)))))
3417 "Subdissector MUST NOT set pinfo->desegment_offset(%d) in previous or next part of MSP, must between (%d, %d).",((void) ((pinfo->desegment_offset > reassembly_info->
last_msp->length && pinfo->desegment_offset <
reassembly_info->last_msp->length + bytes_belong_to_prev_msp
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3418, "pinfo->desegment_offset > reassembly_info->last_msp->length && pinfo->desegment_offset < reassembly_info->last_msp->length + bytes_belong_to_prev_msp"
, wmem_strdup_printf(pinfo->pool, "Subdissector MUST NOT set pinfo->desegment_offset(%d) in previous or next part of MSP, must between (%d, %d)."
, pinfo->desegment_offset, reassembly_info->last_msp->
length, reassembly_info->last_msp->length + bytes_belong_to_prev_msp
)))))
3418 pinfo->desegment_offset, reassembly_info->last_msp->length, reassembly_info->last_msp->length + bytes_belong_to_prev_msp))((void) ((pinfo->desegment_offset > reassembly_info->
last_msp->length && pinfo->desegment_offset <
reassembly_info->last_msp->length + bytes_belong_to_prev_msp
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3418, "pinfo->desegment_offset > reassembly_info->last_msp->length && pinfo->desegment_offset < reassembly_info->last_msp->length + bytes_belong_to_prev_msp"
, wmem_strdup_printf(pinfo->pool, "Subdissector MUST NOT set pinfo->desegment_offset(%d) in previous or next part of MSP, must between (%d, %d)."
, pinfo->desegment_offset, reassembly_info->last_msp->
length, reassembly_info->last_msp->length + bytes_belong_to_prev_msp
)))))
;
3419
3420 /* shorten the bytes_belong_to_prev_msp and just truncate the reassembled tvb */
3421 bytes_belong_to_prev_msp = pinfo->desegment_offset - reassembly_info->last_msp->length;
3422 fragment_truncate(&streaming_reassembly_table, pinfo, reassembly_id, NULL((void*)0), pinfo->desegment_offset);
3423 found_BoMSP = true1;
3424 } else {
3425 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT0x0fffffff) {
3426 /* just need more bytes, all remaining bytes belongs to previous MSP (to run fragment_add again) */
3427 bytes_belong_to_prev_msp = length;
3428 }
3429
3430 /* Remove the data added by previous fragment_add(), and reopen fragments for adding more bytes. */
3431 fragment_truncate(&streaming_reassembly_table, pinfo, reassembly_id, NULL((void*)0), reassembly_info->last_msp->length);
3432 fragment_set_partial_reassembly(&streaming_reassembly_table, pinfo, reassembly_id, NULL((void*)0));
3433
3434 reassembly_info->prev_deseg_len = bytes_belong_to_prev_msp + pinfo->desegment_len;
3435 bytes_belong_to_prev_msp = MIN(reassembly_info->prev_deseg_len, length)(((reassembly_info->prev_deseg_len) < (length)) ? (reassembly_info
->prev_deseg_len) : (length))
;
3436 reassembly_info->prev_deseg_len -= bytes_belong_to_prev_msp;
3437 need_more = (reassembly_info->prev_deseg_len > 0);
3438 continue;
3439 }
3440 }
3441
3442 if (pinfo->desegment_len == 0 || found_BoMSP) {
3443 /* We will arrive here, only when the MSP is defragmented and dissected or this
3444 * payload all belongs to previous MSP (only fragment_add() with need_more=true called)
3445 * or BoMSP is parsed while pinfo->desegment_offset > 0 and pinfo->desegment_len != 0
3446 */
3447 offset += bytes_belong_to_prev_msp;
3448 length -= bytes_belong_to_prev_msp;
3449 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 3449,
"length >= 0"))))
;
3450 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3451 reassembly_info->last_msp->length += bytes_belong_to_prev_msp;
3452 }
3453
3454 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && reassembled_tvb) {
3455 /* completed current msp */
3456 reassembly_info->last_msp->last_frame = cur_frame_num;
3457 reassembly_info->last_msp->end_offset_at_last_frame = offset;
3458 reassembly_info->prev_deseg_len = pinfo->desegment_len;
3459 }
3460 bytes_belong_to_prev_msp = 0; /* break */
3461 }
3462 }
3463
3464 /* to find and handle OmNFP, and find BoMSP at first scan. */
3465 if (length > 0 && !found_BoMSP
7.1
'found_BoMSP' is false
) {
7
Assuming 'length' is > 0
8
Taking true branch
3466 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
9
Taking false branch
3467 /* It is first scan, to dissect remaining bytes to find whether it is OmNFP only, or BoMSP only or OmNFP + BoMSP. */
3468 datalen = length;
3469 DISSECTOR_ASSERT(cur_msp == NULL)((void) ((cur_msp == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 3469,
"cur_msp == ((void*)0)"))))
;
3470 } else {
3471 /* Not first scan */
3472 if (cur_msp
9.1
'cur_msp' is null
) {
10
Taking false branch
3473 /* There's a BoMSP. Let's calculate the length of OmNFP between EoMSP and BoMSP */
3474 datalen = cur_msp->start_offset_at_first_frame - offset; /* if result is zero that means no OmNFP */
3475 } else {
3476 /* This payload is not a beginning of MSP. The remaining bytes all belong to OmNFP without BoMSP */
3477 datalen = length;
3478 }
3479 }
3480 DISSECTOR_ASSERT(datalen >= 0)((void) ((datalen >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 3480,
"datalen >= 0"))))
;
11
'?' condition is true
3481
3482 /* Dissect the remaining of this payload. If (datalen == 0) means remaining only have one BoMSP without OmNFP. */
3483 if (datalen
11.1
'datalen' is > 0
> 0) {
12
Taking true branch
3484 /* we dissect if it is not dissected before or it is a non-fragment pdu (between two multisegment pdus) */
3485 pinfo->can_desegment = 2;
3486 pinfo->desegment_offset = 0;
3487 pinfo->desegment_len = 0;
3488
3489 call_dissector_only(subdissector_handle, tvb_new_subset_length(tvb, offset, datalen),
3490 pinfo, subdissector_tree, subdissector_data);
3491
3492 if (pinfo->desegment_len) {
13
Assuming field 'desegment_len' is not equal to 0
3493 DISSECTOR_ASSERT_HINT(pinfo->desegment_len != DESEGMENT_UNTIL_FIN, "Subdissector MUST NOT "((void) ((pinfo->desegment_len != 0x0ffffffe) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3495, "pinfo->desegment_len != 0x0ffffffe"
, "Subdissector MUST NOT " "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "
" DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined."
))))
14
Taking true branch
15
Assuming field 'desegment_len' is not equal to 268435454
16
'?' condition is true
3494 "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "((void) ((pinfo->desegment_len != 0x0ffffffe) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3495, "pinfo->desegment_len != 0x0ffffffe"
, "Subdissector MUST NOT " "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "
" DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined."
))))
3495 " DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined.")((void) ((pinfo->desegment_len != 0x0ffffffe) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/reassemble.c", 3495, "pinfo->desegment_len != 0x0ffffffe"
, "Subdissector MUST NOT " "set pinfo->desegment_len to DESEGMENT_UNTIL_FIN. Instead, it can set pinfo->desegment_len to "
" DESEGMENT_ONE_MORE_SEGMENT or the length of head if the length of entire message is not able to be determined."
))))
;
3496 /* only happen during first scan */
3497 DISSECTOR_ASSERT(!PINFO_FD_VISITED(pinfo) && datalen == length)((void) ((!((pinfo)->fd->visited) && datalen ==
length) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/reassemble.c", 3497, "!((pinfo)->fd->visited) && datalen == length"
))))
;
17
Assuming field 'visited' is 0
18
'?' condition is true
3498 offset += pinfo->desegment_offset;
3499 length -= pinfo->desegment_offset;
3500 } else {
3501 /* all remaining bytes are consumed by subdissector */
3502 offset += datalen;
3503 length -= datalen;
3504 }
3505 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
19
Taking true branch
3506 reassembly_info->prev_deseg_len = pinfo->desegment_len;
3507 }
3508 } /* else all remaining bytes (BoMSP) belong to a new MSP */
3509 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/reassemble.c", 3509,
"length >= 0"))))
;
20
Assuming 'length' is >= 0
21
'?' condition is true
3510 }
3511
3512 /* handling BoMSP */
3513 if (length > 0) {
22
Assuming 'length' is > 0
23
Taking true branch
3514 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "[%s segment of a reassembled PDU] ", label);
3515 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
24
Taking true branch
3516 /* create a msp for current frame during first scan */
3517 cur_msp = wmem_new0(wmem_file_scope(), multisegment_pdu_t)((multisegment_pdu_t*)wmem_alloc0((wmem_file_scope()), sizeof
(multisegment_pdu_t)))
;
3518 cur_msp->first_frame = cur_frame_num;
3519 cur_msp->last_frame = UINT64_MAX(18446744073709551615UL);
3520 cur_msp->start_offset_at_first_frame = offset;
3521 cur_msp->length = length;
3522 cur_msp->streaming_reassembly_id = reassembly_id = create_streaming_reassembly_id();
3523 cur_msp->prev_msp = reassembly_info->last_msp;
3524 reassembly_info->last_msp = cur_msp;
3525 if (reassembly_info->multisegment_pdus
24.1
Field 'multisegment_pdus' is equal to NULL
== NULL((void*)0)) {
25
Taking true branch
3526 reassembly_info->multisegment_pdus = wmem_map_new(wmem_file_scope(), g_int64_hash, g_int64_equal);
3527 }
3528 frame_ptr = (uint64_t*)wmem_memdup(wmem_file_scope(), &cur_frame_num, sizeof(uint64_t));
3529 wmem_map_insert(reassembly_info->multisegment_pdus, frame_ptr, cur_msp);
3530 } else {
3531 DISSECTOR_ASSERT(cur_msp && cur_msp->start_offset_at_first_frame == offset)((void) ((cur_msp && cur_msp->start_offset_at_first_frame
== offset) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/reassemble.c", 3531, "cur_msp && cur_msp->start_offset_at_first_frame == offset"
))))
;
3532 reassembly_id = cur_msp->streaming_reassembly_id;
3533 }
3534 /* add first fragment of the new MSP to reassembly table */
3535 head = fragment_add(&streaming_reassembly_table, tvb, offset, pinfo, reassembly_id,
26
Calling 'fragment_add'
3536 NULL((void*)0), 0, length, true1);
3537
3538 if (head && frag_hf_items->hf_reassembled_in) {
3539 proto_item_set_generated(
3540 proto_tree_add_uint(segment_tree, *(frag_hf_items->hf_reassembled_in),
3541 tvb, offset, length, head->reassembled_in)
3542 );
3543 }
3544 proto_tree_add_bytes_format(segment_tree, hf_segment_data, tvb, offset, length,
3545 NULL((void*)0), "%s Segment data (%u byte%s)", label, length, plurality(length, "", "s")((length) == 1 ? ("") : ("s")));
3546 }
3547
3548 pinfo->can_desegment = save_can_desegment;
3549 pinfo->desegment_offset = save_desegment_offset;
3550 pinfo->desegment_len = save_desegment_len;
3551
3552 return orig_length;
3553}
3554
3555int
3556additional_bytes_expected_to_complete_reassembly(streaming_reassembly_info_t* reassembly_info)
3557{
3558 return reassembly_info->prev_deseg_len;
3559}
3560
3561/*
3562 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3563 *
3564 * Local variables:
3565 * c-basic-offset: 8
3566 * tab-width: 8
3567 * indent-tabs-mode: t
3568 * End:
3569 *
3570 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3571 * :indentSize=8:tabSize=8:noTabs=false:
3572 */