Пример #1
0
static int
read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_header, guint8 *pd,
    int length, int *err, char **err_info)
{
    int seek_increment;
    int bytes_consumed = 0;

    /* validate offsets */
    if (offset_to_frame < current_offset_from_packet_header) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("Observer: bad record (offset to packet data %d < %d)",
            offset_to_frame, current_offset_from_packet_header);
        return -1;
    }

    /* skip to the packet data */
    seek_increment = offset_to_frame - current_offset_from_packet_header;
    if (seek_increment > 0) {
        if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1) {
            return -1;
        }
        bytes_consumed += seek_increment;
    }

    /* read in the packet data */
    wtap_file_read_expected_bytes(pd, length, fh, err, err_info);
    bytes_consumed += length;

    return bytes_consumed;
}
Пример #2
0
/* Read IPFIX message header from file.  Return true on success.  Set *err to
 * 0 on EOF, any other value for "real" errors (EOF is ok, since return
 * value is still FALSE)
 */
static gboolean
ipfix_read_message_header(ipfix_message_header_t *pfx_hdr, FILE_T fh, int *err, gchar **err_info)
{
    wtap_file_read_expected_bytes(pfx_hdr, IPFIX_MSG_HDR_SIZE, fh, err, err_info);  /* macro which does a return if read fails */

    /* fix endianess, because IPFIX files are always big-endian */
    pfx_hdr->version = g_ntohs(pfx_hdr->version);
    pfx_hdr->message_length = g_ntohs(pfx_hdr->message_length);
    pfx_hdr->export_time_secs = g_ntohl(pfx_hdr->export_time_secs);
    pfx_hdr->sequence_number = g_ntohl(pfx_hdr->sequence_number);
    pfx_hdr->observation_id = g_ntohl(pfx_hdr->observation_id);

    /* is the version number one we expect? */
    if (pfx_hdr->version != IPFIX_VERSION) {
        /* Not an ipfix file. */
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("ipfix: wrong version %d", pfx_hdr->version);
        return FALSE;
    }

    if (pfx_hdr->message_length < 16) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("ipfix: message length %u is too short", pfx_hdr->message_length);
        return FALSE;
    }

    /* go back to before header */
    if (file_seek(fh, 0 - IPFIX_MSG_HDR_SIZE, SEEK_CUR, err) == -1) {
        ipfix_debug0("ipfix_read: couldn't go back in file before header");
        return FALSE;
    }

    return TRUE;
}
Пример #3
0
/* classic wtap: read packet */
static gboolean
ipfix_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{
    ipfix_message_header_t msg_hdr;

    *data_offset = file_tell(wth->fh);
    ipfix_debug1("ipfix_read: data_offset is initially %" G_GINT64_MODIFIER "d", *data_offset);

    if (!ipfix_read_message_header(&msg_hdr, wth->fh, err, err_info)) {
        ipfix_debug2("ipfix_read: couldn't read message header with code: %d\n, and error '%s'",
                     *err, *err_info);
        return FALSE;
    }

    buffer_assure_space(wth->frame_buffer, msg_hdr.message_length);
    wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer),
                   msg_hdr.message_length, wth->fh, err, err_info);

    wth->phdr.presence_flags = 0;
    wth->phdr.len = msg_hdr.message_length;
    wth->phdr.caplen = msg_hdr.message_length;
    wth->phdr.ts.secs =  0;
    wth->phdr.ts.nsecs = 0;

    /*ipfix_debug2("Read length: %u Packet length: %u", msg_hdr.message_length, wth->phdr.caplen);*/
    ipfix_debug1("ipfix_read: data_offset is finally %" G_GINT64_MODIFIER "d", file_tell(wth->fh));

    return TRUE;
}
Пример #4
0
/* classic wtap: seek to file position and read packet */
static gboolean
ipfix_seek_read(wtap *wth, gint64 seek_off,
    union wtap_pseudo_header *pseudo_header, guint8 *pd, int length _U_,
    int *err, gchar **err_info)
{
    ipfix_message_header_t msg_hdr;

    (void) pseudo_header; /* avoids compiler warning about unused variable */

    /* seek to the right file position */
    if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) {
        ipfix_debug2("ipfix_seek_read: couldn't read message header with code: %d\n, and error '%s'",
                     *err, *err_info);
        return FALSE;   /* Seek error */
    }

    ipfix_debug1("ipfix_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);

    if (!ipfix_read_message_header(&msg_hdr, wth->random_fh, err, err_info)) {
        ipfix_debug0("ipfix_read: couldn't read message header");
        return FALSE;
    }

    if(length != (int)msg_hdr.message_length) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("ipfix: record length %u doesn't match requested length %d",
                                    msg_hdr.message_length, length);
        ipfix_debug1("ipfix_seek_read: %s", *err_info);
        return FALSE;
    }

    wtap_file_read_expected_bytes(pd, length, wth->random_fh, err, err_info);

    return TRUE;
}
Пример #5
0
static gboolean
peekclassic_seek_read_v56(wtap *wth, gint64 seek_off,
    struct wtap_pkthdr *phdr, guint8 *pd, int length,
    int *err, gchar **err_info)
{
	union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
	guint8 ep_pkt[PEEKCLASSIC_V56_PKT_SIZE];
	int pkt_encap;
	guint16 protoNum;
	unsigned int i;

	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
		return FALSE;

	wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->random_fh,
	    err, err_info);

	protoNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_PROTONUM_OFFSET]);
	pkt_encap = WTAP_ENCAP_UNKNOWN;
	for (i=0; i<NUM_PEEKCLASSIC_ENCAPS; i++) {
		if (peekclassic_encap[i].protoNum == protoNum) {
			pkt_encap = peekclassic_encap[i].encap;
		}
	}

	switch (pkt_encap) {

	case WTAP_ENCAP_ETHERNET:
		/* We assume there's no FCS in this frame. */
		pseudo_header->eth.fcs_len = 0;
		break;
	}

	/*
	 * XXX - should "errno" be set in "wtap_file_read_expected_bytes()"?
	 */
	errno = WTAP_ERR_CANT_READ;
	wtap_file_read_expected_bytes(pd, length, wth->random_fh, err,
	    err_info);
	return TRUE;
}
Пример #6
0
static gboolean
peekclassic_seek_read_v7(wtap *wth, gint64 seek_off,
    struct wtap_pkthdr *phdr, guint8 *pd, int length,
    int *err, gchar **err_info)
{
	union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
	guint8 ep_pkt[PEEKCLASSIC_V7_PKT_SIZE];
	guint8  status;

	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
		return FALSE;

	/* Read the packet header. */
	wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->random_fh,
	    err, err_info);
	status = ep_pkt[PEEKCLASSIC_V7_STATUS_OFFSET];

	switch (wth->file_encap) {

	case WTAP_ENCAP_IEEE_802_11_AIROPEEK:
		pseudo_header->ieee_802_11.fcs_len = 0;		/* no FCS */
		pseudo_header->ieee_802_11.decrypted = FALSE;
		break;

	case WTAP_ENCAP_ETHERNET:
		/* XXX - it appears that if the low-order bit of
		   "status" is 0, there's an FCS in this frame,
		   and if it's 1, there's 4 bytes of 0. */
		pseudo_header->eth.fcs_len = (status & 0x01) ? 0 : 4;
		break;
	}

	/*
	 * XXX - should "errno" be set in "wtap_file_read_expected_bytes()"?
	 */
	errno = WTAP_ERR_CANT_READ;
	wtap_file_read_expected_bytes(pd, length, wth->random_fh, err,
	    err_info);
	return TRUE;
}
Пример #7
0
static gboolean tnef_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{
  guint8 *buf;
  gint64 file_size;
  int packet_size;
  struct stat statb;

  *err = 0;

  /* there is only ever one packet */
  if(wth->data_offset)
    return FALSE;

  *data_offset = wth->data_offset;

  if ((file_size = wtap_file_size(wth, err)) == -1)
    return FALSE;

  if (file_size > WTAP_MAX_PACKET_SIZE) {
    /*
     * Probably a corrupt capture file; don't blow up trying
     * to allocate space for an immensely-large packet.
     */
    *err = WTAP_ERR_BAD_RECORD;
    *err_info = g_strdup_printf("tnef: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
				file_size, WTAP_MAX_PACKET_SIZE);
    return FALSE;
  }
  packet_size = (int)file_size;

  buffer_assure_space(wth->frame_buffer, packet_size);
  buf = buffer_start_ptr(wth->frame_buffer);

  wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err);

  wth->data_offset += packet_size;

  wth->phdr.caplen = packet_size;
  wth->phdr.len = packet_size;

  if (fstat(wth->fd, &statb) == -1) {
    *err = errno;
    return FALSE;
  }

  wth->phdr.ts.secs = statb.st_mtime;
  wth->phdr.ts.nsecs = 0;

  return TRUE;
}
Пример #8
0
static gboolean ber_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{
  gint64 offset;
  guint8 *buf;
  gint64 file_size;
  int packet_size;

  *err = 0;

  offset = file_tell(wth->fh);

  /* there is only ever one packet */
  if (offset != 0)
    return FALSE;

  *data_offset = offset;

  if ((file_size = wtap_file_size(wth, err)) == -1)
    return FALSE;

  if (file_size > WTAP_MAX_PACKET_SIZE) {
    /*
     * Probably a corrupt capture file; don't blow up trying
     * to allocate space for an immensely-large packet.
     */
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup_printf("ber: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
				file_size, WTAP_MAX_PACKET_SIZE);
    return FALSE;
  }
  packet_size = (int)file_size;

  buffer_assure_space(wth->frame_buffer, packet_size);
  buf = buffer_start_ptr(wth->frame_buffer);

  wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err, err_info);

  wth->phdr.presence_flags = 0; /* yes, we have no bananas^Wtime stamp */

  wth->phdr.caplen = packet_size;
  wth->phdr.len = packet_size;

  wth->phdr.ts.secs = 0;
  wth->phdr.ts.nsecs = 0;

  return TRUE;
}
Пример #9
0
static gboolean
jpeg_jfif_read(wtap *wth, int *err, gchar **err_info,
		gint64 *data_offset)
{
	guint8 *buf;
	gint64 file_size;
	int packet_size;
	gint64 capture_size;

	*err = 0;

	/* interpret the file as one packet only */
	if (wth->data_offset)
		return FALSE;

	*data_offset = wth->data_offset;

	if ((file_size = wtap_file_size(wth, err)) == -1)
		return FALSE;

	/* Read maximum possible packet size */
	if (file_size <= WTAP_MAX_PACKET_SIZE) {
		capture_size = file_size;
	} else {
		capture_size = WTAP_MAX_PACKET_SIZE;
	}
	packet_size = (int)capture_size;

	buffer_assure_space(wth->frame_buffer, packet_size);
	buf = buffer_start_ptr(wth->frame_buffer);

	wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err);

	wth->data_offset += packet_size;

	wth->phdr.caplen = packet_size;
	wth->phdr.len = (int)file_size;

	wth->phdr.ts.secs = 0;
	wth->phdr.ts.nsecs = 0;

	*err_info = NULL;
	return TRUE;
}
Пример #10
0
static gboolean
read_packet_data(FILE_T fh, int offset_to_frame, int offset, guint8 *pd,
    int length, int *err, char **err_info)
{
	int seek_increment;

	/* get to the packet data */
	if (offset_to_frame < offset) {
		*err = WTAP_ERR_BAD_RECORD;
		*err_info = g_strdup_printf("Observer: bad record (offset to packet data %d < %d)",
		    offset_to_frame, offset);
		return FALSE;
	}
	seek_increment = offset_to_frame - offset;
	if (seek_increment > 0) {
		if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1)
			return FALSE;
	}

	/* read in the packet */
	wtap_file_read_expected_bytes(pd, length, fh, err);
	return TRUE;
}
Пример #11
0
static gboolean
airopeekv9_seek_read(wtap *wth, gint64 seek_off,
    union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
    int *err, gchar **err_info)
{
    airopeek9_t *airopeek9 = (airopeek9_t *)wth->priv;
    hdr_info_t hdr_info;

    if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
	return FALSE;

    /* Process the packet header. */
    if (airopeekv9_process_header(wth->random_fh, &hdr_info, err, err_info) == -1)
	return FALSE;

    switch (wth->file_encap) {

    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
	pseudo_header->ieee_802_11 = hdr_info.ieee_802_11;
	if (airopeek9->has_fcs)
	    pseudo_header->ieee_802_11.fcs_len = 4;
	else
	    pseudo_header->ieee_802_11.fcs_len = 0;
	break;

    case WTAP_ENCAP_ETHERNET:
	pseudo_header->eth.fcs_len = 0;
	break;
    }

    /*
     * XXX - should "errno" be set in "wtap_file_read_expected_bytes()"?
     */
    errno = WTAP_ERR_CANT_READ;
    wtap_file_read_expected_bytes(pd, length, wth->random_fh, err);
    return TRUE;
}
Пример #12
0
static gboolean
peekclassic_read_v56(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{
	peekclassic_t *peekclassic = (peekclassic_t *)wth->priv;
	guint8 ep_pkt[PEEKCLASSIC_V56_PKT_SIZE];
	guint16 length;
	guint16 sliceLength;
#if 0
	guint8  flags;
	guint8  status;
#endif
	guint32 timestamp;
#if 0
	guint16 destNum;
	guint16 srcNum;
#endif
	guint16 protoNum;
	char    protoStr[8];
	unsigned int i;

	/*
	 * XXX - in order to figure out whether this packet is an
	 * Ethernet packet or not, we have to look at the packet
	 * header, so we have to remember the address of the header,
	 * not the address of the data, for random access.
	 *
	 * If we can determine that from the file header, rather than
	 * the packet header, we can remember the offset of the data,
	 * and not have the seek_read routine read the header.
	 */
	*data_offset = file_tell(wth->fh);

	wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->fh, err,
	    err_info);

	/* Extract the fields from the packet */
	length = pntohs(&ep_pkt[PEEKCLASSIC_V56_LENGTH_OFFSET]);
	sliceLength = pntohs(&ep_pkt[PEEKCLASSIC_V56_SLICE_LENGTH_OFFSET]);
#if 0
	flags = ep_pkt[PEEKCLASSIC_V56_FLAGS_OFFSET];
	status = ep_pkt[PEEKCLASSIC_V56_STATUS_OFFSET];
#endif
	timestamp = pntohl(&ep_pkt[PEEKCLASSIC_V56_TIMESTAMP_OFFSET]);
#if 0
	destNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_DESTNUM_OFFSET]);
	srcNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_SRCNUM_OFFSET]);
#endif
	protoNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_PROTONUM_OFFSET]);
	memcpy(protoStr, &ep_pkt[PEEKCLASSIC_V56_PROTOSTR_OFFSET],
	    sizeof protoStr);

	/*
	 * XXX - is the captured packet data padded to a multiple
	 * of 2 bytes?
	 */

	/* force sliceLength to be the actual length of the packet */
	if (0 == sliceLength) {
		sliceLength = length;
	}

	/* read the frame data */
	buffer_assure_space(wth->frame_buffer, sliceLength);
	wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer),
	                              sliceLength, wth->fh, err, err_info);

	/* fill in packet header values */
	wth->phdr.len        = length;
	wth->phdr.caplen     = sliceLength;
	/* timestamp is in milliseconds since reference_time */
	wth->phdr.ts.secs  = peekclassic->reference_time.tv_sec
	    + (timestamp / 1000);
	wth->phdr.ts.nsecs = 1000 * (timestamp % 1000) * 1000;

	wth->phdr.pkt_encap = WTAP_ENCAP_UNKNOWN;
	for (i=0; i<NUM_PEEKCLASSIC_ENCAPS; i++) {
		if (peekclassic_encap[i].protoNum == protoNum) {
			wth->phdr.pkt_encap = peekclassic_encap[i].encap;
		}
	}

	switch (wth->phdr.pkt_encap) {

	case WTAP_ENCAP_ETHERNET:
		/* We assume there's no FCS in this frame. */
		wth->phdr.pseudo_header.eth.fcs_len = 0;
		break;
	}
	return TRUE;
}
Пример #13
0
static gboolean
commview_read_header(commview_header_t *cv_hdr, FILE_T fh, int *err,
    gchar **err_info)
{
	wtap_file_read_expected_bytes(&cv_hdr->data_len, 2, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->source_data_len, 2, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->version, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->year, 2, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->month, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->day, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->hours, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->minutes, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->seconds, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->usecs, 4, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->flags, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->signal_level_percent, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->rate, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->band, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->channel, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->direction, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->signal_level_dbm, 1, fh, err, err_info);
	wtap_file_read_expected_bytes(&cv_hdr->noise_level, 1, fh, err, err_info);

	/* Convert multi-byte values from little endian to host endian format */
	cv_hdr->data_len = GUINT16_FROM_LE(cv_hdr->data_len);
	cv_hdr->source_data_len = GUINT16_FROM_LE(cv_hdr->source_data_len);
	cv_hdr->year = GUINT16_FROM_LE(cv_hdr->year);
	cv_hdr->usecs = GUINT32_FROM_LE(cv_hdr->usecs);

	return TRUE;
}
Пример #14
0
/* classic wtap: open capture file.  Return 1 on success, 0 on normal failure
 * like malformed format, -1 on bad error like file system
 */
int
ipfix_open(wtap *wth, int *err, gchar **err_info)
{
    gint i, n, records_for_ipfix_check = RECORDS_FOR_IPFIX_CHECK;
    gchar *s;
    guint16 checked_len = 0;
    ipfix_message_header_t msg_hdr;
    ipfix_set_header_t set_hdr;

    ipfix_debug0("ipfix_open: opening file");

    /* number of records to scan before deciding if this really is IPFIX */
    if ((s = getenv("IPFIX_RECORDS_TO_CHECK")) != NULL) {
        if ((n = atoi(s)) > 0 && n < 101) {
            records_for_ipfix_check = n;
        }
    }

    /*
     * IPFIX is a little hard because there's no magic number; we look at
     * the first few records and see if they look enough like IPFIX
     * records.
     */
    for (i = 0; i < records_for_ipfix_check; i++) {
        /* read first message header to check version */
        if (!ipfix_read_message_header(&msg_hdr, wth->fh, err, err_info)) {
            ipfix_debug3("ipfix_open: couldn't read message header #%d with err code #%d (%s)",
                         i, *err, *err_info);
            if (*err == WTAP_ERR_BAD_FILE) {
                *err = 0;            /* not actually an error in this case */
                g_free(*err_info);
                *err_info = NULL;
                return 0;
            }
            if (*err != 0)
                return -1; /* real failure */
            /* else it's EOF */
            if (i < 1) {
                /* we haven't seen enough to prove this is a ipfix file */
                return 0;
            }
            /* if we got here, it's EOF and we think it's an ipfix file */
            break;
        }
        if (file_seek(wth->fh, IPFIX_MSG_HDR_SIZE, SEEK_CUR, err) == -1) {
            ipfix_debug1("ipfix_open: failed seek to next message in file, %d bytes away",
                         msg_hdr.message_length);
            return 0;
        }
        checked_len = IPFIX_MSG_HDR_SIZE;

        /* check each Set in IPFIX Message for sanity */
        while (checked_len < msg_hdr.message_length) {
            wtap_file_read_expected_bytes(&set_hdr, IPFIX_SET_HDR_SIZE, wth->fh, err, err_info);
            set_hdr.set_length = g_ntohs(set_hdr.set_length);
            if ((set_hdr.set_length < IPFIX_SET_HDR_SIZE) ||
                ((set_hdr.set_length + checked_len) > msg_hdr.message_length))  {
                ipfix_debug1("ipfix_open: found invalid set_length of %d",
                             set_hdr.set_length);
                             return 0;
            }

            if (file_seek(wth->fh, set_hdr.set_length - IPFIX_SET_HDR_SIZE,
                 SEEK_CUR, err) == -1)
            {
                ipfix_debug1("ipfix_open: failed seek to next set in file, %d bytes away",
                             set_hdr.set_length - IPFIX_SET_HDR_SIZE);
                return 0;
            }
            checked_len += set_hdr.set_length;
        }
    }

    /* all's good, this is a IPFIX file */
    wth->file_encap = WTAP_ENCAP_RAW_IPFIX;
    wth->snapshot_length = 0;
    wth->tsprecision = WTAP_FILE_TSPREC_SEC;
    wth->subtype_read = ipfix_read;
    wth->subtype_seek_read = ipfix_seek_read;
    wth->subtype_close = ipfix_close;
    wth->file_type = WTAP_FILE_IPFIX;

    /* go back to beginning of file */
    if (file_seek (wth->fh, 0, SEEK_SET, err) != 0)
    {
        return -1;
    }
    return 1;
}
Пример #15
0
static gboolean airopeekv9_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
    airopeek9_t *airopeek9 = (airopeek9_t *)wth->priv;
    hdr_info_t hdr_info;
    int hdrlen;
    double  t;

    *data_offset = wth->data_offset;

    /* Process the packet header. */
    hdrlen = airopeekv9_process_header(wth->fh, &hdr_info, err, err_info);
    if (hdrlen == 0)
	return FALSE;
    wth->data_offset += hdrlen;

    /*
     * If sliceLength is 0, force it to be the actual length of the packet.
     */
    if (hdr_info.sliceLength == 0)
	hdr_info.sliceLength = hdr_info.length;

    if (hdr_info.sliceLength > WTAP_MAX_PACKET_SIZE) {
	/*
	 * Probably a corrupt capture file; don't blow up trying
	 * to allocate space for an immensely-large packet.
	 */
	*err = WTAP_ERR_BAD_RECORD;
	*err_info = g_strdup_printf("airopeek9: File has %u-byte packet, bigger than maximum of %u",
	    hdr_info.sliceLength, WTAP_MAX_PACKET_SIZE);
	return FALSE;
    }

    /* fill in packet header length values before slicelength may be
       adjusted */
    wth->phdr.len    = hdr_info.length;
    wth->phdr.caplen = hdr_info.sliceLength;

    /* read the frame data */
    buffer_assure_space(wth->frame_buffer, hdr_info.sliceLength);
    wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer),
				  hdr_info.sliceLength, wth->fh, err);
    wth->data_offset += hdr_info.sliceLength;

    /* recalculate and fill in packet time stamp */
    t =  (double) hdr_info.timestamp.lower +
	 (double) hdr_info.timestamp.upper * 4294967296.0;

    t *= 1.0e-9;
    t -= TIME_FIXUP_CONSTANT;
    wth->phdr.ts.secs  = (time_t) t;
    wth->phdr.ts.nsecs = (guint32) ((t - wth->phdr.ts.secs)*1000000000);

    switch (wth->file_encap) {

    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
	/*
	 * The last 4 bytes sometimes contains the FCS but on a lot of
	 * interfaces these are zero.  Is there some way to determine
	 * from the packet header whether it's an FCS or not?
	 *
	 * For now, we just discard those bytes; if we can determine
	 * whether it's an FCS or not, we should use that to determine
	 * whether to supply it as an FCS or discard it.
	 */
	wth->pseudo_header.ieee_802_11 = hdr_info.ieee_802_11;
	if (airopeek9->has_fcs)
	    wth->pseudo_header.ieee_802_11.fcs_len = 4;
	else {
	    wth->pseudo_header.ieee_802_11.fcs_len = 0;
	    wth->phdr.len -= 4;
	    wth->phdr.caplen -= 4;
	}
	break;

    case WTAP_ENCAP_ETHERNET:
	/*
	 * The last 4 bytes appear to be 0 in the captures I've seen;
	 * are there any captures where it's an FCS?
	 */
	wth->pseudo_header.eth.fcs_len = 0;
	wth->phdr.len -= 4;
	wth->phdr.caplen -= 4;
	break;
    }

    return TRUE;
}
Пример #16
0
static gboolean peekclassic_read_packet_v56(wtap *wth, FILE_T fh,
    struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
	peekclassic_t *peekclassic = (peekclassic_t *)wth->priv;
	guint8 ep_pkt[PEEKCLASSIC_V56_PKT_SIZE];
	guint16 length;
	guint16 sliceLength;
#if 0
	guint8  flags;
	guint8  status;
#endif
	guint32 timestamp;
#if 0
	guint16 destNum;
	guint16 srcNum;
#endif
	guint16 protoNum;
#if 0
	char    protoStr[8];
#endif
	unsigned int i;

	wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), fh, err,
	    err_info);

	/* Extract the fields from the packet */
	length = pntohs(&ep_pkt[PEEKCLASSIC_V56_LENGTH_OFFSET]);
	sliceLength = pntohs(&ep_pkt[PEEKCLASSIC_V56_SLICE_LENGTH_OFFSET]);
#if 0
	flags = ep_pkt[PEEKCLASSIC_V56_FLAGS_OFFSET];
	status = ep_pkt[PEEKCLASSIC_V56_STATUS_OFFSET];
#endif
	timestamp = pntohl(&ep_pkt[PEEKCLASSIC_V56_TIMESTAMP_OFFSET]);
#if 0
	destNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_DESTNUM_OFFSET]);
	srcNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_SRCNUM_OFFSET]);
#endif
	protoNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_PROTONUM_OFFSET]);
#if 0
	memcpy(protoStr, &ep_pkt[PEEKCLASSIC_V56_PROTOSTR_OFFSET],
	    sizeof protoStr);
#endif

	/*
	 * XXX - is the captured packet data padded to a multiple
	 * of 2 bytes?
	 */

	/* force sliceLength to be the actual length of the packet */
	if (0 == sliceLength) {
		sliceLength = length;
	}

	/* fill in packet header values */
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	/* timestamp is in milliseconds since reference_time */
	phdr->ts.secs  = peekclassic->reference_time.tv_sec
	    + (timestamp / 1000);
	phdr->ts.nsecs = 1000 * (timestamp % 1000) * 1000;
	phdr->len      = length;
	phdr->caplen   = sliceLength;

	phdr->pkt_encap = WTAP_ENCAP_UNKNOWN;
	for (i=0; i<NUM_PEEKCLASSIC_ENCAPS; i++) {
		if (peekclassic_encap[i].protoNum == protoNum) {
			phdr->pkt_encap = peekclassic_encap[i].encap;
		}
	}

	switch (phdr->pkt_encap) {

	case WTAP_ENCAP_ETHERNET:
		/* We assume there's no FCS in this frame. */
		phdr->pseudo_header.eth.fcs_len = 0;
		break;
	}

	/* read the packet data */
	return wtap_read_packet_bytes(fh, buf, sliceLength, err, err_info);
}
Пример #17
0
static gboolean
peekclassic_read_v7(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{
	guint8 ep_pkt[PEEKCLASSIC_V7_PKT_SIZE];
#if 0
	guint16 protoNum;
#endif
	guint16 length;
	guint16 sliceLength;
#if 0
	guint8  flags;
#endif
	guint8  status;
	guint64 timestamp;
	time_t tsecs;
	guint32 tusecs;

	*data_offset = file_tell(wth->fh);

	wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->fh, err,
	    err_info);

	/* Extract the fields from the packet */
#if 0
	protoNum = pntohs(&ep_pkt[PEEKCLASSIC_V7_PROTONUM_OFFSET]);
#endif
	length = pntohs(&ep_pkt[PEEKCLASSIC_V7_LENGTH_OFFSET]);
	sliceLength = pntohs(&ep_pkt[PEEKCLASSIC_V7_SLICE_LENGTH_OFFSET]);
#if 0
	flags = ep_pkt[PEEKCLASSIC_V7_FLAGS_OFFSET];
#endif
	status = ep_pkt[PEEKCLASSIC_V7_STATUS_OFFSET];
	timestamp = pntohll(&ep_pkt[PEEKCLASSIC_V7_TIMESTAMP_OFFSET]);

	/* force sliceLength to be the actual length of the packet */
	if (0 == sliceLength) {
		sliceLength = length;
	}

	wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	
	/* fill in packet header length values before slicelength may be
	   adjusted */
	wth->phdr.len    = length;
	wth->phdr.caplen = sliceLength;

	if (sliceLength % 2) /* packets are padded to an even length */
		sliceLength++;

	switch (wth->file_encap) {

	case WTAP_ENCAP_IEEE_802_11_AIROPEEK:
		wth->phdr.pseudo_header.ieee_802_11.fcs_len = 0;		/* no FCS */
		wth->phdr.pseudo_header.ieee_802_11.decrypted = FALSE;
		break;

	case WTAP_ENCAP_ETHERNET:
		/* XXX - it appears that if the low-order bit of
		   "status" is 0, there's an FCS in this frame,
		   and if it's 1, there's 4 bytes of 0. */
		wth->phdr.pseudo_header.eth.fcs_len = (status & 0x01) ? 0 : 4;
		break;
	}

	/* read the frame data */
	buffer_assure_space(wth->frame_buffer, sliceLength);
	wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer),
	                              sliceLength, wth->fh, err, err_info);

	/* fill in packet header values */
	tsecs = (time_t) (timestamp/1000000);
	tusecs = (guint32) (timestamp - tsecs*1000000);
	wth->phdr.ts.secs  = tsecs - mac2unix;
	wth->phdr.ts.nsecs = tusecs * 1000;

	if (wth->file_encap == WTAP_ENCAP_IEEE_802_11_AIROPEEK) {
		/*
		 * The last 4 bytes appear to be random data - the length
		 * might include the FCS - so we reduce the length by 4.
		 *
		 * Or maybe this is just the same kind of random 4 bytes
		 * of junk at the end you get in Wireless Sniffer
		 * captures.
		 */
		 wth->phdr.len -= 4;
		 wth->phdr.caplen -= 4;
	}

	return TRUE;
}