Skip to content

Commit

Permalink
Fixes to the TCP reassembly code to correctly handle too short
Browse files Browse the repository at this point in the history
caplen or incomplete data (avoid crashes or erroneous display).

svn path=/trunk/; revision=227
  • Loading branch information
ldeniel committed Mar 23, 1999
1 parent 6cbabed commit 210d386
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 13 deletions.
10 changes: 8 additions & 2 deletions ethereal.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ethereal.c
*
* $Id: ethereal.c,v 1.25 1999/03/23 03:14:33 gram Exp $
* $Id: ethereal.c,v 1.26 1999/03/23 20:25:50 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -191,7 +191,13 @@ follow_stream_cb( GtkWidget *w, gpointer data ) {
NULL, "WM destroy" );
gtk_signal_connect( GTK_OBJECT(streamwindow), "destroy",
NULL, "WM destroy" );
gtk_window_set_title( GTK_WINDOW(streamwindow), "Contents of TCP stream" );
if( incomplete_tcp_stream ) {
gtk_window_set_title( GTK_WINDOW(streamwindow),
"Contents of TCP stream (incomplete)" );
} else {
gtk_window_set_title( GTK_WINDOW(streamwindow),
"Contents of TCP stream" );
}
gtk_widget_set_usize( GTK_WIDGET(streamwindow), DEF_WIDTH, DEF_HEIGHT );
gtk_container_border_width( GTK_CONTAINER(streamwindow), 2 );
/* setup the container */
Expand Down
42 changes: 34 additions & 8 deletions follow.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* follow.c
*
* $Id: follow.c,v 1.5 1998/12/17 05:42:25 gram Exp $
* $Id: follow.c,v 1.6 1999/03/23 20:25:49 deniel Exp $
*
* Copyright 1998 Mike Hall <mlh@io.com>
*
Expand Down Expand Up @@ -45,6 +45,8 @@

extern FILE* data_out_file;

gboolean incomplete_tcp_stream = FALSE;

/* this will build libpcap filter text that will only
pass the packets related to the stream. There is a
chance that two streams could intersect, but not a
Expand Down Expand Up @@ -73,7 +75,7 @@ static u_long seq[2];
static u_long src[2] = { 0, 0 };

void
reassemble_tcp( u_long sequence, u_long length, const char* data, int synflag, u_long srcx ) {
reassemble_tcp( u_long sequence, u_long length, const char* data, u_long data_length, int synflag, u_long srcx ) {
int src_index, j, first = 0;
u_long newseq;
tcp_frag *tmp_frag;
Expand All @@ -100,6 +102,11 @@ reassemble_tcp( u_long sequence, u_long length, const char* data, int synflag, u
fprintf( stderr, "ERROR in reassemble_tcp: Too many addresses!\n");
return;
}

if( data_length < length ) {
incomplete_tcp_stream = TRUE;
}

/* now that we have filed away the srcs, lets get the sequence number stuff
figured out */
if( first ) {
Expand All @@ -109,7 +116,7 @@ reassemble_tcp( u_long sequence, u_long length, const char* data, int synflag, u
seq[src_index]++;
}
/* write out the packet data */
write_packet_data( data, length );
write_packet_data( data, data_length );
return;
}
/* if we are here, we have already seen this src, let's
Expand All @@ -120,19 +127,34 @@ reassemble_tcp( u_long sequence, u_long length, const char* data, int synflag, u
info than we have already seen */
newseq = sequence + length;
if( newseq > seq[src_index] ) {
u_long new_len;

/* this one has more than we have seen. let's get the
payload that we have not seen. */
data += ( seq[src_index] - sequence );

new_len = seq[src_index] - sequence;

if ( data_length <= new_len ) {
data = NULL;
data_length = 0;
incomplete_tcp_stream = TRUE;
} else {
data += new_len;
data_length -= new_len;
}
sequence = seq[src_index];
length = newseq - seq[src_index];

/* this will now appear to be right on time :) */
}
}
if ( sequence == seq[src_index] ) {
/* right on time */
seq[src_index] += length;
if( synflag ) seq[src_index]++;
write_packet_data( data, length );
if( data ) {
write_packet_data( data, data_length );
}
/* done with the packet, see if it caused a fragment to fit */
while( check_fragments( src_index ) )
;
Expand All @@ -141,10 +163,11 @@ reassemble_tcp( u_long sequence, u_long length, const char* data, int synflag, u
/* out of order packet */
if( sequence > seq[src_index] ) {
tmp_frag = (tcp_frag *)malloc( sizeof( tcp_frag ) );
tmp_frag->data = (u_char *)malloc( length );
tmp_frag->data = (u_char *)malloc( data_length );
tmp_frag->seq = sequence;
tmp_frag->len = length;
memcpy( tmp_frag->data, data, length );
tmp_frag->data_len = data_length;
memcpy( tmp_frag->data, data, data_length );
if( frags[src_index] ) {
tmp_frag->next = frags[src_index];
} else {
Expand All @@ -165,7 +188,9 @@ check_fragments( int index ) {
while( current ) {
if( current->seq == seq[index] ) {
/* this fragment fits the stream */
write_packet_data( current->data, current->len );
if( current->data ) {
write_packet_data( current->data, current->data_len );
}
seq[index] += current->len;
if( prev ) {
prev->next = current->next;
Expand All @@ -187,6 +212,7 @@ void
reset_tcp_reassembly() {
tcp_frag *current, *next;
int i;
incomplete_tcp_stream = FALSE;
for( i=0; i<2; i++ ) {
seq[i] = 0;
src[i] = 0;
Expand Down
7 changes: 5 additions & 2 deletions follow.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* follow.h
*
* $Id: follow.h,v 1.2 1998/09/27 22:12:26 gerald Exp $
* $Id: follow.h,v 1.3 1999/03/23 20:25:50 deniel Exp $
*
* Copyright 1998 Mike Hall <mlh@io.com>
*
Expand Down Expand Up @@ -30,15 +30,18 @@

#include "packet.h"

extern gboolean incomplete_tcp_stream;

typedef struct _tcp_frag {
u_long seq;
u_long len;
u_long data_len;
u_char *data;
struct _tcp_frag *next;
} tcp_frag;

char* build_follow_filter( packet_info * );
void reassemble_tcp( u_long, u_long, const char*, int, u_long );
void reassemble_tcp( u_long, u_long, const char*, u_long, int, u_long );
int check_fragments( int );
void reset_tcp_reassembly( void );
void write_packet_data( const u_char *, int );
Expand Down
3 changes: 2 additions & 1 deletion packet-tcp.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* packet-tcp.c
* Routines for TCP packet disassembly
*
* $Id: packet-tcp.c,v 1.17 1999/03/23 03:58:59 guy Exp $
* $Id: packet-tcp.c,v 1.18 1999/03/23 20:25:50 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -469,6 +469,7 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
reassemble_tcp( th.th_seq, /* sequence number */
( pi.iplen -( pi.iphdrlen * 4 )-( hi_nibble(th.th_off_x2) * 4 ) ), /* length */
( pd+offset ), /* data */
( fd->cap_len - offset ), /* captured data length */
( th.th_flags & 0x02 ), /* is syn set? */
pi.ip_src ); /* src ip */
}
Expand Down

0 comments on commit 210d386

Please sign in to comment.