Пример #1
0
static gboolean
libpcap_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct pcaprec_ss990915_hdr hdr;
	guint packet_size;
	guint orig_size;
	int phdr_len;
	libpcap_t *libpcap;

	if (!libpcap_read_header(wth, fh, err, err_info, &hdr))
		return FALSE;

	if (hdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
		/*
		 * Probably a corrupt capture file; return an error,
		 * so that our caller doesn't blow up trying to allocate
		 * space for an immensely-large packet.
		 */
		*err = WTAP_ERR_BAD_FILE;
		if (err_info != NULL) {
			*err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
			    hdr.hdr.incl_len, WTAP_MAX_PACKET_SIZE);
		}
		return FALSE;
	}

	packet_size = hdr.hdr.incl_len;
	orig_size = hdr.hdr.orig_len;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX &&
	    (wth->file_encap == WTAP_ENCAP_FDDI ||
	     wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		packet_size -= 3;
		orig_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}

	phdr_len = pcap_process_pseudo_header(fh, wth->file_type_subtype,
	    wth->file_encap, packet_size, TRUE, phdr, err, err_info);
	if (phdr_len < 0)
		return FALSE;	/* error */

	/*
	 * Don't count any pseudo-header as part of the packet.
	 */
	orig_size -= phdr_len;
	packet_size -= phdr_len;

	phdr->rec_type = REC_TYPE_PACKET;
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;

	/* Update the timestamp, if not already done */
	if (wth->file_encap != WTAP_ENCAP_ERF) {
		phdr->ts.secs = hdr.hdr.ts_sec;
		if (wth->file_tsprec == WTAP_TSPREC_NSEC)
			phdr->ts.nsecs = hdr.hdr.ts_usec;
		else
			phdr->ts.nsecs = hdr.hdr.ts_usec * 1000;
	} else {
		/* Set interface ID for ERF format */
		phdr->presence_flags |= WTAP_HAS_INTERFACE_ID;
		phdr->interface_id = phdr->pseudo_header.erf.phdr.flags & 0x03;
	}
	phdr->caplen = packet_size;
	phdr->len = orig_size;

	/*
	 * Read the packet data.
	 */
	if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info))
		return FALSE;	/* failed */

	libpcap = (libpcap_t *)wth->priv;
	pcap_read_post_process(wth->file_type_subtype, wth->file_encap,
	    phdr, ws_buffer_start_ptr(buf), libpcap->byte_swapped, -1);
	return TRUE;
}
Пример #2
0
/* Read the header of the next packet.

   Return -1 on an I/O error, 0 on success, or a positive number if the
   header looks corrupt.  The higher the positive number, the more things
   are wrong with the header; this is used by the heuristics that try to
   guess what type of file it is, with the type with the fewest problems
   being chosen. */
static int libpcap_try_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
    struct pcaprec_ss990915_hdr *hdr)
{
	int	ret;

	if (!libpcap_read_header(wth, fh, err, err_info, hdr))
		return -1;

	ret = 0;	/* start out presuming everything's OK */
	switch (wth->file_type_subtype) {

	case WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC:
	case WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX:
		/*
		 * Nanosecond resolution; treat fractions-of-a-second
		 * values >= 1 000 000 000 as an indication that
		 * the header format might not be what we think it is.
		 */
		if (hdr->hdr.ts_usec >= 1000000000)
			ret++;
		break;

	default:
		/*
		 * Microsecond resolution; treat fractions-of-a-second
		 * values >= 1 000 000 as an indication that the header
		 * format might not be what we think it is.
		 */
		if (hdr->hdr.ts_usec >= 1000000)
			ret++;
		break;
	}
	if (hdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
		/*
		 * Probably either a corrupt capture file or a file
		 * of a type different from the one we're trying.
		 */
		ret++;
	}

	if (hdr->hdr.orig_len > 64*1024*1024) {
		/*
		 * In theory I guess the on-the-wire packet size can be
		 * arbitrarily large, and it can certainly be larger than the
		 * maximum snapshot length which bounds the snapshot size,
		 * but any file claiming 64MB in a single packet is *probably*
		 * corrupt, and treating them as such makes the heuristics
		 * much more reliable. See, for example,
		 *
		 *    https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9634
		 *
		 * (64MB is an arbitrary size at this point).
		 */
		ret++;
	}

	if (hdr->hdr.incl_len > wth->snapshot_length) {
	        /*
	         * This is not a fatal error, and packets that have one
	         * such packet probably have thousands. For discussion,
	         * see
	         * https://www.wireshark.org/lists/wireshark-dev/201307/msg00076.html
	         * and related messages.
	         *
	         * The packet contents will be copied to a Buffer, which
	         * expands as necessary to hold the contents; we don't have
	         * to worry about fixed-length buffers allocated based on
	         * the original snapshot length.
	         *
	         * We just treat this as an indication that we might be
	         * trying the wrong file type here.
	         */
		ret++;
	}

	if (hdr->hdr.incl_len > hdr->hdr.orig_len) {
		/*
		 * Another hint that this might be the wrong file type.
		 */
		ret++;
	}

	return ret;
}
Пример #3
0
/* Read the next packet */
static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	struct pcaprec_ss990915_hdr hdr;
	guint packet_size;
	guint orig_size;
	int bytes_read;
	guint8 fddi_padding[3];
	int phdr_len;
	libpcap_t *libpcap;

	bytes_read = libpcap_read_header(wth, err, err_info, &hdr);
	if (bytes_read == -1) {
		/*
		 * We failed to read the header.
		 */
		return FALSE;
	}

	packet_size = hdr.hdr.incl_len;
	orig_size = hdr.hdr.orig_len;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (wth->file_type == WTAP_FILE_PCAP_AIX &&
	    (wth->file_encap == WTAP_ENCAP_FDDI ||
	     wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		packet_size -= 3;
		orig_size -= 3;

		/*
		 * Read the padding.
		 */
		if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err,
		    err_info))
			return FALSE;	/* Read error */
	}

	*data_offset = file_tell(wth->fh);

	libpcap = (libpcap_t *)wth->priv;
	phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type,
	    wth->file_encap, packet_size, TRUE, &wth->phdr,
	    &wth->phdr.pseudo_header, err, err_info);
	if (phdr_len < 0)
		return FALSE;	/* error */

	/*
	 * Don't count any pseudo-header as part of the packet.
	 */
	orig_size -= phdr_len;
	packet_size -= phdr_len;

	buffer_assure_space(wth->frame_buffer, packet_size);
	if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
	    packet_size, err, err_info))
		return FALSE;	/* Read error */

	wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;

	/* Update the Timestamp, if not already done */
	if (wth->file_encap != WTAP_ENCAP_ERF) {
	  wth->phdr.ts.secs = hdr.hdr.ts_sec;
	  if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
	    wth->phdr.ts.nsecs = hdr.hdr.ts_usec;
	  } else {
	    wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000;
	  }
	} else {
	  /* Set interface ID for ERF format */
	  wth->phdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
	  wth->phdr.interface_id = wth->phdr.pseudo_header.erf.phdr.flags & 0x03;
	}
	wth->phdr.caplen = packet_size;
	wth->phdr.len = orig_size;

	pcap_read_post_process(wth->file_type, wth->file_encap,
	    &wth->phdr.pseudo_header, buffer_start_ptr(wth->frame_buffer),
	    wth->phdr.caplen, libpcap->byte_swapped, -1);
	return TRUE;
}
Пример #4
0
/* Try to read the first two records of the capture file. */
static libpcap_try_t libpcap_try(wtap *wth, int *err)
{
	/*
	 * pcaprec_ss990915_hdr is the largest header type.
	 */
	struct pcaprec_ss990915_hdr first_rec_hdr, second_rec_hdr;


	/*
	 * Attempt to read the first record's header.
	 */
	if (libpcap_read_header(wth, err, NULL, &first_rec_hdr) == -1) {
		if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
			/*
			 * EOF or short read - assume the file is in this
			 * format.
			 * When our client tries to read the first packet
			 * they will presumably get the same EOF or short
			 * read.
			 */
			return THIS_FORMAT;
		}

		if (*err == WTAP_ERR_BAD_FILE) {
			/*
			 * The first record is bogus, so this is probably
			 * a corrupt file.  Assume the file is in this
			 * format.  When our client tries to read the
			 * first packet they will presumably get the
			 * same bogus record.
			 */
			return THIS_FORMAT;
		}

		/*
		 * Some other error, e.g. an I/O error; just give up.
		 */
		return BAD_READ;
	}

	/*
	 * Now skip over the first record's data, under the assumption
	 * that the header is sane.
	 */
	if (file_seek(wth->fh, first_rec_hdr.hdr.incl_len, SEEK_CUR, err) == -1)
		return BAD_READ;

	/*
	 * Now attempt to read the second record's header.
	 */
	if (libpcap_read_header(wth, err, NULL, &second_rec_hdr) == -1) {
		if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
			/*
			 * EOF or short read - assume the file is in this
			 * format.
			 * When our client tries to read the second packet
			 * they will presumably get the same EOF or short
			 * read.
			 */
			return THIS_FORMAT;
		}

		if (*err == WTAP_ERR_BAD_FILE) {
			/*
			 * The second record is bogus; maybe it's a
			 * Capture File From Hell, and what looks like
			 * the "header" of the next packet is actually
			 * random junk from the middle of a packet.
			 * Try the next format; if we run out of formats,
			 * it probably *is* a corrupt file.
			 */
			return OTHER_FORMAT;
		}

		/*
		 * Some other error, e.g. an I/O error; just give up.
		 */
		return BAD_READ;
	}

	/*
	 * OK, the first two records look OK; assume this is the
	 * right format.
	 */
	return THIS_FORMAT;
}
Пример #5
0
static gboolean
libpcap_process_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    int *err, gchar **err_info)
{
	struct pcaprec_ss990915_hdr hdr;
	guint packet_size;
	guint orig_size;
	int bytes_read;
	guint8 fddi_padding[3];
	int phdr_len;

	bytes_read = libpcap_read_header(wth, fh, err, err_info, &hdr);
	if (bytes_read == -1) {
		/*
		 * We failed to read the header.
		 */
		return FALSE;
	}

	packet_size = hdr.hdr.incl_len;
	orig_size = hdr.hdr.orig_len;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (wth->file_type == WTAP_FILE_PCAP_AIX &&
	    (wth->file_encap == WTAP_ENCAP_FDDI ||
	     wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		packet_size -= 3;
		orig_size -= 3;

		/*
		 * Read the padding.
		 */
		if (!libpcap_read_rec_data(fh, fddi_padding, 3, err,
		    err_info))
			return FALSE;	/* Read error */
	}

	phdr_len = pcap_process_pseudo_header(fh, wth->file_type,
	    wth->file_encap, packet_size, TRUE, phdr, err, err_info);
	if (phdr_len < 0)
		return FALSE;	/* error */

	/*
	 * Don't count any pseudo-header as part of the packet.
	 */
	orig_size -= phdr_len;
	packet_size -= phdr_len;

	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;

	/* Update the timestamp, if not already done */
	if (wth->file_encap != WTAP_ENCAP_ERF) {
		phdr->ts.secs = hdr.hdr.ts_sec;
		if (wth->tsprecision == WTAP_FILE_TSPREC_NSEC)
			phdr->ts.nsecs = hdr.hdr.ts_usec;
		else
			phdr->ts.nsecs = hdr.hdr.ts_usec * 1000;
	} else {
		/* Set interface ID for ERF format */
		phdr->presence_flags |= WTAP_HAS_INTERFACE_ID;
		phdr->interface_id = phdr->pseudo_header.erf.phdr.flags & 0x03;
	}
	phdr->caplen = packet_size;
	phdr->len = orig_size;

	return TRUE;
}
Пример #6
0
/* Read the next packet */
static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	struct pcaprec_ss990915_hdr hdr;
	guint packet_size;
	guint orig_size;
	int bytes_read;
	guchar fddi_padding[3];
	int phdr_len;
	libpcap_t *libpcap;

	bytes_read = libpcap_read_header(wth, err, err_info, &hdr);
	if (bytes_read == -1) {
		/*
		 * We failed to read the header.
		 */
		return FALSE;
	}

	wth->data_offset += bytes_read;
	packet_size = hdr.hdr.incl_len;
	orig_size = hdr.hdr.orig_len;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (wth->file_type == WTAP_FILE_PCAP_AIX &&
	    (wth->file_encap == WTAP_ENCAP_FDDI ||
	     wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		packet_size -= 3;
		orig_size -= 3;
		wth->data_offset += 3;

		/*
		 * Read the padding.
		 */
		if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err))
			return FALSE;	/* Read error */
	}

	*data_offset = wth->data_offset;

	libpcap = (libpcap_t *)wth->priv;
	phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type,
	    wth->file_encap, libpcap->byte_swapped, packet_size,
	    TRUE, &wth->phdr, &wth->pseudo_header, err, err_info);
	if (phdr_len < 0)
		return FALSE;	/* error */

	/*
	 * Don't count any pseudo-header as part of the packet.
	 */
	orig_size -= phdr_len;
	packet_size -= phdr_len;
	wth->data_offset += phdr_len;

	buffer_assure_space(wth->frame_buffer, packet_size);
	if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
	    packet_size, err))
		return FALSE;	/* Read error */
	wth->data_offset += packet_size;

	/* Update the Timestamp, if not already done */
	if (wth->file_encap != WTAP_ENCAP_ERF) {
	  wth->phdr.ts.secs = hdr.hdr.ts_sec;
	  if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
	    wth->phdr.ts.nsecs = hdr.hdr.ts_usec;
	  } else {
	    wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000;
	  }
	}
	wth->phdr.caplen = packet_size;
	wth->phdr.len = orig_size;

	if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
		if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
			/*
			 * Nokia IPSO ATM.
			 *
			 * Guess the traffic type based on the packet
			 * contents.
			 */
			atm_guess_traffic_type(buffer_start_ptr(wth->frame_buffer),
			    wth->phdr.caplen, &wth->pseudo_header);
		} else {
			/*
			 * SunATM.
			 *
			 * If this is ATM LANE traffic, try to guess what
			 * type of LANE traffic it is based on the packet
			 * contents.
			 */
			if (wth->pseudo_header.atm.type == TRAF_LANE) {
				atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer),
				    wth->phdr.caplen, &wth->pseudo_header);
			}
		}
	}

	return TRUE;
}