Beispiel #1
0
/* Returns TRUE if packet data copied, FALSE if error occurred or EOF (no more records). */
static gboolean
collate(pppdump_t* state, FILE_T fh, int *err, gchar **err_info, guint8 *pd,
		int *num_bytes, direction_enum *direction, pkt_id *pid,
		gint64 num_bytes_to_skip)
{
	int		id;
	pkt_t		*pkt = NULL;
	int		byte0, byte1;
	int		n, num_written = 0;
	gint64		start_offset;
	guint32		time_long;
	guint8		time_short;

	/*
	 * Process any data left over in the current record when doing
	 * sequential processing.
	 */
	if (state->num_bytes > 0) {
		g_assert(num_bytes_to_skip == 0);
		pkt = state->pkt;
		num_written = process_data(state, fh, pkt, state->num_bytes,
		    pd, err, err_info, pid);

		if (num_written < 0) {
			return FALSE;
		}
		else if (num_written > 0) {
			*num_bytes = num_written;
			*direction = pkt->dir;
			return TRUE;
		}
		/* if 0 bytes written, keep processing */
	} else {
		/*
		 * We didn't have any data left over, so the packet will
		 * start at the beginning of a record.
		 */
		if (pid)
			pid->num_bytes_to_skip = 0;
	}

	/*
	 * That didn't get all the data for this packet, so process
	 * subsequent records.
	 */
	start_offset = state->offset;
	while ((id = file_getc(fh)) != EOF) {
		state->offset++;
		switch (id) {
			case PPPD_SENT_DATA:
			case PPPD_RECV_DATA:
				pkt = id == PPPD_SENT_DATA ? &state->spkt : &state->rpkt;

				/*
				 * Save the offset of the beginning of
				 * the current record.
				 */
				pkt->cd_offset = state->offset - 1;

				/*
				 * Get the length of the record.
				 */
				byte0 = file_getc(fh);
				if (byte0 == EOF)
					goto done;
				state->offset++;
				byte1 = file_getc(fh);
				if (byte1 == EOF)
					goto done;
				state->offset++;
				n = (byte0 << 8) | byte1;

				if (pkt->id_offset == 0) {
					/*
					 * We don't have the initial data
					 * offset for this packet, which
					 * means this is the first
					 * data record for that packet.
					 * Save the offset of the
					 * beginning of that record and
					 * the offset of the first data
					 * byte in the packet, which is
					 * the first data byte in the
					 * record.
					 */
					pkt->id_offset = pkt->cd_offset;
					pkt->sd_offset = state->offset;
				}

				if (n == 0)
					continue;

				g_assert(num_bytes_to_skip < n);
				while (num_bytes_to_skip) {
					if (file_getc(fh) == EOF)
						goto done;
					state->offset++;
					num_bytes_to_skip--;
					n--;
				}
				num_written = process_data(state, fh, pkt, n,
				    pd, err, err_info, pid);

				if (num_written < 0) {
					return FALSE;
				}
				else if (num_written > 0) {
					*num_bytes = num_written;
					*direction = pkt->dir;
					return TRUE;
				}
				/* if 0 bytes written, keep looping */
				break;

			case PPPD_SEND_DELIM:
			case PPPD_RECV_DELIM:
				/* What can we do? */
				break;

			case PPPD_RESET_TIME:
				wtap_file_read_unknown_bytes(&time_long, sizeof(guint32), fh, err, err_info);
				state->offset += sizeof(guint32);
				state->timestamp = pntohl(&time_long);
				state->tenths = 0;
				break;

			case PPPD_TIME_STEP_LONG:
				wtap_file_read_unknown_bytes(&time_long, sizeof(guint32), fh, err, err_info);
				state->offset += sizeof(guint32);
				state->tenths += pntohl(&time_long);

				if (state->tenths >= 10) {
					state->timestamp += state->tenths / 10;
					state->tenths = state->tenths % 10;
				}

				break;

			case PPPD_TIME_STEP_SHORT:
				wtap_file_read_unknown_bytes(&time_short, sizeof(guint8), fh, err, err_info);
				state->offset += sizeof(guint8);
				state->tenths += time_short;

				if (state->tenths >= 10) {
					state->timestamp += state->tenths / 10;
					state->tenths = state->tenths % 10;
				}

				break;

			default:
				/* XXX - bad file */
				*err = WTAP_ERR_BAD_FILE;
				*err_info = g_strdup_printf("pppdump: bad ID byte 0x%02x", id);
				return FALSE;
		}

	}

done:
	*err = file_error(fh, err_info);
	if (*err == 0) {
		if (state->offset != start_offset) {
			/*
			 * We read at least one byte, so we were working
			 * on a record; an EOF means that record was
			 * cut short.
			 */
			*err = WTAP_ERR_SHORT_READ;
		}
	}
	return FALSE;
}
int airopeek9_open(wtap *wth, int *err, gchar **err_info)
{
    airopeek_section_header_t ap_hdr;
    int ret;
    guint32 fileVersion;
    guint32 mediaType;
    guint32 mediaSubType = 0;
    int file_encap;
    static const int airopeek9_encap[] = {
	WTAP_ENCAP_ETHERNET,
	WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
	WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
	WTAP_ENCAP_IEEE_802_11_WITH_RADIO
    };
    #define NUM_AIROPEEK9_ENCAPS (sizeof airopeek9_encap / sizeof airopeek9_encap[0])
    airopeek9_t *airopeek9;

    wtap_file_read_unknown_bytes(&ap_hdr, sizeof(ap_hdr), wth->fh, err);

    if (memcmp (ap_hdr.section_id, "\177ver", sizeof(ap_hdr.section_id)) != 0)
	return 0;	/* doesn't begin with a "\177ver" section */

    /*
     * XXX - we should get the length of the "\177ver" section, check
     * that it's followed by a little-endian 0x00000200, and then,
     * when reading the XML, make sure we don't go past the end of
     * that section, and skip to the end of that section when
     * we have the file version (and possibly check to make sure all
     * tags are properly opened and closed).
     */
    ret = wtap_file_read_pattern (wth, "<FileVersion>", err);
    if (ret != 1) {
	/* 0 means EOF, which means "not a valid AiroPeek V9 file";
	   -1 means error, and "err" has been set. */
	return ret;
    }
    ret = wtap_file_read_number (wth, &fileVersion, err);
    if (ret != 1) {
	/* 0 means EOF, which means "not a valid AiroPeek V9 file";
	   -1 means error, and "err" has been set. */
	return ret;
    }

    /* If we got this far, we assume it's an AiroPeek V9 file. */
    if (fileVersion != 9) {
	/* We only support version 9. */
	*err = WTAP_ERR_UNSUPPORTED;
	*err_info = g_strdup_printf("airopeekv9: version %u unsupported",
	    fileVersion);
	return -1;
    }

    /*
     * XXX - once we've skipped the "\177ver" section, we should
     * check for a "sess" section and fail if we don't see it.
     * Then we should get the length of the "sess" section, check
     * that it's followed by a little-endian 0x00000200, and then,
     * when reading the XML, make sure we don't go past the end of
     * that section, and skip to the end of the section when
     * we have the file version (and possibly check to make sure all
     * tags are properly opened and closed).
     */
    ret = wtap_file_read_pattern (wth, "<MediaType>", err);
    if (ret == -1)
	return -1;
    if (ret == 0) {
	*err = WTAP_ERR_UNSUPPORTED;
	*err_info = g_strdup("airopeekv9: <MediaType> tag not found");
	return -1;
    }
    /* XXX - this appears to be 0 in both the EtherPeek and AiroPeek
       files we've seen; should we require it to be 0? */
    ret = wtap_file_read_number (wth, &mediaType, err);
    if (ret == -1)
	return -1;
    if (ret == 0) {
	*err = WTAP_ERR_UNSUPPORTED;
	*err_info = g_strdup("airopeekv9: <MediaType> value not found");
	return -1;
    }

    ret = wtap_file_read_pattern (wth, "<MediaSubType>", err);
    if (ret == -1)
	return -1;
    if (ret == 0) {
	*err = WTAP_ERR_UNSUPPORTED;
	*err_info = g_strdup("airopeekv9: <MediaSubType> tag not found");
	return -1;
    }
    ret = wtap_file_read_number (wth, &mediaSubType, err);
    if (ret == -1)
	return -1;
    if (ret == 0) {
	*err = WTAP_ERR_UNSUPPORTED;
	*err_info = g_strdup("airopeekv9: <MediaSubType> value not found");
	return -1;
    }
    if (mediaSubType >= NUM_AIROPEEK9_ENCAPS
        || airopeek9_encap[mediaSubType] == WTAP_ENCAP_UNKNOWN) {
	*err = WTAP_ERR_UNSUPPORTED_ENCAP;
	*err_info = g_strdup_printf("airopeekv9: network type %u unknown or unsupported",
	    mediaSubType);
	return -1;
    }

    ret = wtap_file_read_pattern (wth, "pkts", err);
    if (ret == -1)
	return -1;
    if (ret == 0) {
	*err = WTAP_ERR_SHORT_READ;
	return -1;
    }

    /* skip 8 zero bytes */
    if (file_seek (wth->fh, 8L, SEEK_CUR, err) == -1)
	return 0;

    /*
     * This is an EtherPeek or AiroPeek V9 file.
     */
    wth->data_offset = file_tell (wth->fh);

    file_encap = airopeek9_encap[mediaSubType];

    wth->file_type = WTAP_FILE_AIROPEEK_V9;
    wth->file_encap = file_encap;
    wth->subtype_read = airopeekv9_read;
    wth->subtype_seek_read = airopeekv9_seek_read;
    wth->tsprecision = WTAP_FILE_TSPREC_NSEC;

    airopeek9 = (airopeek9_t *)g_malloc(sizeof(airopeek9_t));
    wth->priv = (void *)airopeek9;
    switch (mediaSubType) {

    case AIROPEEK_V9_NST_ETHERNET:
    case AIROPEEK_V9_NST_802_11:
    case AIROPEEK_V9_NST_802_11_2:
	airopeek9->has_fcs = FALSE;
	break;

    case AIROPEEK_V9_NST_802_11_WITH_FCS:
	airopeek9->has_fcs = TRUE;
	break;
    }

    wth->snapshot_length   = 0; /* not available in header */

    return 1;
}
Beispiel #3
0
int
pppdump_open(wtap *wth, int *err, gchar **err_info)
{
	guint8		buffer[6];	/* Looking for: 0x07 t3 t2 t1 t0 ID */
	pppdump_t	*state;

	/* There is no file header, only packet records. Fortunately for us,
	* timestamp records are separated from packet records, so we should
	* find an "initial time stamp" (i.e., a "reset time" record, or
	* record type 0x07) at the beginning of the file. We'll check for
	* that, plus a valid record following the 0x07 and the four bytes
	* representing the timestamp.
	*/

	wtap_file_read_unknown_bytes(buffer, sizeof(buffer), wth->fh, err,
	    err_info);

	if (buffer[0] == PPPD_RESET_TIME &&
			(buffer[5] == PPPD_SENT_DATA ||
			 buffer[5] == PPPD_RECV_DATA ||
			 buffer[5] == PPPD_TIME_STEP_LONG ||
			 buffer[5] == PPPD_TIME_STEP_SHORT ||
			 buffer[5] == PPPD_RESET_TIME)) {

		goto my_file_type;
	}
	else {
		return 0;
	}

  my_file_type:

	if (file_seek(wth->fh, 5, SEEK_SET, err) == -1)
		return -1;

	state = (pppdump_t *)g_malloc(sizeof(pppdump_t));
	wth->priv = (void *)state;
	state->timestamp = pntohl(&buffer[1]);
	state->tenths = 0;

	init_state(state);

	state->offset = 5;
	wth->file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
	wth->file_type = WTAP_FILE_PPPDUMP;

	wth->snapshot_length = PPPD_BUF_SIZE; /* just guessing */
	wth->subtype_read = pppdump_read;
	wth->subtype_seek_read = pppdump_seek_read;
	wth->subtype_close = pppdump_close;
	wth->tsprecision = WTAP_FILE_TSPREC_DSEC;

	state->seek_state = g_new(pppdump_t,1);

	/* If we have a random stream open, we're going to be reading
	   the file randomly; set up a GPtrArray of pointers to
	   information about how to retrieve the data for each packet. */
	if (wth->random_fh != NULL)
		state->pids = g_ptr_array_new();
	else
		state->pids = NULL;
	state->pkt_cnt = 0;

	return 1;
}
Beispiel #4
0
int etherpeek_open(wtap *wth, int *err, gchar **err_info)
{
	etherpeek_header_t ep_hdr;
	struct timeval reference_time;
	int file_encap;
	etherpeek_t *etherpeek;

	/* EtherPeek files do not start with a magic value large enough
	 * to be unique; hence we use the following algorithm to determine
	 * the type of an unknown file:
	 *  - populate the master header and reject file if there is no match
	 *  - populate the secondary header and check that the reserved space
	 *      is zero, and check some other fields; this isn't perfect,
	 *	and we may have to add more checks at some point.
	 */
	g_assert(sizeof(ep_hdr.master) == ETHERPEEK_MASTER_HDR_SIZE);
	wtap_file_read_unknown_bytes(
		&ep_hdr.master, sizeof(ep_hdr.master), wth->fh, err, err_info);

	/*
	 * It appears that EtherHelp (a free application from WildPackets
	 * that did blind capture, saving to a file, so that you could
	 * give the resulting file to somebody with EtherPeek) saved
	 * captures in EtherPeek format except that it ORed the 0x80
	 * bit on in the version number.
	 *
	 * We therefore strip off the 0x80 bit in the version number.
	 * Perhaps there's some reason to care whether the capture
	 * came from EtherHelp; if we discover one, we should check
	 * that bit.
	 */
	ep_hdr.master.version &= ~0x80;

	/* switch on the file version */
	switch (ep_hdr.master.version) {

	case 5:
	case 6:
	case 7:
		/* get the secondary header */
		g_assert(sizeof(ep_hdr.secondary.v567) ==
		        ETHERPEEK_V567_HDR_SIZE);
		wtap_file_read_unknown_bytes(
			&ep_hdr.secondary.v567,
			sizeof(ep_hdr.secondary.v567), wth->fh, err, err_info);

		if ((0 != ep_hdr.secondary.v567.reserved[0]) ||
		    (0 != ep_hdr.secondary.v567.reserved[1]) ||
		    (0 != ep_hdr.secondary.v567.reserved[2])) {
			/* still unknown */
			return 0;
		}

		/*
		 * Check the mediaType and physMedium fields.
		 * We assume it's not an EtherPeek/TokenPeek/AiroPeek
		 * file if these aren't values we know, rather than
		 * reporting them as invalid *Peek files, as, given
		 * the lack of a magic number, we need all the checks
		 * we can get.
		 */
		ep_hdr.secondary.v567.mediaType =
		    g_ntohl(ep_hdr.secondary.v567.mediaType);
		ep_hdr.secondary.v567.physMedium =
		    g_ntohl(ep_hdr.secondary.v567.physMedium);

		switch (ep_hdr.secondary.v567.physMedium) {

		case 0:
			/*
			 * "Native" format, presumably meaning
			 * Ethernet or Token Ring.
			 */
			switch (ep_hdr.secondary.v567.mediaType) {

			case 0:
				file_encap = WTAP_ENCAP_ETHERNET;
				break;

			case 1:
				file_encap = WTAP_ENCAP_TOKEN_RING;
				break;

			default:
				/*
				 * Assume this isn't a *Peek file.
				 */
				return 0;
			}
			break;

		case 1:
			switch (ep_hdr.secondary.v567.mediaType) {

			case 0:
				/*
				 * 802.11, with a private header giving
				 * some radio information.  Presumably
				 * this is from AiroPeek.
				 */
				file_encap = WTAP_ENCAP_IEEE_802_11_AIROPEEK;
				break;

			default:
				/*
				 * Assume this isn't a *Peek file.
				 */
				return 0;
			}
			break;

		default:
			/*
			 * Assume this isn't a *Peek file.
			 */
			return 0;
		}


		/*
		 * Assume this is a V5, V6 or V7 *Peek file, and byte
		 * swap the rest of the fields in the secondary header.
		 *
		 * XXX - we could check the file length if the file were
		 * uncompressed, but it might be compressed.
		 */
		ep_hdr.secondary.v567.filelength =
		    g_ntohl(ep_hdr.secondary.v567.filelength);
		ep_hdr.secondary.v567.numPackets =
		    g_ntohl(ep_hdr.secondary.v567.numPackets);
		ep_hdr.secondary.v567.timeDate =
		    g_ntohl(ep_hdr.secondary.v567.timeDate);
		ep_hdr.secondary.v567.timeStart =
		    g_ntohl(ep_hdr.secondary.v567.timeStart);
		ep_hdr.secondary.v567.timeStop =
		    g_ntohl(ep_hdr.secondary.v567.timeStop);
		ep_hdr.secondary.v567.appVers =
		    g_ntohl(ep_hdr.secondary.v567.appVers);
		ep_hdr.secondary.v567.linkSpeed =
		    g_ntohl(ep_hdr.secondary.v567.linkSpeed);

		/* Get the reference time as a "struct timeval" */
		reference_time.tv_sec  =
		    ep_hdr.secondary.v567.timeDate - mac2unix;
		reference_time.tv_usec = 0;
		break;

	default:
		/*
		 * Assume this isn't a *Peek file.
		 */
		return 0;
	}

	/*
	 * This is an EtherPeek (or TokenPeek or AiroPeek?) file.
	 *
	 * At this point we have recognised the file type and have populated
	 * the whole ep_hdr structure in host byte order.
	 */
	etherpeek = (etherpeek_t *)g_malloc(sizeof(etherpeek_t));
	wth->priv = (void *)etherpeek;
	etherpeek->reference_time = reference_time;
	switch (ep_hdr.master.version) {

	case 5:
	case 6:
		wth->file_type = WTAP_FILE_ETHERPEEK_V56;
		/*
		 * XXX - can we get the file encapsulation from the
		 * header in the same way we do for V7 files?
		 */
		wth->file_encap = WTAP_ENCAP_PER_PACKET;
		wth->subtype_read = etherpeek_read_v56;
		wth->subtype_seek_read = etherpeek_seek_read_v56;
		break;

	case 7:
		wth->file_type = WTAP_FILE_ETHERPEEK_V7;
		wth->file_encap = file_encap;
		wth->subtype_read = etherpeek_read_v7;
		wth->subtype_seek_read = etherpeek_seek_read_v7;
		break;

	default:
		/* this is impossible */
		g_assert_not_reached();
	}

	wth->snapshot_length   = 0; /* not available in header */
	wth->tsprecision = WTAP_FILE_TSPREC_USEC;

	return 1;
}