Ethereal-users: Re: [ethereal-users] Problem reading a capture produced by MS Netmon 5.00.646

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: Wed, 22 Mar 2000 01:51:47 -0800
> > I've attached the patch; it should be applied to the Ethereal source, in
> > the "wiretap" directory.
> 
> I have just patched and recompiled Ethereal, and now the capture file is
> correctly decoded !
> Thanks a lot, you have been amazingly fast !!

Perhaps a little too fast; I forgot that the frame table has to be
byte-swapped on big-endian machines.

I suspect you're probably using a PC, in which case you have a
little-endian processor and thus aren't bitten by that bug, but, for
those reading those capture files on big-endian machines, I've attached
a patch to fix that (it also frees the frame table a little earlier; I
may be redoing Ethereal in ways that require it to leave the capture
file open with Wiretap even after reading the entire file, and freeing
the frame table as soon as it is at the end of the sequential pass
through the frames can save some memory).

(I may also look into handling the statistics pseudo-frame in Wiretap at
some point.)
Index: netmon.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/wiretap/netmon.c,v
retrieving revision 1.26
diff -c -r1.26 netmon.c
*** netmon.c	2000/03/22 07:06:54	1.26
--- netmon.c	2000/03/22 09:47:35
***************
*** 124,129 ****
--- 124,131 ----
  	struct tm tm;
  	int frame_table_offset;
  	guint32 frame_table_length;
+ 	int frame_table_size;
+ 	guint32 *frame_table;
  
  	/* Read in the string that should be at the start of a Network
  	 * Monitor file */
***************
*** 231,261 ****
  	 * in it as the offsets of the frames.
  	 */
  	frame_table_length = pletohl(&hdr.frametablelength);
! 	wth->capture.netmon->frame_table_size = frame_table_length / sizeof (guint32);
! 	if ((wth->capture.netmon->frame_table_size * sizeof (guint32)) != frame_table_length) {
  		g_message("netmon: frame table length is %u, which is not a multiple of the size of an entry",
  		    frame_table_length);
  		*err = WTAP_ERR_UNSUPPORTED;
  		return -1;
  	}
! 	if (wth->capture.netmon->frame_table_size == 0) {
  		g_message("netmon: frame table length is %u, which means it's less than one entry in size",
  		    frame_table_length);
  		*err = WTAP_ERR_UNSUPPORTED;
  		return -1;
  	}
! 	wth->capture.netmon->frame_table = g_malloc(frame_table_length);
  	errno = WTAP_ERR_CANT_READ;
  	file_seek(wth->fh, frame_table_offset, SEEK_SET);
! 	bytes_read = file_read(wth->capture.netmon->frame_table, 1,
! 	    frame_table_length, wth->fh);
  	if (bytes_read != frame_table_length) {
  		*err = file_error(wth->fh);
  		if (*err != 0)
  			return -1;
  		return 0;
  	}
  
  	/* Set up to start reading at the first frame. */
  	wth->capture.netmon->current_frame = 0;
  
--- 233,272 ----
  	 * in it as the offsets of the frames.
  	 */
  	frame_table_length = pletohl(&hdr.frametablelength);
! 	frame_table_size = frame_table_length / sizeof (guint32);
! 	if ((frame_table_size * sizeof (guint32)) != frame_table_length) {
  		g_message("netmon: frame table length is %u, which is not a multiple of the size of an entry",
  		    frame_table_length);
  		*err = WTAP_ERR_UNSUPPORTED;
  		return -1;
  	}
! 	if (frame_table_size == 0) {
  		g_message("netmon: frame table length is %u, which means it's less than one entry in size",
  		    frame_table_length);
  		*err = WTAP_ERR_UNSUPPORTED;
  		return -1;
  	}
! 	frame_table = g_malloc(frame_table_length);
  	errno = WTAP_ERR_CANT_READ;
  	file_seek(wth->fh, frame_table_offset, SEEK_SET);
! 	bytes_read = file_read(frame_table, 1, frame_table_length, wth->fh);
  	if (bytes_read != frame_table_length) {
  		*err = file_error(wth->fh);
  		if (*err != 0)
  			return -1;
  		return 0;
  	}
+ 	wth->capture.netmon->frame_table_size = frame_table_size;
+ 	wth->capture.netmon->frame_table = frame_table;
  
+ #ifdef WORDS_BIGENDIAN
+ 	/*
+ 	 * OK, now byte-swap the frame table.
+ 	 */
+ 	for (i = 0; i < frame_table_size; i++)
+ 		frame_table[i] = pletohl(&frame_table[i]);
+ #endif
+ 
  	/* Set up to start reading at the first frame. */
  	wth->capture.netmon->current_frame = 0;
  
***************
*** 280,286 ****
  
  	/* Have we reached the end of the packet data? */
  	if (netmon->current_frame >= netmon->frame_table_size) {
! 		/* Yes. */
  		return 0;
  	}
  
--- 291,300 ----
  
  	/* Have we reached the end of the packet data? */
  	if (netmon->current_frame >= netmon->frame_table_size) {
! 		/* Yes.  We won't need the frame table any more;
! 		   free it. */
! 		g_free(wth->capture.netmon->frame_table);
! 		wth->capture.netmon->frame_table = NULL;
  		return 0;
  	}
  
***************
*** 390,396 ****
  static void
  netmon_close(wtap *wth)
  {
! 	g_free(wth->capture.netmon->frame_table);
  	g_free(wth->capture.netmon);
  }
  
--- 404,411 ----
  static void
  netmon_close(wtap *wth)
  {
! 	if (wth->capture.netmon->frame_table != NULL)
! 		g_free(wth->capture.netmon->frame_table);
  	g_free(wth->capture.netmon);
  }