Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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