Esempio n. 1
0
void
capture_ipfc (const guchar *pd, int len, packet_counts *ld)
{
  if (!BYTES_ARE_IN_FRAME(0, len, 16)) {
    ld->other++;
    return;
  }

  capture_llc(pd, 16, len, ld);
}
Esempio n. 2
0
void
capture_sll(const guchar *pd, int len, packet_counts *ld)
{
	guint16 protocol;

	if (!BYTES_ARE_IN_FRAME(0, len, SLL_HEADER_SIZE)) {
		ld->other++;
		return;
	}
	protocol = pntohs(&pd[14]);
	if (protocol <= 1536) {	/* yes, 1536 - that's how Linux does it */
		/*
		 * "proto" is *not* a length field, it's a Linux internal
		 * protocol type.
		 */
		switch (protocol) {

		case LINUX_SLL_P_802_2:
			/*
			 * 802.2 LLC.
			 */
			capture_llc(pd, len, SLL_HEADER_SIZE, ld);
			break;

		case LINUX_SLL_P_ETHERNET:
			/*
			 * Ethernet.
			 */
			capture_eth(pd, SLL_HEADER_SIZE, len, ld);
			break;

		case LINUX_SLL_P_802_3:
			/*
			 * Novell IPX inside 802.3 with no 802.2 LLC
			 * header.
			 */
			capture_ipx(ld);
			break;

		case LINUX_SLL_P_PPPHDLC:
			/*
			 * PPP HDLC.
			 */
			capture_ppp_hdlc(pd, len, SLL_HEADER_SIZE, ld);
			break;

		default:
			ld->other++;
			break;
		}
	} else
		capture_ethertype(protocol, pd, SLL_HEADER_SIZE, len, ld);
}
Esempio n. 3
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 */
Esempio n. 4
0
void
capture_ethertype(guint16 etype, const guchar *pd, int offset, int len,
                  packet_counts *ld)
{
    switch (etype) {
    case ETHERTYPE_ARP:
        ld->arp++;
        break;
    case ETHERTYPE_IP:
        capture_ip(pd, offset, len, ld);
        break;
    case ETHERTYPE_IPv6:
        capture_ipv6(pd, offset, len, ld);
        break;
    case ETHERTYPE_IPX:
        capture_ipx(ld);
        break;
    case ETHERTYPE_VLAN:
        capture_vlan(pd, offset, len, ld);
        break;
    case ETHERTYPE_IEEE_802_1AD:
    case ETHERTYPE_IEEE_802_1AH:
        capture_ieee8021ah(pd, offset, len, ld);
        break;
    case ETHERTYPE_VINES_IP:
    case ETHERTYPE_VINES_ECHO:
        capture_vines(ld);
        break;
    case ETHERTYPE_BPQ:
        capture_bpq(pd, offset, len, ld);
        break;
    case ETHERTYPE_JUMBO_LLC:
        capture_llc(pd, offset, len, ld);
        break;
    default:
        ld->other++;
        break;
    }
}
Esempio n. 5
0
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;
  }
}
Esempio n. 6
0
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;
	}
}