Ethereal-users: Re: [Ethereal-users] Strange capture file.

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: Mon, 4 Feb 2002 16:15:56 -0800 (PST)
> I have got a problem using tethereal.
> I am capturing icmpv6 packets in a file, using the following syntax:
> tethereal -c 10 -i atm0 -w capture.pcap
> 
> Sometimes, tethereal and ethereal seem unable to read the capture file
> as v6 packets:

The code for handling "raw IP" captures was assuming that "raw IP" meant
"raw IPv4"; I've checked in a change to make it check the IP version
number field and treat the data as IPv4 or IPv6 or "other" depending on
the version number.

BTW, on what OS were you running this, and what version of libpcap did
you have? The current version of libpcap from tcpdump.org uses "raw IP"
as a capture type only for:

	some link-layer types it can't handle in BSD/OS;

	SLIP, and some tunnel interfaces, on Linux;

	PPP interfaces on Irix;

so I wouldn't expect it to treat what I assume, from the name, is an ATM
interface as "raw IP".

> I tried to dump the packet using tcpdump:
> --------------------------------------------------------------------------------------------
> 
> tcpdump6 -r capture_bug.pcap -vvvv -s 1000
> 
> 20:17:04.313283 3ffe:304:124:2220:0:0:0:51 >
> 3ffe:304:124:2420:0:0:0:139: icmp: echo request 60162/0 [ttl 254]

The current tcpdump.org tcpdump does what Ethereal now also does.

I've attached a patch to "packet-raw.c" in the current version of
Ethereal, which adds the change I checked in.
Index: packet-raw.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-raw.c,v
retrieving revision 1.32
diff -c -r1.32 packet-raw.c
*** packet-raw.c	2002/01/21 07:36:40	1.32
--- packet-raw.c	2002/02/05 00:07:17
***************
*** 45,50 ****
--- 45,52 ----
  static const char zeroes[10];
  
  static dissector_handle_t ip_handle;
+ static dissector_handle_t ipv6_handle;
+ static dissector_handle_t data_handle;
  static dissector_handle_t ppp_hdlc_handle;
  
  void
***************
*** 76,82 ****
      capture_ip(pd, 10, len, ld);
    }
    else {
!     capture_ip(pd, 0, len, ld);
    }
  }
  
--- 78,102 ----
      capture_ip(pd, 10, len, ld);
    }
    else {
!     /* 
!      * OK, is this IPv4 or IPv6?
!      */
!     if (BYTES_ARE_IN_FRAME(0,len,1)) {
!       switch (pd[0] & 0xF0) {
! 
!       case 0x40:
!         /* IPv4 */
!         capture_ip(pd, 0, len, ld);
!         break;
! 
! #if 0
!       case 0x60:
!         /* IPv6 */
!         capture_ipv6(pd, 0, len, ld);
!         break;
! #endif
!       }
!     }
    }
  }
  
***************
*** 116,149 ****
     */
    if (tvb_get_ntohs(tvb, 0) == 0xff03) {
  	call_dissector(ppp_hdlc_handle, tvb, pinfo, tree);
- 	return;
    }
    /* The Linux ISDN driver sends a fake MAC address before the PPP header
     * on its ippp interfaces... */
    else if (tvb_get_ntohs(tvb, 6) == 0xff03) {
  	next_tvb = tvb_new_subset(tvb, 6, -1, -1);
  	call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
- 	return;
    }
    /* ...except when it just puts out one byte before the PPP header... */
    else if (tvb_get_ntohs(tvb, 1) == 0xff03) {
  	next_tvb = tvb_new_subset(tvb, 1, -1, -1);
  	call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
- 	return;
    }
    /* ...and if the connection is currently down, it sends 10 bytes of zeroes
     * instead of a fake MAC address and PPP header. */
    else if (memcmp(tvb_get_ptr(tvb, 0, 10), zeroes, 10) == 0) {
  	next_tvb = tvb_new_subset(tvb, 10, -1, -1);
  	call_dissector(ip_handle, next_tvb, pinfo, tree);
- 	return;
    }
    else {
! 	next_tvb = tvb_new_subset(tvb, 0, -1, -1);
! 	call_dissector(ip_handle, next_tvb, pinfo, tree);
! 	return;
    }
-   g_assert_not_reached();
  }
  
  void
--- 136,181 ----
     */
    if (tvb_get_ntohs(tvb, 0) == 0xff03) {
  	call_dissector(ppp_hdlc_handle, tvb, pinfo, tree);
    }
    /* The Linux ISDN driver sends a fake MAC address before the PPP header
     * on its ippp interfaces... */
    else if (tvb_get_ntohs(tvb, 6) == 0xff03) {
  	next_tvb = tvb_new_subset(tvb, 6, -1, -1);
  	call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
    }
    /* ...except when it just puts out one byte before the PPP header... */
    else if (tvb_get_ntohs(tvb, 1) == 0xff03) {
  	next_tvb = tvb_new_subset(tvb, 1, -1, -1);
  	call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
    }
    /* ...and if the connection is currently down, it sends 10 bytes of zeroes
     * instead of a fake MAC address and PPP header. */
    else if (memcmp(tvb_get_ptr(tvb, 0, 10), zeroes, 10) == 0) {
  	next_tvb = tvb_new_subset(tvb, 10, -1, -1);
  	call_dissector(ip_handle, next_tvb, pinfo, tree);
    }
    else {
! 	/*
! 	 * OK, is this IPv4 or IPv6?
! 	 */
! 	switch (tvb_get_guint8(tvb, 0) & 0xF0) {
! 
! 	case 0x40:
! 	  /* IPv4 */
! 	  call_dissector(ip_handle, tvb, pinfo, tree);
! 	  break;
! 
! 	case 0x60:
! 	  /* IPv6 */
! 	  call_dissector(ipv6_handle, tvb, pinfo, tree);
! 	  break;
! 
! 	default:
! 	  /* None of the above. */
! 	  call_dissector(data_handle, tvb, pinfo, tree);
! 	  break;
! 	}
    }
  }
  
  void
***************
*** 163,171 ****
    dissector_handle_t raw_handle;
  
    /*
!    * Get handles for the IP and PPP-in-HDLC-like-framing dissectors.
     */
    ip_handle = find_dissector("ip");
    ppp_hdlc_handle = find_dissector("ppp_hdlc");
    raw_handle = create_dissector_handle(dissect_raw, proto_raw);
    dissector_add("wtap_encap", WTAP_ENCAP_RAW_IP, raw_handle);
--- 195,206 ----
    dissector_handle_t raw_handle;
  
    /*
!    * Get handles for the IP, IPv6, undissected-data, and
!    * PPP-in-HDLC-like-framing dissectors.
     */
    ip_handle = find_dissector("ip");
+   ipv6_handle = find_dissector("ipv6");
+   data_handle = find_dissector("data");
    ppp_hdlc_handle = find_dissector("ppp_hdlc");
    raw_handle = create_dissector_handle(dissect_raw, proto_raw);
    dissector_add("wtap_encap", WTAP_ENCAP_RAW_IP, raw_handle);