1 /* reassemble.h 2 * Declarations of routines for {fragment,segment} reassembly 3 * 4 * Wireshark - Network traffic analyzer 5 * By Gerald Combs <gerald@wireshark.org> 6 * Copyright 1998 Gerald Combs 7 * 8 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 /* make sure that all flags that are set in a fragment entry is also set for 12 * the flags field of fd_head !!! 13 */ 14 15 #ifndef REASSEMBLE_H 16 #define REASSEMBLE_H 17 18 #include "ws_symbol_export.h" 19 20 /* only in fd_head: packet is defragmented */ 21 #define FD_DEFRAGMENTED 0x0001 22 23 /* there are overlapping fragments */ 24 #define FD_OVERLAP 0x0002 25 26 /* overlapping fragments contain different data */ 27 #define FD_OVERLAPCONFLICT 0x0004 28 29 /* more than one fragment which indicates end-of data */ 30 #define FD_MULTIPLETAILS 0x0008 31 32 /* fragment starts before the end of the datagram but extends 33 past the end of the datagram */ 34 #define FD_TOOLONGFRAGMENT 0x0010 35 36 /* fragment tvb is subset, don't tvb_free() it */ 37 #define FD_SUBSET_TVB 0x0020 38 39 /* this flag is used to request fragment_add to continue the reassembly process */ 40 #define FD_PARTIAL_REASSEMBLY 0x0040 41 42 /* fragment offset is indicated by sequence number and not byte offset 43 into the defragmented packet */ 44 #define FD_BLOCKSEQUENCE 0x0100 45 46 /* This flag is set in (only) fd_head to denote that datalen has been set to a valid value. 47 * It's implied by FD_DEFRAGMENTED (we must know the total length of the 48 * datagram if we have defragmented it...) 49 */ 50 #define FD_DATALEN_SET 0x0400 51 52 typedef struct _fragment_item { 53 struct _fragment_item *next; 54 guint32 frame; /* XXX - does this apply to reassembly heads? */ 55 guint32 offset; /* XXX - does this apply to reassembly heads? */ 56 guint32 len; /* XXX - does this apply to reassembly heads? */ 57 guint32 fragment_nr_offset; /**< offset for frame numbering, for sequences, where the 58 * provided fragment number of the first fragment does 59 * not start with 0 60 * XXX - does this apply only to reassembly heads? */ 61 guint32 datalen; /**< When flags&FD_BLOCKSEQUENCE is set, the 62 * index of the last block (segments in 63 * datagram + 1); otherwise the number of 64 * bytes of the full datagram. Only valid in 65 * the first item of the fragments list when 66 * flags&FD_DATALEN is set.*/ 67 guint32 reassembled_in; /**< frame where this PDU was reassembled, 68 * only valid in the first item of the list 69 * and when FD_DEFRAGMENTED is set*/ 70 guint8 reas_in_layer_num; /**< The current "depth" or layer number in the current frame where reassembly was completed. 71 * Example: in SCTP there can be several data chunks and we want the reassemblied tvb for the final 72 * segment only. */ 73 guint32 flags; /**< XXX - do some of these apply only to reassembly 74 * heads and others only to fragments within 75 * a reassembly? */ 76 tvbuff_t *tvb_data; 77 /** 78 * Null if the reassembly had no error; non-null if it had 79 * an error, in which case it's the string for the error. 80 * 81 * XXX - this is wasted in all but the reassembly head; we 82 * should probably have separate data structures for a 83 * reassembly and for the fragments in a reassembly. 84 */ 85 const char *error; 86 } fragment_item, fragment_head; 87 88 89 /* 90 * Flags for fragment_add_seq_* 91 */ 92 93 /* we don't have any sequence numbers - fragments are assumed to appear in 94 * order */ 95 #define REASSEMBLE_FLAGS_NO_FRAG_NUMBER 0x0001 96 97 /* a special fudge for the 802.11 dissector */ 98 #define REASSEMBLE_FLAGS_802_11_HACK 0x0002 99 100 /* 101 * Flags for fragment_add_seq_single_* 102 */ 103 104 /* we want to age off old packets */ 105 #define REASSEMBLE_FLAGS_AGING 0x0001 106 107 /* 108 * Generates a fragment identifier based on the given parameters. "data" is an 109 * opaque type whose interpretation is up to the caller of fragment_add* 110 * functions and the fragment key function (possibly NULL if you do not care). 111 * 112 * Keys returned by this function are only used within this packet scope. 113 */ 114 typedef gpointer (*fragment_temporary_key)(const packet_info *pinfo, 115 const guint32 id, const void *data); 116 117 /* 118 * Like fragment_temporary_key, but used for identifying reassembled fragments 119 * which may persist through multiple packets. 120 */ 121 typedef gpointer (*fragment_persistent_key)(const packet_info *pinfo, 122 const guint32 id, const void *data); 123 124 /* 125 * Data structure to keep track of fragments and reassemblies. 126 */ 127 typedef struct { 128 GHashTable *fragment_table; 129 GHashTable *reassembled_table; 130 fragment_temporary_key temporary_key_func; 131 fragment_persistent_key persistent_key_func; 132 GDestroyNotify free_temporary_key_func; /* temporary key destruction function */ 133 } reassembly_table; 134 135 /* 136 * Table of functions for a reassembly table. 137 */ 138 typedef struct { 139 /* Functions for fragment table */ 140 GHashFunc hash_func; /* hash function */ 141 GEqualFunc equal_func; /* comparison function */ 142 fragment_temporary_key temporary_key_func; /* temporary key creation function */ 143 fragment_persistent_key persistent_key_func; /* persistent key creation function */ 144 GDestroyNotify free_temporary_key_func; /* temporary key destruction function */ 145 GDestroyNotify free_persistent_key_func; /* persistent key destruction function */ 146 } reassembly_table_functions; 147 148 /* 149 * Tables of functions exported for the benefit of dissectors that 150 * don't need special items in their keys. 151 */ 152 WS_DLL_PUBLIC const reassembly_table_functions 153 addresses_reassembly_table_functions; /* keys have endpoint addresses and an ID */ 154 WS_DLL_PUBLIC const reassembly_table_functions 155 addresses_ports_reassembly_table_functions; /* keys have endpoint addresses and ports and an ID */ 156 157 /* 158 * Register a reassembly table. By registering the table with epan, the creation and 159 * destruction of the table can be managed by epan and not the dissector. 160 */ 161 WS_DLL_PUBLIC void 162 reassembly_table_register(reassembly_table *table, 163 const reassembly_table_functions *funcs); 164 165 /* 166 * Initialize/destroy a reassembly table. 167 * 168 * init: If table doesn't exist: create table; 169 * else: just remove any entries; 170 * destroy: remove entries and destroy table; 171 */ 172 WS_DLL_PUBLIC void 173 reassembly_table_init(reassembly_table *table, 174 const reassembly_table_functions *funcs); 175 WS_DLL_PUBLIC void 176 reassembly_table_destroy(reassembly_table *table); 177 178 /* 179 * This function adds a new fragment to the reassembly table 180 * If this is the first fragment seen for this datagram, a new entry 181 * is created in the table, otherwise this fragment is just added 182 * to the linked list of fragments for this packet. 183 * The list of fragments for a specific datagram is kept sorted for 184 * easier handling. 185 * 186 * Datagrams (messages) are identified by a key generated by 187 * fragment_temporary_key or fragment_persistent_key, based on the "pinfo", "id" 188 * and "data" pairs. (This is the sole purpose of "data".) 189 * 190 * Fragments are identified by "frag_offset". 191 * 192 * Returns a pointer to the head of the fragment data list if we have all the 193 * fragments, NULL otherwise. Note that the reassembled fragments list may have 194 * a non-zero fragment offset, the only guarantee is that no gaps exist within 195 * the list. 196 */ 197 WS_DLL_PUBLIC fragment_head * 198 fragment_add(reassembly_table *table, tvbuff_t *tvb, const int offset, 199 const packet_info *pinfo, const guint32 id, const void *data, 200 const guint32 frag_offset, const guint32 frag_data_len, 201 const gboolean more_frags); 202 /* 203 * Like fragment_add, except that the fragment may be added to multiple 204 * reassembly tables. This is needed when multiple protocol layers try 205 * to add the same packet to the reassembly table. 206 */ 207 WS_DLL_PUBLIC fragment_head * 208 fragment_add_multiple_ok(reassembly_table *table, tvbuff_t *tvb, 209 const int offset, const packet_info *pinfo, 210 const guint32 id, const void *data, 211 const guint32 frag_offset, 212 const guint32 frag_data_len, 213 const gboolean more_frags); 214 215 /* 216 * Like fragment_add, but maintains a table for completed reassemblies. 217 * 218 * If the packet was seen before, return the head of the fully reassembled 219 * fragments list (NULL if there was none). 220 * 221 * Otherwise (if reassembly was not possible before), try to to add the new 222 * fragment to the fragments table. If reassembly is now possible, remove all 223 * (reassembled) fragments from the fragments table and store it as a completed 224 * reassembly. The head of this reassembled fragments list is returned. 225 * 226 * Otherwise (if reassembly is still not possible after adding this fragment), 227 * return NULL. 228 */ 229 WS_DLL_PUBLIC fragment_head * 230 fragment_add_check(reassembly_table *table, tvbuff_t *tvb, const int offset, 231 const packet_info *pinfo, const guint32 id, 232 const void *data, const guint32 frag_offset, 233 const guint32 frag_data_len, const gboolean more_frags); 234 235 /* 236 * Like fragment_add, but fragments have a block sequence number starting from 237 * zero (for the first fragment of each datagram). This differs from 238 * fragment_add for which the fragment may start at any offset. 239 * 240 * If this is the first fragment seen for this datagram, a new 241 * "fragment_head" structure is allocated to refer to the reassembled 242 * packet, and: 243 * 244 * if "more_frags" is false, and either we have no sequence numbers, or 245 * are using the 802.11 hack (via fragment_add_seq_802_11), it is assumed that 246 * this is the only fragment in the datagram. The structure is not added to the 247 * hash table, and not given any fragments to refer to, but is just returned. 248 * 249 * In this latter case reassembly wasn't done (since there was only one 250 * fragment in the packet); dissectors can check the 'next' pointer on the 251 * returned list to see if this case was hit or not. 252 * 253 * Otherwise, this fragment is just added to the linked list of fragments 254 * for this packet; the fragment_item is also added to the fragment hash if 255 * necessary. 256 * 257 * If this packet completes assembly, these functions return the head of the 258 * fragment data; otherwise, they return null. 259 */ 260 WS_DLL_PUBLIC fragment_head * 261 fragment_add_seq(reassembly_table *table, tvbuff_t *tvb, const int offset, 262 const packet_info *pinfo, const guint32 id, const void *data, 263 const guint32 frag_number, const guint32 frag_data_len, 264 const gboolean more_frags, const guint32 flags); 265 266 /* 267 * Like fragment_add_seq, but maintains a table for completed reassemblies 268 * just like fragment_add_check. 269 */ 270 WS_DLL_PUBLIC fragment_head * 271 fragment_add_seq_check(reassembly_table *table, tvbuff_t *tvb, const int offset, 272 const packet_info *pinfo, const guint32 id, 273 const void *data, 274 const guint32 frag_number, const guint32 frag_data_len, 275 const gboolean more_frags); 276 277 /* 278 * Like fragment_add_seq_check, but immediately returns a fragment list for a 279 * new fragment. This is a workaround specific for the 802.11 dissector, do not 280 * use it elsewhere. 281 */ 282 WS_DLL_PUBLIC fragment_head * 283 fragment_add_seq_802_11(reassembly_table *table, tvbuff_t *tvb, 284 const int offset, const packet_info *pinfo, 285 const guint32 id, const void *data, 286 const guint32 frag_number, const guint32 frag_data_len, 287 const gboolean more_frags); 288 289 /* 290 * Like fragment_add_seq_check, but without explicit fragment number. Fragments 291 * are simply appended until no "more_frags" is false. 292 */ 293 WS_DLL_PUBLIC fragment_head * 294 fragment_add_seq_next(reassembly_table *table, tvbuff_t *tvb, const int offset, 295 const packet_info *pinfo, const guint32 id, 296 const void *data, const guint32 frag_data_len, 297 const gboolean more_frags); 298 299 /* 300 * Like fragment_add_seq_check, but for protocols like PPP MP with a single 301 * sequence number that increments for each fragment, thus acting like the sum 302 * of the PDU sequence number and explicit fragment number in other protocols. 303 * See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list 304 * of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS 305 * (RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay. 306 * It is guaranteed to reassemble a packet split up to "max_frags" in size, 307 * but may manage to reassemble more in certain cases. 308 */ 309 WS_DLL_PUBLIC fragment_head * 310 fragment_add_seq_single(reassembly_table *table, tvbuff_t *tvb, 311 const int offset, const packet_info *pinfo, const guint32 id, 312 const void* data, const guint32 frag_data_len, 313 const gboolean first, const gboolean last, 314 const guint32 max_frags); 315 316 /* 317 * A variation on the above that ages off fragments that have not been 318 * reassembled. Useful if the sequence number loops to deal with leftover 319 * fragments from the beginning of the capture or missing fragments. 320 */ 321 WS_DLL_PUBLIC fragment_head * 322 fragment_add_seq_single_aging(reassembly_table *table, tvbuff_t *tvb, 323 const int offset, const packet_info *pinfo, const guint32 id, 324 const void* data, const guint32 frag_data_len, 325 const gboolean first, const gboolean last, 326 const guint32 max_frags, const guint32 max_age); 327 328 /* 329 * Start a reassembly, expecting "tot_len" as the number of given fragments (not 330 * the number of bytes). Data can be added later using fragment_add_seq_check. 331 */ 332 WS_DLL_PUBLIC void 333 fragment_start_seq_check(reassembly_table *table, const packet_info *pinfo, 334 const guint32 id, const void *data, 335 const guint32 tot_len); 336 337 /* 338 * Mark end of reassembly and returns the reassembled fragment (if completed). 339 * Use it when fragments were added with "more_flags" set while you discovered 340 * that no more fragments have to be added. 341 * XXX rename to fragment_finish as it works also for fragment_add? 342 */ 343 WS_DLL_PUBLIC fragment_head * 344 fragment_end_seq_next(reassembly_table *table, const packet_info *pinfo, 345 const guint32 id, const void *data); 346 347 /* To specify the offset for the fragment numbering, the first fragment is added with 0, and 348 * afterwards this offset is set. All additional calls to off_seq_check will calculate 349 * the number in sequence in regards to the offset */ 350 WS_DLL_PUBLIC void 351 fragment_add_seq_offset(reassembly_table *table, const packet_info *pinfo, const guint32 id, 352 const void *data, const guint32 fragment_offset); 353 354 /* 355 * Sets the expected index for the last block (for fragment_add_seq functions) 356 * or the expected number of bytes (for fragment_add functions). A reassembly 357 * must already have started. 358 * 359 * Note that for FD_BLOCKSEQUENCE tot_len is the index for the tail fragment. 360 * i.e. since the block numbers start at 0, if we specify tot_len==2, that 361 * actually means we want to defragment 3 blocks, block 0, 1 and 2. 362 */ 363 WS_DLL_PUBLIC void 364 fragment_set_tot_len(reassembly_table *table, const packet_info *pinfo, 365 const guint32 id, const void *data, const guint32 tot_len); 366 367 /* 368 * Similar to fragment_set_tot_len, it sets the expected number of bytes (for 369 * fragment_add functions) for a previously started reassembly. If the specified 370 * length already matches the reassembled length, then nothing will be done. 371 * 372 * If the fragments were previously reassembled, then this state will be 373 * cleared, allowing new fragments to extend the reassembled result again. 374 */ 375 void 376 fragment_reset_tot_len(reassembly_table *table, const packet_info *pinfo, 377 const guint32 id, const void *data, const guint32 tot_len); 378 379 /* 380 * Return the expected index for the last block (for fragment_add_seq functions) 381 * or the expected number of bytes (for fragment_add functions). 382 */ 383 WS_DLL_PUBLIC guint32 384 fragment_get_tot_len(reassembly_table *table, const packet_info *pinfo, 385 const guint32 id, const void *data); 386 387 /* 388 * This function will set the partial reassembly flag(FD_PARTIAL_REASSEMBLY) for a fh. 389 * When this function is called, the fh MUST already exist, i.e. 390 * the fh MUST be created by the initial call to fragment_add() before 391 * this function is called. Also note that this function MUST be called to indicate 392 * a fh will be extended (increase the already stored data). After calling this function, 393 * and if FD_DEFRAGMENTED is set, the reassembly process will be continued. 394 */ 395 WS_DLL_PUBLIC void 396 fragment_set_partial_reassembly(reassembly_table *table, 397 const packet_info *pinfo, const guint32 id, 398 const void *data); 399 400 /* This function is used to check if there is partial or completed reassembly state 401 * matching this packet. I.e. Are there reassembly going on or not for this packet? 402 */ 403 WS_DLL_PUBLIC fragment_head * 404 fragment_get(reassembly_table *table, const packet_info *pinfo, 405 const guint32 id, const void *data); 406 407 /* The same for the reassemble table */ 408 /* id *must* be the frame number for this to work! */ 409 WS_DLL_PUBLIC fragment_head * 410 fragment_get_reassembled(reassembly_table *table, const guint32 id); 411 412 WS_DLL_PUBLIC fragment_head * 413 fragment_get_reassembled_id(reassembly_table *table, const packet_info *pinfo, 414 const guint32 id); 415 416 /* This will free up all resources and delete reassembly state for this PDU. 417 * Except if the PDU is completely reassembled, then it would NOT deallocate the 418 * buffer holding the reassembled data but instead return the TVB 419 * 420 * So, if you call fragment_delete and it returns non-NULL, YOU are responsible to 421 * tvb_free() . 422 */ 423 WS_DLL_PUBLIC tvbuff_t * 424 fragment_delete(reassembly_table *table, const packet_info *pinfo, 425 const guint32 id, const void *data); 426 427 /* This struct holds references to all the tree and field handles used when 428 * displaying the reassembled fragment tree in the packet details view. A 429 * dissector will populate this structure with its own tree and field handles 430 * and then invoke show_fragment_tree to have those items added to the packet 431 * details tree. 432 */ 433 typedef struct _fragment_items { 434 gint *ett_fragment; 435 gint *ett_fragments; 436 437 int *hf_fragments; /* FT_NONE */ 438 int *hf_fragment; /* FT_FRAMENUM */ 439 int *hf_fragment_overlap; /* FT_BOOLEAN */ 440 int *hf_fragment_overlap_conflict; /* FT_BOOLEAN */ 441 int *hf_fragment_multiple_tails; /* FT_BOOLEAN */ 442 int *hf_fragment_too_long_fragment; /* FT_BOOLEAN */ 443 int *hf_fragment_error; /* FT_FRAMENUM */ 444 int *hf_fragment_count; /* FT_UINT32 */ 445 int *hf_reassembled_in; /* FT_FRAMENUM */ 446 int *hf_reassembled_length; /* FT_UINT32 */ 447 int *hf_reassembled_data; /* FT_BYTES */ 448 449 const char *tag; 450 } fragment_items; 451 452 WS_DLL_PUBLIC tvbuff_t * 453 process_reassembled_data(tvbuff_t *tvb, const int offset, packet_info *pinfo, 454 const char *name, fragment_head *fd_head, const fragment_items *fit, 455 gboolean *update_col_infop, proto_tree *tree); 456 457 WS_DLL_PUBLIC gboolean 458 show_fragment_tree(fragment_head *ipfd_head, const fragment_items *fit, 459 proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, proto_item **fi); 460 461 WS_DLL_PUBLIC gboolean 462 show_fragment_seq_tree(fragment_head *ipfd_head, const fragment_items *fit, 463 proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, proto_item **fi); 464 465 /* Initialize internal structures 466 */ 467 extern void reassembly_tables_init(void); 468 469 /* Cleanup internal structures 470 */ 471 extern void 472 reassembly_table_cleanup(void); 473 474 #endif 475