Ejemplo n.º 1
0
void
capture_raw(const guchar *pd, int len, packet_counts *ld)
{
  /* So far, the only time we get raw connection types are with Linux and
   * Irix PPP connections.  We can't tell what type of data is coming down
   * the line, so our safest bet is IP. - GCC
   */

  /* Currently, the Linux 2.1.xxx PPP driver passes back some of the header
   * sometimes.  This check should be removed when 2.2 is out.
   */
  if (BYTES_ARE_IN_FRAME(0,len,2) && pd[0] == 0xff && pd[1] == 0x03) {
    capture_ppp_hdlc(pd, 0, len, ld);
  }
  /* The Linux ISDN driver sends a fake MAC address before the PPP header
   * on its ippp interfaces... */
  else if (BYTES_ARE_IN_FRAME(0,len,8) && pd[6] == 0xff && pd[7] == 0x03) {
    capture_ppp_hdlc(pd, 6, len, ld);
  }
  /* ...except when it just puts out one byte before the PPP header... */
  else if (BYTES_ARE_IN_FRAME(0,len,3) && pd[1] == 0xff && pd[2] == 0x03) {
    capture_ppp_hdlc(pd, 1, len, ld);
  }
  /* ...and if the connection is currently down, it sends 10 bytes of zeroes
   * instead of a fake MAC address and PPP header. */
  else if (BYTES_ARE_IN_FRAME(0,len,10) && memcmp(pd, zeroes, 10) == 0) {
    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
      }
    }
  }
}
Ejemplo 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);
}
Ejemplo n.º 3
0
static void
capture_info_packet(packet_counts *counts, gint wtap_linktype, const guchar *pd, guint32 caplen, union wtap_pseudo_header *pseudo_header)
{
    counts->total++;
    switch (wtap_linktype) {
    case WTAP_ENCAP_ETHERNET:
        capture_eth(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_FDDI:
    case WTAP_ENCAP_FDDI_BITSWAPPED:
        capture_fddi(pd, caplen, counts);
        break;
    case WTAP_ENCAP_IEEE_802_11_PRISM:
        capture_prism(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_TOKEN_RING:
        capture_tr(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_NULL:
        capture_null(pd, caplen, counts);
        break;
    case WTAP_ENCAP_PPP:
        capture_ppp_hdlc(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_RAW_IP:
        capture_raw(pd, caplen, counts);
        break;
    case WTAP_ENCAP_SLL:
        capture_sll(pd, caplen, counts);
        break;
    case WTAP_ENCAP_LINUX_ATM_CLIP:
        capture_clip(pd, caplen, counts);
        break;
    case WTAP_ENCAP_IEEE_802_11:
    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
        capture_ieee80211(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_IEEE_802_11_RADIOTAP:
        capture_radiotap(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_IEEE_802_11_AVS:
        capture_wlancap(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_CHDLC:
        capture_chdlc(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_LOCALTALK:
        capture_llap(counts);
        break;
    case WTAP_ENCAP_ATM_PDUS:
        capture_atm(pseudo_header, pd, caplen, counts);
        break;
    case WTAP_ENCAP_IP_OVER_FC:
        capture_ipfc(pd, caplen, counts);
        break;
    case WTAP_ENCAP_ARCNET:
        capture_arcnet(pd, caplen, counts, FALSE, TRUE);
        break;
    case WTAP_ENCAP_ARCNET_LINUX:
        capture_arcnet(pd, caplen, counts, TRUE, FALSE);
        break;
    case WTAP_ENCAP_APPLE_IP_OVER_IEEE1394:
        capture_ap1394(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_FRELAY:
    case WTAP_ENCAP_FRELAY_WITH_PHDR:
        capture_fr(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_ENC:
        capture_enc(pd, caplen, counts);
        break;
    case WTAP_ENCAP_PPI:
        capture_ppi(pd, caplen, counts);
        break;
    case WTAP_ENCAP_I2C:
        capture_i2c(pseudo_header, counts);
        break;
    case WTAP_ENCAP_AX25_KISS:
        capture_ax25_kiss(pd, 0, caplen, counts);
        break;
    case WTAP_ENCAP_AX25:
        capture_ax25(pd, 0, caplen, counts);
        break;
        /* XXX - some ATM drivers on FreeBSD might prepend a 4-byte ATM
           pseudo-header to DLT_ATM_RFC1483, with LLC header following;
           we might have to implement that at some point. */
    }
}
Ejemplo n.º 4
0
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 {