2001-06-08 06:27:16 +00:00
|
|
|
/* reassemble.h
|
|
|
|
* Declarations of outines for {fragment,segment} reassembly
|
|
|
|
*
|
2003-04-20 11:36:16 +00:00
|
|
|
* $Id: reassemble.h,v 1.18 2003/04/20 11:36:16 guy Exp $
|
2001-06-08 06:27:16 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-06-08 06:27:16 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-06-08 06:27:16 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-06-08 06:27:16 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* make sure that all flags that are set in a fragment entry is also set for
|
|
|
|
* the flags field of fd_head !!!
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* only in fd_head: packet is defragmented */
|
|
|
|
#define FD_DEFRAGMENTED 0x0001
|
|
|
|
|
|
|
|
/* there are overlapping fragments */
|
|
|
|
#define FD_OVERLAP 0x0002
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
/* overlapping fragments contain different data */
|
|
|
|
#define FD_OVERLAPCONFLICT 0x0004
|
2001-06-08 06:27:16 +00:00
|
|
|
|
|
|
|
/* more than one fragment which indicates end-of data */
|
|
|
|
#define FD_MULTIPLETAILS 0x0008
|
|
|
|
|
|
|
|
/* fragment contains data past the end of the datagram */
|
|
|
|
#define FD_TOOLONGFRAGMENT 0x0010
|
|
|
|
|
2002-02-03 23:28:38 +00:00
|
|
|
/* fragment data not alloced, fd->data pointing to fd_head->data+fd->offset */
|
|
|
|
#define FD_NOT_MALLOCED 0x0020
|
|
|
|
|
|
|
|
/* this flag is used to request fragment_add to continue the reassembly process */
|
|
|
|
#define FD_PARTIAL_REASSEMBLY 0x0040
|
|
|
|
|
2001-12-15 05:40:32 +00:00
|
|
|
/* fragment offset is indicated by sequence number and not byte offset
|
|
|
|
into the defragmented packet */
|
|
|
|
#define FD_BLOCKSEQUENCE 0x0100
|
|
|
|
|
2001-06-08 06:27:16 +00:00
|
|
|
typedef struct _fragment_data {
|
|
|
|
struct _fragment_data *next;
|
|
|
|
guint32 frame;
|
|
|
|
guint32 offset;
|
|
|
|
guint32 len;
|
|
|
|
guint32 datalen; /*Only valid in first item of list */
|
2003-04-09 09:04:08 +00:00
|
|
|
guint32 reassembled_in; /* frame where this PDU was reassembled,
|
|
|
|
only valid in the first item of the list
|
|
|
|
and when FD_DEFRAGMENTED is set*/
|
2001-06-08 06:27:16 +00:00
|
|
|
guint32 flags;
|
|
|
|
unsigned char *data;
|
|
|
|
} fragment_data;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize a fragment table.
|
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern void fragment_table_init(GHashTable **fragment_table);
|
2001-06-08 06:27:16 +00:00
|
|
|
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
/*
|
|
|
|
* Initialize a reassembled-packet table.
|
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern void reassembled_table_init(GHashTable **reassembled_table);
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
|
2001-06-08 06:27:16 +00:00
|
|
|
/*
|
|
|
|
* Free up all space allocated for fragment keys and data.
|
|
|
|
*/
|
|
|
|
void reassemble_init(void);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function adds a new fragment to the fragment hash table.
|
|
|
|
* If this is the first fragment seen for this datagram, a new entry
|
|
|
|
* is created in the hash table, otherwise this fragment is just added
|
|
|
|
* to the linked list of fragments for this packet.
|
|
|
|
* The list of fragments for a specific datagram is kept sorted for
|
|
|
|
* easier handling.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the head of the fragment data list if we have all the
|
|
|
|
* fragments, NULL otherwise.
|
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern fragment_data *fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
2001-06-08 06:27:16 +00:00
|
|
|
guint32 id, GHashTable *fragment_table, guint32 frag_offset,
|
|
|
|
guint32 frag_data_len, gboolean more_frags);
|
2003-04-20 00:27:29 +00:00
|
|
|
extern fragment_data *fragment_add_multiple_ok(tvbuff_t *tvb, int offset,
|
|
|
|
packet_info *pinfo, guint32 id, GHashTable *fragment_table,
|
|
|
|
guint32 frag_offset, guint32 frag_data_len, gboolean more_frags);
|
2001-11-24 09:36:40 +00:00
|
|
|
|
We can't use the frame_data structure as a key structure when looking
for reassembled frames - in Tethereal, there's only one frame_data
structure used for all frames. Instead, use the frame number itself as
the key.
Add a "fragment_add_check()" routine, for fragments where there's a
fragment offset rather than a fragment sequence number, which does the
same sort of thing as "fragment_add_seq_check()" - i.e., once reassembly
is done, it puts the reassembled fragment into a separate hash table, so
that there're only incomplete reassemblies in the fragment hash table.
That's necessary in order to handle cases where the packet ID field can
be reused.
Use that routine for IPv4 fragment reassembly - IP IDs can be reused (in
fact, RFC 791 suggests that doing so might be a feature:
It is appropriate for some higher level protocols to choose the
identifier. For example, TCP protocol modules may retransmit an
identical TCP segment, and the probability for correct reception
would be enhanced if the retransmission carried the same identifier
as the original transmission since fragments of either datagram
could be used to construct a correct TCP segment.
and RFC 1122 says that it's permitted to do so, although it also says
"we believe that retransmitting the same Identification field is not
useful":
3.2.1.5 Identification: RFC-791 Section 3.2
When sending an identical copy of an earlier datagram, a
host MAY optionally retain the same Identification field in
the copy.
DISCUSSION:
Some Internet protocol experts have maintained that
when a host sends an identical copy of an earlier
datagram, the new copy should contain the same
Identification value as the original. There are two
suggested advantages: (1) if the datagrams are
fragmented and some of the fragments are lost, the
receiver may be able to reconstruct a complete datagram
from fragments of the original and the copies; (2) a
congested gateway might use the IP Identification field
(and Fragment Offset) to discard duplicate datagrams
from the queue.
However, the observed patterns of datagram loss in the
Internet do not favor the probability of retransmitted
fragments filling reassembly gaps, while other
mechanisms (e.g., TCP repacketizing upon
retransmission) tend to prevent retransmission of an
identical datagram [IP:9]. Therefore, we believe that
retransmitting the same Identification field is not
useful. Also, a connectionless transport protocol like
UDP would require the cooperation of the application
programs to retain the same Identification value in
identical datagrams.
and, in any case, I've seen that in at least one capture, and it
confuses the current reassembly code).
Unfortunately, that means that fragments other than the last fragment
can't be tagged with the frame number in which the reassembly was done;
see the comment in packet-ip.c for a discussion of that problem.
svn path=/trunk/; revision=7506
2003-04-20 00:11:28 +00:00
|
|
|
extern fragment_data *fragment_add_check(tvbuff_t *tvb, int offset,
|
|
|
|
packet_info *pinfo, guint32 id, GHashTable *fragment_table,
|
|
|
|
GHashTable *reassembled_table, guint32 frag_offset,
|
|
|
|
guint32 frag_data_len, gboolean more_frags);
|
|
|
|
|
2002-04-17 04:54:30 +00:00
|
|
|
/* same as fragment_add() but this one assumes frag_number is a block
|
|
|
|
sequence number. note that frag_number is 0 for the first fragment. */
|
2002-11-14 18:54:53 +00:00
|
|
|
extern fragment_data *fragment_add_seq(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
2002-04-17 04:54:30 +00:00
|
|
|
guint32 id, GHashTable *fragment_table, guint32 frag_number,
|
2001-12-15 05:40:32 +00:00
|
|
|
guint32 frag_data_len, gboolean more_frags);
|
|
|
|
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
/*
|
2002-10-24 06:17:36 +00:00
|
|
|
* These functions add a new fragment to the fragment hash table.
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
* If this is the first fragment seen for this datagram, a new
|
|
|
|
* "fragment_data" structure is allocated to refer to the reassembled,
|
|
|
|
* packet, and:
|
|
|
|
*
|
|
|
|
* if "more_frags" is false, the structure is not added to
|
|
|
|
* the hash table, and not given any fragments to refer to,
|
|
|
|
* but is just returned;
|
|
|
|
*
|
|
|
|
* if "more_frags" is true, this fragment is added to the linked
|
|
|
|
* list of fragments for this packet, and the "fragment_data"
|
|
|
|
* structure is put into the hash table.
|
|
|
|
*
|
|
|
|
* Otherwise, this fragment is just added to the linked list of fragments
|
|
|
|
* for this packet.
|
|
|
|
*
|
2002-10-24 06:17:36 +00:00
|
|
|
* They return a pointer to the head of the fragment data list, and removes
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
* that from the fragment hash table if necessary and adds it to the
|
|
|
|
* table of reassembled fragments, if we have all the fragments or if
|
|
|
|
* this is the only fragment and "more_frags" is false, returns NULL
|
|
|
|
* otherwise.
|
|
|
|
*
|
2002-10-24 06:17:36 +00:00
|
|
|
* They assumes frag_number is a block sequence number.
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
* The bsn for the first block is 0.
|
2002-10-24 06:17:36 +00:00
|
|
|
*
|
|
|
|
* "fragment_add_seq_check()" takes the sequence number as an argument;
|
|
|
|
* "fragment_add_seq_next()" is for protocols with no sequence number,
|
|
|
|
* and assumes fragments always appear in sequence.
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern fragment_data *
|
Add a separate hash table to the reassembly code for reassembled
packets, using the reassembly ID and the frame number of the final frame
as the key. There is no guarantee that reassembly IDs won't be reused,
even when talking between the same source and destination address; if,
once reassembly is complete, the "fragment_data" structure is moved to
the latter hash table, this will keep reused reassembly IDs from causing
mis-reassembly.
Add a routine "fragment_add_seq_check()", which
if a fragment has the "more fragments" flag not set but is the
first fragment of a reassembly, treats that as a non-fragmented
frame, allocating a "fragment_data" structure for the reassembly
but not attaching any fragment to it, and adding it to a
reassembled packet list;
if a packet has been reassembled, removes it from the table of
reassemblies and moves it to the table of reassembled packets;
if the frame's been seen already, looks it up in the table of
reassembled packets rather than the table of reassemblies.
Add reassembly support for fragmented 802.11 frames. Use
"fragment_add_seq_check()" to cope with the fact that some
hardware+drivers apparently hands us reassembled frames with a non-zero
fragment number and the "more fragments" bit clear (as if it puts the
802.11 header of the *last* fragment onto the reassembled data).
svn path=/trunk/; revision=5177
2002-04-17 08:25:05 +00:00
|
|
|
fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|
|
|
guint32 id, GHashTable *fragment_table,
|
|
|
|
GHashTable *reassembled_table, guint32 frag_number,
|
|
|
|
guint32 frag_data_len, gboolean more_frags);
|
|
|
|
|
2002-11-14 18:54:53 +00:00
|
|
|
extern fragment_data *
|
2002-10-24 06:17:36 +00:00
|
|
|
fragment_add_seq_next(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
|
|
|
|
GHashTable *fragment_table, GHashTable *reassembled_table,
|
|
|
|
guint32 frag_data_len, gboolean more_frags);
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
/* to specify how much to reassemble, for fragmentation where last fragment can not be
|
2001-11-24 09:36:40 +00:00
|
|
|
* identified by flags or such.
|
2001-12-15 05:40:32 +00:00
|
|
|
* note that for FD_BLOCKSEQUENCE tot_len is the index for the tail fragment.
|
2002-08-28 21:04:11 +00:00
|
|
|
* i.e. since the block numbers start at 0, if we specify tot_len==2, that
|
2001-12-15 05:40:32 +00:00
|
|
|
* actually means we want to defragment 3 blocks, block 0, 1 and 2.
|
|
|
|
*
|
2001-11-24 09:36:40 +00:00
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern void
|
2002-08-28 21:04:11 +00:00
|
|
|
fragment_set_tot_len(packet_info *pinfo, guint32 id, GHashTable *fragment_table,
|
2001-11-24 09:36:40 +00:00
|
|
|
guint32 tot_len);
|
2002-05-24 11:51:14 +00:00
|
|
|
|
|
|
|
/* to resad whatever totlen previously set */
|
2002-11-14 18:54:53 +00:00
|
|
|
extern guint32
|
2002-05-24 11:51:14 +00:00
|
|
|
fragment_get_tot_len(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
|
|
|
|
|
2002-02-03 23:28:38 +00:00
|
|
|
/*
|
|
|
|
* This function will set the partial reassembly flag(FD_PARTIAL_REASSEMBLY) for a fh.
|
|
|
|
* When this function is called, the fh MUST already exist, i.e.
|
|
|
|
* the fh MUST be created by the initial call to fragment_add() before
|
2002-08-28 21:04:11 +00:00
|
|
|
* this function is called. Also note that this function MUST be called to indicate
|
2002-02-03 23:28:38 +00:00
|
|
|
* a fh will be extended (increase the already stored data). After calling this function,
|
|
|
|
* and if FD_DEFRAGMENTED is set, the reassembly process will be continued.
|
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern void
|
2002-02-03 23:28:38 +00:00
|
|
|
fragment_set_partial_reassembly(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
|
2001-11-24 09:36:40 +00:00
|
|
|
|
|
|
|
/* This function is used to check if there is partial or completed reassembly state
|
|
|
|
* matching this packet. I.e. Are there reassembly going on or not for this packet?
|
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern fragment_data *
|
2001-11-24 09:36:40 +00:00
|
|
|
fragment_get(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
|
|
|
|
|
|
|
|
/* This will free up all resources and delete reassembly state for this PDU.
|
|
|
|
* Except if the PDU is completely reassembled, then it would NOT deallocate the
|
|
|
|
* buffer holding the reassembled data but instead return the pointer to that
|
|
|
|
* buffer.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
|
|
|
* So, if you call fragment_delete and it returns non-NULL, YOU are responsible to
|
2001-11-24 09:36:40 +00:00
|
|
|
* g_free() that buffer.
|
|
|
|
*/
|
2002-11-14 18:54:53 +00:00
|
|
|
extern unsigned char *
|
2001-11-24 09:36:40 +00:00
|
|
|
fragment_delete(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
|
2002-06-05 11:21:49 +00:00
|
|
|
|
We can't use the frame_data structure as a key structure when looking
for reassembled frames - in Tethereal, there's only one frame_data
structure used for all frames. Instead, use the frame number itself as
the key.
Add a "fragment_add_check()" routine, for fragments where there's a
fragment offset rather than a fragment sequence number, which does the
same sort of thing as "fragment_add_seq_check()" - i.e., once reassembly
is done, it puts the reassembled fragment into a separate hash table, so
that there're only incomplete reassemblies in the fragment hash table.
That's necessary in order to handle cases where the packet ID field can
be reused.
Use that routine for IPv4 fragment reassembly - IP IDs can be reused (in
fact, RFC 791 suggests that doing so might be a feature:
It is appropriate for some higher level protocols to choose the
identifier. For example, TCP protocol modules may retransmit an
identical TCP segment, and the probability for correct reception
would be enhanced if the retransmission carried the same identifier
as the original transmission since fragments of either datagram
could be used to construct a correct TCP segment.
and RFC 1122 says that it's permitted to do so, although it also says
"we believe that retransmitting the same Identification field is not
useful":
3.2.1.5 Identification: RFC-791 Section 3.2
When sending an identical copy of an earlier datagram, a
host MAY optionally retain the same Identification field in
the copy.
DISCUSSION:
Some Internet protocol experts have maintained that
when a host sends an identical copy of an earlier
datagram, the new copy should contain the same
Identification value as the original. There are two
suggested advantages: (1) if the datagrams are
fragmented and some of the fragments are lost, the
receiver may be able to reconstruct a complete datagram
from fragments of the original and the copies; (2) a
congested gateway might use the IP Identification field
(and Fragment Offset) to discard duplicate datagrams
from the queue.
However, the observed patterns of datagram loss in the
Internet do not favor the probability of retransmitted
fragments filling reassembly gaps, while other
mechanisms (e.g., TCP repacketizing upon
retransmission) tend to prevent retransmission of an
identical datagram [IP:9]. Therefore, we believe that
retransmitting the same Identification field is not
useful. Also, a connectionless transport protocol like
UDP would require the cooperation of the application
programs to retain the same Identification value in
identical datagrams.
and, in any case, I've seen that in at least one capture, and it
confuses the current reassembly code).
Unfortunately, that means that fragments other than the last fragment
can't be tagged with the frame number in which the reassembly was done;
see the comment in packet-ip.c for a discussion of that problem.
svn path=/trunk/; revision=7506
2003-04-20 00:11:28 +00:00
|
|
|
/*
|
|
|
|
* This function adds fragment_data structure to a reassembled-packet
|
2003-04-20 11:36:16 +00:00
|
|
|
* hash table, using the frame numbers of each of the frames from
|
|
|
|
* which it was reassembled as keys, and sets the "reassembled_in"
|
|
|
|
* frame number.
|
We can't use the frame_data structure as a key structure when looking
for reassembled frames - in Tethereal, there's only one frame_data
structure used for all frames. Instead, use the frame number itself as
the key.
Add a "fragment_add_check()" routine, for fragments where there's a
fragment offset rather than a fragment sequence number, which does the
same sort of thing as "fragment_add_seq_check()" - i.e., once reassembly
is done, it puts the reassembled fragment into a separate hash table, so
that there're only incomplete reassemblies in the fragment hash table.
That's necessary in order to handle cases where the packet ID field can
be reused.
Use that routine for IPv4 fragment reassembly - IP IDs can be reused (in
fact, RFC 791 suggests that doing so might be a feature:
It is appropriate for some higher level protocols to choose the
identifier. For example, TCP protocol modules may retransmit an
identical TCP segment, and the probability for correct reception
would be enhanced if the retransmission carried the same identifier
as the original transmission since fragments of either datagram
could be used to construct a correct TCP segment.
and RFC 1122 says that it's permitted to do so, although it also says
"we believe that retransmitting the same Identification field is not
useful":
3.2.1.5 Identification: RFC-791 Section 3.2
When sending an identical copy of an earlier datagram, a
host MAY optionally retain the same Identification field in
the copy.
DISCUSSION:
Some Internet protocol experts have maintained that
when a host sends an identical copy of an earlier
datagram, the new copy should contain the same
Identification value as the original. There are two
suggested advantages: (1) if the datagrams are
fragmented and some of the fragments are lost, the
receiver may be able to reconstruct a complete datagram
from fragments of the original and the copies; (2) a
congested gateway might use the IP Identification field
(and Fragment Offset) to discard duplicate datagrams
from the queue.
However, the observed patterns of datagram loss in the
Internet do not favor the probability of retransmitted
fragments filling reassembly gaps, while other
mechanisms (e.g., TCP repacketizing upon
retransmission) tend to prevent retransmission of an
identical datagram [IP:9]. Therefore, we believe that
retransmitting the same Identification field is not
useful. Also, a connectionless transport protocol like
UDP would require the cooperation of the application
programs to retain the same Identification value in
identical datagrams.
and, in any case, I've seen that in at least one capture, and it
confuses the current reassembly code).
Unfortunately, that means that fragments other than the last fragment
can't be tagged with the frame number in which the reassembly was done;
see the comment in packet-ip.c for a discussion of that problem.
svn path=/trunk/; revision=7506
2003-04-20 00:11:28 +00:00
|
|
|
*/
|
|
|
|
extern void
|
|
|
|
fragment_reassembled(fragment_data *fd_head, packet_info *pinfo,
|
|
|
|
GHashTable *reassembled_table);
|
2002-06-05 11:21:49 +00:00
|
|
|
|
2003-04-20 11:36:16 +00:00
|
|
|
/* hf_fragment, hf_fragment_error, and hf_reassembled_in should be
|
|
|
|
FT_FRAMENUM, the others should be FT_BOOLEAN
|
2002-12-19 11:22:38 +00:00
|
|
|
*/
|
2002-06-05 11:21:49 +00:00
|
|
|
typedef struct _fragment_items {
|
2002-08-28 21:04:11 +00:00
|
|
|
gint *ett_fragment;
|
2002-06-05 11:21:49 +00:00
|
|
|
gint *ett_fragments;
|
|
|
|
|
|
|
|
int *hf_fragments;
|
|
|
|
int *hf_fragment;
|
|
|
|
int *hf_fragment_overlap;
|
|
|
|
int *hf_fragment_overlap_conflict;
|
|
|
|
int *hf_fragment_multiple_tails;
|
|
|
|
int *hf_fragment_too_long_fragment;
|
|
|
|
int *hf_fragment_error;
|
2003-04-20 11:36:16 +00:00
|
|
|
int *hf_reassembled_in;
|
2002-06-07 10:11:41 +00:00
|
|
|
|
|
|
|
char *tag;
|
2002-06-05 11:21:49 +00:00
|
|
|
} fragment_items;
|
2002-06-07 10:11:41 +00:00
|
|
|
|
2003-04-20 08:06:01 +00:00
|
|
|
extern tvbuff_t *
|
|
|
|
process_reassembled_data(tvbuff_t *tvb, packet_info *pinfo, char *name,
|
2003-04-20 11:36:16 +00:00
|
|
|
fragment_data *fd_head, const fragment_items *fit,
|
|
|
|
gboolean *update_col_infop, proto_tree *tree);
|
2003-04-20 08:06:01 +00:00
|
|
|
|
2002-06-07 10:11:41 +00:00
|
|
|
extern gboolean
|
2002-10-24 06:17:36 +00:00
|
|
|
show_fragment_tree(fragment_data *ipfd_head, const fragment_items *fit,
|
2002-06-07 10:11:41 +00:00
|
|
|
proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb);
|
|
|
|
|
|
|
|
extern gboolean
|
2002-10-24 06:17:36 +00:00
|
|
|
show_fragment_seq_tree(fragment_data *ipfd_head, const fragment_items *fit,
|
2002-06-07 10:11:41 +00:00
|
|
|
proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb);
|