Bug Summary

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