Ethereal-dev: Re: [ethereal-dev] Ethereal segfault

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Sat, 11 Mar 2000 20:40:09 -0800
> I applied both patches, and can report that the cordumps have gone.
> However, with the attached capture file, if I do follow TCP stream,
> I get to see the requests,but not the IPP responses (HTTP/1.0 OK).
> I see the packets allright, but they aren't included in the stream.
> 
> Is that how it should be ?

No.

The problem is that the "follow TCP stream" code was looking only at the
IP address to determine to which side of the connection a packet
belonged; that doesn't work if both sides of the connection have the
*same* IP address, i.e. if it's a conversation between two ports on the
same machine.

I've checked in a fix, making it look at both the IP address *and* the
port number.

I've attached a patch (don't apply this patch to the code in the CVS
tree, as that code includes this patch and some other changes, just
apply it to a released tree) with the fix in question.

(Hopefully, this mail will get to you - all mail I've tried sending in
the past has bounced....)
Index: follow.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/follow.c,v
retrieving revision 1.20
diff -c -r1.20 follow.c
*** follow.c	1999/12/10 04:25:59	1.20
--- follow.c	2000/03/12 04:37:39
***************
*** 87,93 ****
  
  static tcp_frag *frags[2] = { 0, 0};
  static u_long seq[2];
! static guint32 src[2] = { 0, 0 };
  
  void 
  reassemble_tcp( u_long sequence, u_long length, const char* data,
--- 87,94 ----
  
  static tcp_frag *frags[2] = { 0, 0};
  static u_long seq[2];
! static guint32 src_addr[2] = { 0, 0 };
! static u_int src_port[2] = { 0, 0 };
  
  void 
  reassemble_tcp( u_long sequence, u_long length, const char* data,
***************
*** 120,128 ****
    sc.usecs    = usecs;
    sc.dlen     = data_length;
  
!   /* first we check to see if we have seen this src ip before. */
    for( j=0; j<2; j++ ) {
!     if( src[j] == srcx ) {
        src_index = j;
      }
    }
--- 121,131 ----
    sc.usecs    = usecs;
    sc.dlen     = data_length;
  
!   /* Check to see if we have seen this source IP and port before.
!      (Yes, we have to check both source IP and port; the connection
!      might be between two different ports on the same machine.) */
    for( j=0; j<2; j++ ) {
!     if( src_addr[j] == srcx && src_port[j] == srcport ) {
        src_index = j;
      }
    }
***************
*** 130,137 ****
    if( src_index < 0 ) {
      /* assign it to a src_index and get going */
      for( j=0; j<2; j++ ) {
!       if( src[j] == 0 ) {
! 	src[j] = srcx;
  	src_index = j;
  	first = 1;
  	break;
--- 133,141 ----
    if( src_index < 0 ) {
      /* assign it to a src_index and get going */
      for( j=0; j<2; j++ ) {
!       if( src_addr[j] == 0 ) {
! 	src_addr[j] = srcx;
! 	src_port[j] = srcport;
  	src_index = j;
  	first = 1;
  	break;
***************
*** 256,262 ****
    incomplete_tcp_stream = FALSE;
    for( i=0; i<2; i++ ) {
      seq[i] = 0;
!     src[i] = 0;
      ip_address[i] = 0;
      tcp_port[i] = 0;
      current = frags[i];
--- 260,267 ----
    incomplete_tcp_stream = FALSE;
    for( i=0; i<2; i++ ) {
      seq[i] = 0;
!     src_addr[i] = 0;
!     src_port[i] = 0;
      ip_address[i] = 0;
      tcp_port[i] = 0;
      current = frags[i];