Ethereal-dev: Re: [Ethereal-dev] AIX 'iptrace' format and FDDI

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

From: Guy Harris <guy@xxxxxxxxxx>
Date: Fri, 1 Nov 2002 12:44:56 -0800
On Fri, Nov 01, 2002 at 08:24:31PM +0100, Martin Regner wrote:
> Guy is correct.
> There seems to be 3 bytes of padding in front of the raw FDDI data (50
> 10 00 5a ...)

I've checked in a change that skips those 3 bytes in FDDI captures, so
it'll be in the next release.  I've attached the patch to
"wiretap/iptrace.c", in case the person who sent the capture built
Ethereal from source.
Index: wiretap/iptrace.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/wiretap/iptrace.c,v
retrieving revision 1.44
diff -c -r1.44 wiretap/iptrace.c
*** wiretap/iptrace.c	28 Aug 2002 20:30:44 -0000	1.44
--- wiretap/iptrace.c	1 Nov 2002 20:38:39 -0000
***************
*** 87,93 ****
   * iptrace 1.0                                             *
   ***********************************************************/
  
! /* iptrace 1.0, discovered through inspection */
  typedef struct {
  /* 0-3 */	guint32		pkt_length;	/* packet length + 0x16 */
  /* 4-7 */	guint32		tv_sec;		/* time stamp, seconds since the Epoch */
--- 87,110 ----
   * iptrace 1.0                                             *
   ***********************************************************/
  
! /*
!  * iptrace 1.0, discovered through inspection
!  *
!  * Packet record contains:
!  *
!  *	an initial header, with a length field and a time stamp, in
!  *	seconds since the Epoch;
!  *
!  *	data, with the specified length.
!  *
!  * The data contains:
!  *
!  *	a bunch of information about the packet;
!  *
!  *	padding, at least for FDDI;
!  *
!  *	the raw packet data.
!  */
  typedef struct {
  /* 0-3 */	guint32		pkt_length;	/* packet length + 0x16 */
  /* 4-7 */	guint32		tv_sec;		/* time stamp, seconds since the Epoch */
***************
*** 98,123 ****
  /* 29 */	guint8		tx_flag;	/* 0=receive, 1=transmit */
  } iptrace_1_0_phdr;
  
  /* Read the next packet */
  static gboolean iptrace_read_1_0(wtap *wth, int *err, long *data_offset)
  {
  	int			ret;
  	guint32			packet_size;
! 	guint8			header[30];
  	guint8			*data_ptr;
  	iptrace_1_0_phdr	pkt_hdr;
  
  	/* Read the descriptor data */
  	*data_offset = wth->data_offset;
! 	ret = iptrace_read_rec_header(wth->fh, header, 30, err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		return FALSE;
  	}
! 	wth->data_offset += 30;
  
  	/* Read the packet data */
! 	packet_size = pntohl(&header[0]) - 0x16;
  	buffer_assure_space( wth->frame_buffer, packet_size );
  	data_ptr = buffer_start_ptr( wth->frame_buffer );
  	if (!iptrace_read_rec_data(wth->fh, data_ptr, packet_size, err))
--- 115,173 ----
  /* 29 */	guint8		tx_flag;	/* 0=receive, 1=transmit */
  } iptrace_1_0_phdr;
  
+ #define IPTRACE_1_0_PHDR_SIZE	30	/* initial header plus packet data */
+ #define IPTRACE_1_0_PDATA_SIZE	22	/* packet data */
+ 
  /* Read the next packet */
  static gboolean iptrace_read_1_0(wtap *wth, int *err, long *data_offset)
  {
  	int			ret;
  	guint32			packet_size;
! 	guint8			header[IPTRACE_1_0_PHDR_SIZE];
  	guint8			*data_ptr;
  	iptrace_1_0_phdr	pkt_hdr;
+ 	char			fddi_padding[3];
  
  	/* Read the descriptor data */
  	*data_offset = wth->data_offset;
! 	ret = iptrace_read_rec_header(wth->fh, header, IPTRACE_1_0_PHDR_SIZE,
! 	    err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		return FALSE;
  	}
! 	wth->data_offset += IPTRACE_1_0_PHDR_SIZE;
! 
! 	/*
! 	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
! 	 * value giving the type of the interface.  Check out the
! 	 * <net/if_types.h> header file.
! 	 */
! 	pkt_hdr.if_type = header[28];
! 	wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
  
  	/* Read the packet data */
! 	packet_size = pntohl(&header[0]) - IPTRACE_1_0_PDATA_SIZE;
! 
! 	/*
! 	 * AIX appears to put 3 bytes of padding in front of FDDI
! 	 * frames; strip that crap off.
! 	 */
! 	if (wth->phdr.pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
! 		/*
! 		 * The packet size is really a record size and includes
! 		 * the padding.
! 		 */
! 		packet_size -= 3;
! 		wth->data_offset += 3;
! 
! 		/*
! 		 * Read the padding.
! 		 */
! 		if (!iptrace_read_rec_data(wth->fh, fddi_padding, 3, err))
! 			return FALSE;	/* Read error */
! 	}
! 
  	buffer_assure_space( wth->frame_buffer, packet_size );
  	data_ptr = buffer_start_ptr( wth->frame_buffer );
  	if (!iptrace_read_rec_data(wth->fh, data_ptr, packet_size, err))
***************
*** 129,142 ****
  	wth->phdr.ts.tv_sec = pntohl(&header[4]);
  	wth->phdr.ts.tv_usec = 0;
  
- 	/*
- 	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
- 	 * value giving the type of the interface.  Check out the
- 	 * <net/if_types.h> header file.
- 	 */
- 	pkt_hdr.if_type = header[28];
- 	wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
- 
  	if (wth->phdr.pkt_encap == WTAP_ENCAP_UNKNOWN) {
  		g_message("iptrace: interface type IFT=0x%02x unknown or unsupported",
  		    pkt_hdr.if_type);
--- 179,184 ----
***************
*** 170,182 ****
      int *err)
  {
  	int			ret;
! 	guint8			header[30];
  
  	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
  		return FALSE;
  
  	/* Read the descriptor data */
! 	ret = iptrace_read_rec_header(wth->random_fh, header, 30, err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		if (ret == 0) {
--- 212,227 ----
      int *err)
  {
  	int			ret;
! 	guint8			header[IPTRACE_1_0_PHDR_SIZE];
! 	int			pkt_encap;
! 	char			fddi_padding[3];
  
  	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
  		return FALSE;
  
  	/* Read the descriptor data */
! 	ret = iptrace_read_rec_header(wth->random_fh, header,
! 	    IPTRACE_1_0_PHDR_SIZE, err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		if (ret == 0) {
***************
*** 186,197 ****
  		return FALSE;
  	}
  
  	/* Get the packet data */
  	if (!iptrace_read_rec_data(wth->random_fh, pd, packet_size, err))
  		return FALSE;
  
  	/* Get the ATM pseudo-header, if this is ATM traffic. */
! 	if (wtap_encap_ift(header[28]) == WTAP_ENCAP_ATM_SNIFFER)
  		get_atm_pseudo_header(pd, packet_size, pseudo_header, header);
  
  	return TRUE;
--- 231,259 ----
  		return FALSE;
  	}
  
+ 	/*
+ 	 * Get the interface type.
+ 	 */
+ 	pkt_encap = wtap_encap_ift(header[28]);
+ 
+ 	/*
+ 	 * AIX appears to put 3 bytes of padding in front of FDDI
+ 	 * frames; strip that crap off.
+ 	 */
+ 	if (pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
+ 		/*
+ 		 * Read the padding.
+ 		 */
+ 		if (!iptrace_read_rec_data(wth->random_fh, fddi_padding, 3, err))
+ 			return FALSE;	/* Read error */
+ 	}
+ 
  	/* Get the packet data */
  	if (!iptrace_read_rec_data(wth->random_fh, pd, packet_size, err))
  		return FALSE;
  
  	/* Get the ATM pseudo-header, if this is ATM traffic. */
! 	if (pkt_encap == WTAP_ENCAP_ATM_SNIFFER)
  		get_atm_pseudo_header(pd, packet_size, pseudo_header, header);
  
  	return TRUE;
***************
*** 201,207 ****
   * iptrace 2.0                                             *
   ***********************************************************/
  
! /* iptrace 2.0, discovered through inspection */
  typedef struct {
  /* 0-3 */	guint32		pkt_length;	/* packet length + 32 */
  /* 4-7 */	guint32		tv_sec0;	/* time stamp, seconds since the Epoch */
--- 263,286 ----
   * iptrace 2.0                                             *
   ***********************************************************/
  
! /*
!  * iptrace 2.0, discovered through inspection
!  *
!  * Packet record contains:
!  *
!  *	an initial header, with a length field and a time stamp, in
!  *	seconds since the Epoch;
!  *
!  *	data, with the specified length.
!  *
!  * The data contains:
!  *
!  *	a bunch of information about the packet;
!  *
!  *	padding, at least for FDDI;
!  *
!  *	the raw packet data.
!  */
  typedef struct {
  /* 0-3 */	guint32		pkt_length;	/* packet length + 32 */
  /* 4-7 */	guint32		tv_sec0;	/* time stamp, seconds since the Epoch */
***************
*** 215,240 ****
  /* 36-39 */	guint32		tv_nsec;	/* nanoseconds since that second */
  } iptrace_2_0_phdr;
  
  /* Read the next packet */
  static gboolean iptrace_read_2_0(wtap *wth, int *err, long *data_offset)
  {
  	int			ret;
  	guint32			packet_size;
! 	guint8			header[40];
  	guint8			*data_ptr;
  	iptrace_2_0_phdr	pkt_hdr;
  
  	/* Read the descriptor data */
  	*data_offset = wth->data_offset;
! 	ret = iptrace_read_rec_header(wth->fh, header, 40, err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		return FALSE;
  	}
! 	wth->data_offset += 40;
  
  	/* Read the packet data */
! 	packet_size = pntohl(&header[0]) - 32;
  	buffer_assure_space( wth->frame_buffer, packet_size );
  	data_ptr = buffer_start_ptr( wth->frame_buffer );
  	if (!iptrace_read_rec_data(wth->fh, data_ptr, packet_size, err))
--- 294,352 ----
  /* 36-39 */	guint32		tv_nsec;	/* nanoseconds since that second */
  } iptrace_2_0_phdr;
  
+ #define IPTRACE_2_0_PHDR_SIZE	40	/* initial header plus packet data */
+ #define IPTRACE_2_0_PDATA_SIZE	32	/* packet data */
+ 
  /* Read the next packet */
  static gboolean iptrace_read_2_0(wtap *wth, int *err, long *data_offset)
  {
  	int			ret;
  	guint32			packet_size;
! 	guint8			header[IPTRACE_2_0_PHDR_SIZE];
  	guint8			*data_ptr;
  	iptrace_2_0_phdr	pkt_hdr;
+ 	char			fddi_padding[3];
  
  	/* Read the descriptor data */
  	*data_offset = wth->data_offset;
! 	ret = iptrace_read_rec_header(wth->fh, header, IPTRACE_2_0_PHDR_SIZE,
! 	    err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		return FALSE;
  	}
! 	wth->data_offset += IPTRACE_2_0_PHDR_SIZE;
! 
! 	/*
! 	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
! 	 * value giving the type of the interface.  Check out the
! 	 * <net/if_types.h> header file.
! 	 */
! 	pkt_hdr.if_type = header[28];
! 	wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
  
  	/* Read the packet data */
! 	packet_size = pntohl(&header[0]) - IPTRACE_2_0_PDATA_SIZE;
! 
! 	/*
! 	 * AIX appears to put 3 bytes of padding in front of FDDI
! 	 * frames; strip that crap off.
! 	 */
! 	if (wth->phdr.pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
! 		/*
! 		 * The packet size is really a record size and includes
! 		 * the padding.
! 		 */
! 		packet_size -= 3;
! 		wth->data_offset += 3;
! 
! 		/*
! 		 * Read the padding.
! 		 */
! 		if (!iptrace_read_rec_data(wth->fh, fddi_padding, 3, err))
! 			return FALSE;	/* Read error */
! 	}
! 
  	buffer_assure_space( wth->frame_buffer, packet_size );
  	data_ptr = buffer_start_ptr( wth->frame_buffer );
  	if (!iptrace_read_rec_data(wth->fh, data_ptr, packet_size, err))
***************
*** 250,263 ****
  	wth->phdr.ts.tv_sec = pntohl(&header[32]);
  	wth->phdr.ts.tv_usec = pntohl(&header[36]) / 1000;
  
- 	/*
- 	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
- 	 * value giving the type of the interface.  Check out the
- 	 * <net/if_types.h> header file.
- 	 */
- 	pkt_hdr.if_type = header[28];
- 	wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
- 
  	if (wth->phdr.pkt_encap == WTAP_ENCAP_UNKNOWN) {
  		g_message("iptrace: interface type IFT=0x%02x unknown or unsupported",
  		    pkt_hdr.if_type);
--- 362,367 ----
***************
*** 291,303 ****
      int *err)
  {
  	int			ret;
! 	guint8			header[40];
  
  	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
  		return FALSE;
  
  	/* Read the descriptor data */
! 	ret = iptrace_read_rec_header(wth->random_fh, header, 40, err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		if (ret == 0) {
--- 395,410 ----
      int *err)
  {
  	int			ret;
! 	guint8			header[IPTRACE_2_0_PHDR_SIZE];
! 	int			pkt_encap;
! 	char			fddi_padding[3];
  
  	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
  		return FALSE;
  
  	/* Read the descriptor data */
! 	ret = iptrace_read_rec_header(wth->random_fh, header,
! 	    IPTRACE_2_0_PHDR_SIZE, err);
  	if (ret <= 0) {
  		/* Read error or EOF */
  		if (ret == 0) {
***************
*** 307,318 ****
  		return FALSE;
  	}
  
  	/* Get the packet data */
  	if (!iptrace_read_rec_data(wth->random_fh, pd, packet_size, err))
  		return FALSE;
  
  	/* Get the ATM pseudo-header, if this is ATM traffic. */
! 	if (wtap_encap_ift(header[28]) == WTAP_ENCAP_ATM_SNIFFER)
  		get_atm_pseudo_header(pd, packet_size, pseudo_header, header);
  
  	return TRUE;
--- 414,442 ----
  		return FALSE;
  	}
  
+ 	/*
+ 	 * Get the interface type.
+ 	 */
+ 	pkt_encap = wtap_encap_ift(header[28]);
+ 
+ 	/*
+ 	 * AIX appears to put 3 bytes of padding in front of FDDI
+ 	 * frames; strip that crap off.
+ 	 */
+ 	if (pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
+ 		/*
+ 		 * Read the padding.
+ 		 */
+ 		if (!iptrace_read_rec_data(wth->random_fh, fddi_padding, 3, err))
+ 			return FALSE;	/* Read error */
+ 	}
+ 
  	/* Get the packet data */
  	if (!iptrace_read_rec_data(wth->random_fh, pd, packet_size, err))
  		return FALSE;
  
  	/* Get the ATM pseudo-header, if this is ATM traffic. */
! 	if (pkt_encap == WTAP_ENCAP_ATM_SNIFFER)
  		get_atm_pseudo_header(pd, packet_size, pseudo_header, header);
  
  	return TRUE;