コード例 #1
0
void
capture_ap1394(const guchar *pd, int offset, int len, packet_counts *ld)
{
  guint16    etype;

  if (!BYTES_ARE_IN_FRAME(offset, len, 18)) {
    ld->other++;
    return;
  }

  /* Skip destination and source addresses */
  offset += 16;

  etype = pntohs(&pd[offset]);
  offset += 2;
  capture_ethertype(etype, pd, offset, len, ld);
}
コード例 #2
0
void
capture_fddi(const guchar *pd, int len, packet_counts *ld)
{
  int offset = 0, fc;

  if (!BYTES_ARE_IN_FRAME(0, len, FDDI_HEADER_SIZE + FDDI_PADDING)) {
    ld->other++;
    return;
  }
  offset = FDDI_PADDING + FDDI_HEADER_SIZE;

  fc = (int) pd[FDDI_P_FC+FDDI_PADDING];

  switch (fc) {

    /* From now, only 802.2 SNAP (Async. LCC frame) is supported */

    case FDDI_FC_LLC_ASYNC + 0  :
    case FDDI_FC_LLC_ASYNC + 1  :
    case FDDI_FC_LLC_ASYNC + 2  :
    case FDDI_FC_LLC_ASYNC + 3  :
    case FDDI_FC_LLC_ASYNC + 4  :
    case FDDI_FC_LLC_ASYNC + 5  :
    case FDDI_FC_LLC_ASYNC + 6  :
    case FDDI_FC_LLC_ASYNC + 7  :
    case FDDI_FC_LLC_ASYNC + 8  :
    case FDDI_FC_LLC_ASYNC + 9  :
    case FDDI_FC_LLC_ASYNC + 10 :
    case FDDI_FC_LLC_ASYNC + 11 :
    case FDDI_FC_LLC_ASYNC + 12 :
    case FDDI_FC_LLC_ASYNC + 13 :
    case FDDI_FC_LLC_ASYNC + 14 :
    case FDDI_FC_LLC_ASYNC + 15 :
      capture_llc(pd, offset, len, ld);
      return;
    default :
      ld->other++;
      return;

  } /* fc */

} /* capture_fddi */
コード例 #3
0
ファイル: packet-enc.c プロジェクト: HeartFlying/wireshark
static gboolean
capture_enc(const guchar *pd, int offset _U_, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
{
  guint32 af;

  if (!BYTES_ARE_IN_FRAME(0, len, BSD_ENC_HDRLEN))
    return FALSE;

  memcpy((char *)&af, (const char *)&pd[0], sizeof(af));
  if ((af & 0xFFFF0000) != 0) {
    /*
     * BSD AF_ types will always have the upper 16 bits as 0, so if any
     * of them are non-zero, the af field must be byte-swapped, and
     * will, at least in DLT_ENC headers, always have at least one of
     * the lower 16 bits not being 0 (it won't be AF_UNSPEC, which is
     * 0), so if the af field is byte-swapped, at least one of the
     * upper 16 bits will be 0.
     */
    af = GUINT32_SWAP_LE_BE(af);
  }
  return try_capture_dissector("enc", af, pd, BSD_ENC_HDRLEN, len, cpinfo, pseudo_header);
}
コード例 #4
0
ファイル: packet-eth.c プロジェクト: mcrotty/stack
void
capture_eth(const guchar *pd, int offset, int len, packet_counts *ld)
{
  guint16 etype, length;
  int ethhdr_type;          /* the type of ethernet frame */

  if (!BYTES_ARE_IN_FRAME(offset, len, ETH_HEADER_SIZE)) {
    ld->other++;
    return;
  }

  etype = pntohs(&pd[offset+12]);

  if (etype <= IEEE_802_3_MAX_LEN) {
    /* Oh, yuck.  Cisco ISL frames require special interpretation of the
       destination address field; fortunately, they can be recognized by
       checking the first 5 octets of the destination address, which are
       01-00-0C-00-00 or 0C-00-0C-00-00 for ISL frames. */
    if ((pd[offset] == 0x01 || pd[offset] == 0x0C) && pd[offset+1] == 0x00
        && pd[offset+2] == 0x0C && pd[offset+3] == 0x00
        && pd[offset+4] == 0x00) {
      capture_isl(pd, offset, len, ld);
      return;
    }
  }

  /*
   * If the type/length field is <= the maximum 802.3 length,
   * and is not zero, this is an 802.3 frame, and it's a length
   * field; it might be an Novell "raw 802.3" frame, with no
   * 802.2 LLC header, or it might be a frame with an 802.2 LLC
   * header.
   *
   * If the type/length field is >= the minimum Ethernet II length,
   * this is an Ethernet II frame, and it's a type field.
   *
   * If the type/length field is > maximum 802.3 length and < minimum
   * Ethernet II length, then this is an invalid packet.
   *
   * If the type/length field is zero (ETHERTYPE_UNK), this is
   * a frame used internally by the Cisco MDS switch to contain
   * Fibre Channel ("Vegas").  We treat that as an Ethernet II
   * frame; the dissector for those frames registers itself with
   * an ethernet type of ETHERTYPE_UNK.
   */
  if (etype > IEEE_802_3_MAX_LEN && etype < ETHERNET_II_MIN_LEN) {
    ld->other++;
    return;
  }

  if (etype <= IEEE_802_3_MAX_LEN && etype != ETHERTYPE_UNK) {
    length = etype;

    /* Is there an 802.2 layer? I can tell by looking at the first 2
       bytes after the 802.3 header. If they are 0xffff, then what
       follows the 802.3 header is an IPX payload, meaning no 802.2.
       (IPX/SPX is they only thing that can be contained inside a
       straight 802.3 packet). A non-0xffff value means that there's an
       802.2 layer inside the 802.3 layer */
    if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
      ethhdr_type = ETHERNET_802_3;
    }
    else {
      ethhdr_type = ETHERNET_802_2;
    }

    /* Convert the LLC length from the 802.3 header to a total
       frame length, by adding in the size of any data that preceded
       the Ethernet header, and adding in the Ethernet header size,
       and set the payload and captured-payload lengths to the minima
       of the total length and the frame lengths. */
    length += offset + ETH_HEADER_SIZE;
    if (len > length)
      len = length;
  } else {
    ethhdr_type = ETHERNET_II;
  }
  offset += ETH_HEADER_SIZE;

  switch (ethhdr_type) {
    case ETHERNET_802_3:
      capture_ipx(ld);
      break;
    case ETHERNET_802_2:
      capture_llc(pd, offset, len, ld);
      break;
    case ETHERNET_II:
      capture_ethertype(etype, pd, offset, len, ld);
      break;
  }
}
コード例 #5
0
void
capture_radiotap(const guchar *pd, int offset, int len, packet_counts *ld)
{
    guint16 it_len;
    guint32 present;
    guint8 rflags;

    if(!BYTES_ARE_IN_FRAME(offset, len, RADIOTAP_MIN_HEADER_LEN)) {
        ld->other ++;
        return;
    }
    it_len = pletohs(&pd[RADIOTAP_LENGTH_OFFSET]);
    if(!BYTES_ARE_IN_FRAME(offset, len, it_len)) {
        ld->other ++;
        return;
    }

    if(it_len > len) {
        /* Header length is bigger than total packet length */
        ld->other ++;
        return;
    }

    if(it_len < RADIOTAP_MIN_HEADER_LEN) {
        /* Header length is shorter than fixed-length portion of header */
        ld->other ++;
        return;
    }

    present = pletohl(&pd[RADIOTAP_PRESENT_OFFSET]);
    offset += RADIOTAP_MIN_HEADER_LEN;
    it_len -= RADIOTAP_MIN_HEADER_LEN;

    rflags = 0;

    /*
     * IEEE80211_RADIOTAP_TSFT is the lowest-order bit.
     */
    if (present & BIT(IEEE80211_RADIOTAP_TSFT)) {
    	if (it_len < 8) {
	    /* No room in header for this field. */
	    ld->other ++;
	    return;
	}
	/* That field is present, and it's 8 bits long. */
	offset += 8;
	it_len -= 8;
    }

    /*
     * IEEE80211_RADIOTAP_FLAGS is the next bit.
     */
    if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
    	if (it_len < 1) {
	    /* No room in header for this field. */
	    ld->other ++;
	    return;
	}
	/* That field is present; fetch it. */
	if(!BYTES_ARE_IN_FRAME(offset, len, 1)) {
	    ld->other ++;
	    return;
	}
	rflags = pd[offset];
    }

    /* 802.11 header follows */
    if (rflags & IEEE80211_RADIOTAP_F_DATAPAD)
	capture_ieee80211_datapad(pd, offset + it_len, len, ld);
    else
	capture_ieee80211(pd, offset + it_len, len, ld);
}
コード例 #6
0
ファイル: packet-arcnet.c プロジェクト: ARK1988/wireshark
void
capture_arcnet (const guchar *pd, int len, packet_counts *ld,
                gboolean has_offset, gboolean has_exception)
{
  int offset = has_offset ? 4 : 2;

  if (!BYTES_ARE_IN_FRAME(offset, len, 1)) {
    ld->other++;
    return;
  }

  switch (pd[offset]) {

  case ARCNET_PROTO_IP_1051:
    /* No fragmentation stuff in the header */
    capture_ip(pd, offset + 1, len, ld);
    break;

  case ARCNET_PROTO_IP_1201:
    /*
     * There's fragmentation stuff in the header.
     *
     * XXX - on at least some versions of NetBSD, it appears that we
     * might we get ARCNET frames, not reassembled packets; we should
     * perhaps bump "ld->other" for all but the first frame of a packet.
     *
     * XXX - but on FreeBSD it appears that we get reassembled packets
     * on input (but apparently we get frames on output - or maybe
     * we get the packet *and* all its frames!); how to tell the
     * difference?  It looks from the FreeBSD reassembly code as if
     * the reassembled packet arrives with the header for the first
     * frame.  It also looks as if, on output, we first get the
     * full packet, with a header containing none of the fragmentation
     * stuff, and then get the frames.
     *
     * On Linux, we get only reassembled packets, and the exception
     * frame stuff is hidden - there's a split flag and sequence
     * number, but it appears that it will never have the exception
     * frame stuff.
     *
     * XXX - what about OpenBSD?  And, for that matter, what about
     * Windows?  (I suspect Windows supplies reassembled frames,
     * as WinPcap, like PF_PACKET sockets, taps into the networking
     * stack just as other protocols do.)
     */
    offset++;
    if (!BYTES_ARE_IN_FRAME(offset, len, 1)) {
      ld->other++;
      return;
    }
    if (has_exception && pd[offset] == 0xff) {
      /* This is an exception packet.  The flag value there is the
         "this is an exception flag" packet; the next two bytes
         after it are padding, and another copy of the packet
         type appears after the padding. */
      offset += 4;
    }
    capture_ip(pd, offset + 3, len, ld);
    break;

  case ARCNET_PROTO_ARP_1051:
  case ARCNET_PROTO_ARP_1201:
    /*
     * XXX - do we have to worry about fragmentation for ARP?
     */
    ld->arp++;
    break;

  case ARCNET_PROTO_IPX:
    ld->ipx++;
    break;

  default:
    ld->other++;
    break;
  }
}
コード例 #7
0
void
capture_llc(const guchar *pd, int offset, int len, packet_counts *ld) {

	int		is_snap;
	guint16		control;
	int		llc_header_len;

	if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
		ld->other++;
		return;
	}
	is_snap = (pd[offset] == SAP_SNAP) && (pd[offset+1] == SAP_SNAP);
	llc_header_len = 2;	/* DSAP + SSAP */

	/*
	 * XXX - the page referred to in the comment above about the
	 * Command/Response bit also implies that LLC Type 2 always
	 * uses extended operation, so we don't need to determine
	 * whether it's basic or extended operation; is that the case?
	 */
	control = get_xdlc_control(pd, offset+2, pd[offset+1] & SSAP_CR_BIT);
	llc_header_len += XDLC_CONTROL_LEN(control, TRUE);
	if (!BYTES_ARE_IN_FRAME(offset, len, llc_header_len)) {
		ld->other++;
		return;
	}

	if (!XDLC_IS_INFORMATION(control)) {
		ld->other++;
		return;
	}
	if (is_snap)
		capture_snap(pd, offset+llc_header_len, len, ld);
	else {
		/* non-SNAP */
		switch (pd[offset]) {

		case SAP_IP:
			capture_ip(pd, offset + llc_header_len, len, ld);
			break;

		case SAP_NETWARE1:
		case SAP_NETWARE2:
			capture_ipx(ld);
			break;

		case SAP_NETBIOS:
			capture_netbios(ld);
			break;

		case SAP_VINES1:
		case SAP_VINES2:
			capture_vines(ld);
			break;

		default:
			ld->other++;
			break;
		}
	}
}
コード例 #8
0
ファイル: packet-null.c プロジェクト: pvons/wireshark
void
capture_null( const guchar *pd, int len, packet_counts *ld )
{
  guint32 null_header;

  /*
   * BSD drivers that use DLT_NULL - including the FreeBSD 3.2 ISDN-for-BSD
   * drivers, as well as the 4.4-Lite and FreeBSD loopback drivers -
   * stuff the AF_ value for the protocol, in *host* byte order, in the
   * first four bytes.  (BSD drivers that use DLT_LOOP, such as recent
   * OpenBSD loopback drivers, stuff it in *network* byte order in the
   * first four bytes.)
   *
   * However, the IRIX and UNICOS/mp snoop socket mechanism supplies,
   * on loopback devices, a 4-byte header that has a 2 byte (big-endian)
   * AF_ value and 2 bytes of 0, so it's
   *
   *	0000AAAA
   *
   * when read on a little-endian machine and
   *
   *	AAAA0000
   *
   * when read on a big-endian machine.  The current CVS version of libpcap
   * compensates for this by converting it to standard 4-byte format before
   * processing the packet, but snoop captures from IRIX or UNICOS/mp
   * have the 2-byte+2-byte header, as might tcpdump or libpcap captures
   * with older versions of libpcap.
   *
   * AF_ values are small integers, and probably fit in 8 bits (current
   * values on the BSDs do), and have their upper 24 bits zero.
   * This means that, in practice, if you look at the header as a 32-bit
   * integer in host byte order:
   *
   *	on a little-endian machine:
   *
   *		a little-endian DLT_NULL header looks like
   *
   *			000000AA
   *
   *		a big-endian DLT_NULL header, or a DLT_LOOP header, looks
   *		like
   *
   *			AA000000
   *
   *		an IRIX or UNICOS/mp DLT_NULL header looks like
   *
   *			0000AA00
   *
   *	on a big-endian machine:
   *
   *		a big-endian DLT_NULL header, or a DLT_LOOP header, looks
   *		like
   *
   *			000000AA
   *
   *		a little-endian DLT_NULL header looks like
   *
   *			AA000000
   *
   *		an IRIX or UNICOS/mp DLT_NULL header looks like
   *
   *			00AA0000
   *
   * However, according to Gerald Combs, a FreeBSD ISDN PPP dump that
   * Andreas Klemm sent to wireshark-dev has a packet type of DLT_NULL,
   * and the family bits look like PPP's protocol field.  (Was this an
   * older, or different, ISDN driver?)  Looking at what appears to be
   * that capture file, it appears that it's using PPP in HDLC framing,
   * RFC 1549, wherein the first two octets of the frame are 0xFF
   * (address) and 0x03 (control), so the header bytes are, in order:
   *
   *	0xFF
   *	0x03
   *	high-order byte of a PPP protocol field
   *	low-order byte of a PPP protocol field
   *
   * If we treat that as a 32-bit host-byte-order value, it looks like
   *
   *	PPPP03FF
   *
   * where PPPP is a byte-swapped PPP protocol type if we read it on
   * a little-endian machine and
   *
   *	FF03PPPP
   *
   * where PPPP is a PPP protocol type if we read it on a big-endian
   * machine.  0x0000 does not appear to be a valid PPP protocol type
   * value, so at least one of those hex digits is guaranteed not to
   * be 0.
   *
   * Old versions of libpcap for Linux used DLT_NULL for loopback devices,
   * but not any other devices.  (Current versions use DLT_EN10MB for it.)
   * The Linux loopback driver puts an *Ethernet* header at the beginning
   * of loopback packets, with fake source and destination addresses and
   * the appropriate Ethernet type value; however, those older versions of
   * libpcap for Linux compensated for this by skipping the source and
   * destination MAC addresses, replacing them with 2 bytes of 0.
   * This means that if we're reading the capture on a little-endian
   * machine, the header, treated as a 32-bit integer, looks like
   *
   *	EEEE0000
   *
   * where EEEE is a byte-swapped Ethernet type, and if we're reading it
   * on a big-endian machine, it looks like
   *
   *	0000EEEE
   *
   * where EEEE is an Ethernet type.
   *
   * If the first 2 bytes of the header are FF 03:
   *
   *	it can't be a big-endian BSD DLT_NULL header, or a DLT_LOOP
   *	header, as AF_ values are small so the first 2 bytes of the
   *	header would be 0;
   *
   *	it can't be a little-endian BSD DLT_NULL header, as the
   *	resulting AF_ value would be >= 0x03FF, which is too big
   *	for an AF_ value;
   *
   *	it can't be an IRIX or UNICOS/mp DLT_NULL header, as the
   *	resulting AF_ value with be 0x03FF.
   *
   * So the first thing we do is check the first two bytes of the
   * header; if it's FF 03, we treat the packet as a PPP frame.
   *
   * Otherwise, if the upper 16 bits are non-zero, either:
   *
   *	it's a BSD DLT_NULL or DLT_LOOP header whose AF_ value
   *	is not in our byte order;
   *
   *	it's an IRIX or UNICOS/mp DLT_NULL header being read on
   *	a big-endian machine;
   *
   *	it's a Linux DLT_NULL header being read on a little-endian
   *	machine.
   *
   * In all those cases except for the IRIX or UNICOS/mp DLT_NULL header,
   * we should byte-swap it (if it's a Linux DLT_NULL header, that'll
   * put the Ethernet type in the right byte order).  In the case
   * of the IRIX or UNICOS/mp DLT_NULL header, we should just get
   * the upper 16 bits as an AF_ value.
   *
   * If it's a BSD DLT_NULL or DLT_LOOP header whose AF_ value is not
   * in our byte order, then the upper 2 hex digits would be non-zero
   * and the next 2 hex digits down would be zero, as AF_ values fit in
   * 8 bits, and the upper 2 hex digits are the *lower* 8 bits of the value.
   *
   * If it's an IRIX or UNICOS/mp DLT_NULL header, the upper 2 hex digits
   * would be zero and the next 2 hex digits down would be non-zero, as
   * the upper 16 bits are a big-endian AF_ value.  Furthermore, the
   * next 2 hex digits down are likely to be < 0x60, as 0x60 is 96,
   * and, so far, we're far from requiring AF_ values that high.
   *
   * If it's a Linux DLT_NULL header, the third hex digit from the top
   * will be >= 6, as Ethernet types are >= 1536, or 0x0600, and
   * it's byte-swapped, so the second 2 hex digits from the top are
   * >= 0x60.
   *
   * So, if the upper 16 bits are non-zero:
   *
   *	if the upper 2 hex digits are 0 and the next 2 hex digits are
   *	in the range 0x00-0x5F, we treat it as a big-endian IRIX or
   *	UNICOS/mp DLT_NULL header;
   *
   *	otherwise, we byte-swap it and do the next stage.
   *
   * If the upper 16 bits are zero, either:
   *
   *	it's a BSD DLT_NULLor DLT_LOOP header whose AF_ value is in
   *	our byte order;
   *
   *	it's an IRIX or UNICOS/mp DLT_NULL header being read on
   *	a little-endian machine;
   *
   *	it's a Linux DLT_NULL header being read on a big-endian
   *	machine.
   *
   * In all of those cases except for the IRIX or UNICOS/mp DLT_NULL header,
   * we should *not* byte-swap it.  In the case of the IRIX or UNICOS/mp
   * DLT_NULL header, we should extract the AF_ value and byte-swap it.
   *
   * If it's a BSD DLT_NULL or DLT_LOOP header whose AF_ value is
   * in our byte order, the upper 6 hex digits would all be zero.
   *
   * If it's an IRIX or UNICOS/mp DLT_NULL header, the upper 4 hex
   * digits would be zero and the next 2 hex digits would not be zero.
   * Furthermore, the third hex digit from the bottom would be <
   */
  if (!BYTES_ARE_IN_FRAME(0, len, 2)) {
    ld->other++;
    return;
  }
  if (pd[0] == 0xFF && pd[1] == 0x03) {
    /*
     * Hand it to PPP.
     */
    capture_ppp_hdlc(pd, 0, len, ld);
  } else {
    /*
     * Treat it as a normal DLT_NULL header.
     */
    if (!BYTES_ARE_IN_FRAME(0, len, (int)sizeof(null_header))) {
      ld->other++;
      return;
    }
    memcpy((char *)&null_header, (const char *)&pd[0], sizeof(null_header));

    if ((null_header & 0xFFFF0000) != 0) {
      /*
       * It is possible that the AF_ type was only a 16 bit value.
       * IRIX and UNICOS/mp loopback snoop use a 4 byte header with
       * AF_ type in the first 2 bytes!
       * BSD AF_ types will always have the upper 8 bits as 0.
       */
      if ((null_header & 0xFF000000) == 0 &&
          (null_header & 0x00FF0000) < 0x00060000) {
        /*
         * Looks like a IRIX or UNICOS/mp loopback header, in the
         * correct byte order.  Set the null header value to the
         * AF_ type, which is in the upper 16 bits of "null_header".
         */
        null_header >>= 16;
      } else {
        /* Byte-swap it. */
        null_header = GUINT32_SWAP_LE_BE(null_header);
      }
    } else {
コード例 #9
0
ファイル: packet-tr.c プロジェクト: dogphilly/wireshark
void
capture_tr(const guchar *pd, int offset, int len, packet_counts *ld) {

	int			source_routed = 0;
	int			frame_type;
	int			x;
	guint8			trn_rif_bytes;
	guint8			actual_rif_bytes;
	guint16			first2_sr;

	/* The trn_hdr struct, as separate variables */
	guint8			trn_fc;		/* field control field */
	const guint8		*trn_shost;	/* source host */

	if (!BYTES_ARE_IN_FRAME(offset, len, TR_MIN_HEADER_LEN)) {
		ld->other++;
		return;
	}

	if ((x = check_for_old_linux(pd)))
	{
		/* Actually packet starts x bytes into what we have got but with all
		   source routing compressed
		*/
		 /* pd = &pd[x]; */ offset+=x;
	}

	/* get the data */
	trn_fc = pd[offset + 1];
	trn_shost = &pd[offset + 8];

	frame_type = (trn_fc & 192) >> 6;

	/* if the high bit on the first byte of src hwaddr is 1, then
		this packet is source-routed */
	source_routed = trn_shost[0] & 128;

	trn_rif_bytes = pd[offset + 14] & 31;

	if (fix_linux_botches) {
		/* the Linux 2.0 TR code strips source-route bits in
		 * order to test for SR. This can be removed from most
		 * packets with oltr, but not all. So, I try to figure out
		 * which packets should have been SR here. I'll check to
		 * see if there's a SNAP or IPX field right after
		 * my RIF fields.
		 *
		 * The Linux 2.4.18 code, at least appears to do the
		 * same thing, from a capture I got from somebody running
		 * 2.4.18 (RH 7.1, so perhaps this is a Red Hat
		 * "improvement").
		 */
		if (!source_routed && trn_rif_bytes > 0) {
			if (pd[offset + 0x0e] != pd[offset + 0x0f]) {
				first2_sr = pntohs(&pd[offset + 0xe0 + trn_rif_bytes]);
				if (
					(first2_sr == 0xaaaa &&
					pd[offset + 0x10 + trn_rif_bytes] == 0x03) ||

					first2_sr == 0xe0e0 ||
					first2_sr == 0xe0aa ) {

					source_routed = 1;
				}
			}
		}
	}

	if (source_routed) {
		actual_rif_bytes = trn_rif_bytes;
	}
	else {
		trn_rif_bytes = 0;
		actual_rif_bytes = 0;
	}

	if (fix_linux_botches) {
		/* this is a silly hack for Linux 2.0.x. Read the comment
		 * below about LLC headers. If we're sniffing our own NIC,
		 * we get a full RIF, sometimes with garbage
		 */
		if ((source_routed && trn_rif_bytes == 2 && frame_type == 1) ||
			(!source_routed && frame_type == 1)) {
			/* look for SNAP or IPX only */
			if ( (pd[offset + 0x20] == 0xaa && pd[offset + 0x21] == 0xaa && pd[offset + 0x22] == 03) ||
				 (pd[offset + 0x20] == 0xe0 && pd[offset + 0x21] == 0xe0) ) {
				actual_rif_bytes = 18;
			} else if (
				pd[offset + 0x23] == 0 &&
				pd[offset + 0x24] == 0 &&
				pd[offset + 0x25] == 0 &&
				pd[offset + 0x26] == 0x00 &&
				pd[offset + 0x27] == 0x11) {

				actual_rif_bytes = 18;

			       /* Linux 2.0.x also requires drivers pass up
			        * a fake SNAP and LLC header before the
				* real LLC hdr for all Token Ring frames
				* that arrive with DSAP and SSAP != 0xAA
				* (i.e. for non SNAP frames e.g. for Netware
				* frames) the fake SNAP header has the
				* ETH_P_TR_802_2 ether type (0x0011) and the protocol id
				* bytes as zero frame looks like :-
				* TR Header | Fake LLC | Fake SNAP | Wire LLC | Rest of data
				*/
			       offset += 8; /* Skip fake LLC and SNAP */
			}
		}
	}

	offset += actual_rif_bytes + TR_MIN_HEADER_LEN;

	/* The package is either MAC or LLC */
	switch (frame_type) {
		/* MAC */
		case 0:
			ld->other++;
			break;
		case 1:
			capture_llc(pd, offset, len, ld);
			break;
		default:
			/* non-MAC, non-LLC, i.e., "Reserved" */
			ld->other++;
			break;
	}
}