Ejemplo n.º 1
0
static gboolean peekclassic_read_v7(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	int sliceLength;

	*data_offset = file_tell(wth->fh);

	/* Read the packet. */
	sliceLength = peekclassic_read_packet_v7(wth, wth->fh, &wth->phdr,
	    wth->frame_buffer, err, err_info);
	if (sliceLength < 0)
		return FALSE;

	/* Skip extra ignored data at the end of the packet. */
	if ((guint32)sliceLength > wth->phdr.caplen) {
		if (!wtap_read_bytes(wth->fh, NULL, sliceLength - wth->phdr.caplen,
		    err, err_info))
			return FALSE;
	}

	/* Records are padded to an even length, so if the slice length
	   is odd, read the padding byte. */
	if (sliceLength & 0x01) {
		if (!wtap_read_bytes(wth->fh, NULL, 1, err, err_info))
			return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 2
0
wtap_open_return_val aethra_open(wtap *wth, int *err, gchar **err_info)
{
	struct aethra_hdr hdr;
	struct tm tm;
	aethra_t *aethra;

	/* Read in the string that should be at the start of a "aethra" file */
	if (!wtap_read_bytes(wth->fh, hdr.magic, sizeof hdr.magic, err,
	    err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	if (memcmp(hdr.magic, aethra_magic, sizeof aethra_magic) != 0)
		return WTAP_OPEN_NOT_MINE;

	/* Read the rest of the header. */
	if (!wtap_read_bytes(wth->fh, (char *)&hdr + sizeof hdr.magic,
	    sizeof hdr - sizeof hdr.magic, err, err_info))
		return WTAP_OPEN_ERROR;
	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_AETHRA;
	aethra = (aethra_t *)g_malloc(sizeof(aethra_t));
	wth->priv = (void *)aethra;
	wth->subtype_read = aethra_read;
	wth->subtype_seek_read = aethra_seek_read;

	/*
	 * Convert the time stamp to a "time_t".
	 */
	tm.tm_year = pletoh16(&hdr.start_year) - 1900;
	tm.tm_mon = pletoh16(&hdr.start_month) - 1;
	tm.tm_mday = pletoh16(&hdr.start_day);
	tm.tm_hour = hdr.start_hour;
	tm.tm_min = hdr.start_min;
	tm.tm_sec = hdr.start_sec;
	tm.tm_isdst = -1;
	aethra->start = mktime(&tm);

	/*
	 * We've only seen ISDN files, so, for now, we treat all
	 * files as ISDN.
	 */
	wth->file_encap = WTAP_ENCAP_ISDN;
	wth->snapshot_length = 0;	/* not available in header */
	wth->file_tsprec = WTAP_TSPREC_MSEC;
	return WTAP_OPEN_MINE;
}
Ejemplo n.º 3
0
static int
read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_header, Buffer *buf,
    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 (!wtap_read_bytes(fh, NULL, seek_increment, err, err_info)) {
            return -1;
        }
        bytes_consumed += seek_increment;
    }

    /* read in the packet data */
    if (!wtap_read_packet_bytes(fh, buf, length, err, err_info))
        return FALSE;
    bytes_consumed += length;

    return bytes_consumed;
}
Ejemplo n.º 4
0
wtap_open_return_val tnef_open(wtap *wth, int *err, gchar **err_info)
{
  guint32 magic;

  if (!wtap_read_bytes(wth->fh, &magic, sizeof magic, err, err_info))
    return (*err != WTAP_ERR_SHORT_READ) ? WTAP_OPEN_ERROR : WTAP_OPEN_NOT_MINE;

  if (GUINT32_TO_LE(magic) != TNEF_SIGNATURE)
     /* Not a tnef file */
     return WTAP_OPEN_NOT_MINE;

  /* seek back to the start of the file  */
  if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
    return WTAP_OPEN_ERROR;

  wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_TNEF;
  wth->file_encap = WTAP_ENCAP_TNEF;
  wth->snapshot_length = 0;

  wth->subtype_read = tnef_read;
  wth->subtype_seek_read = tnef_seek_read;
  wth->file_tsprec = WTAP_TSPREC_SEC;

  return WTAP_OPEN_MINE;
}
Ejemplo n.º 5
0
wtap_open_return_val stanag4607_open(wtap *wth, int *err, gchar **err_info)
{
  guint16 version_id;
  stanag4607_t *stanag4607;

  if (!wtap_read_bytes(wth->fh, &version_id, sizeof version_id, err, err_info))
    return (*err != WTAP_ERR_SHORT_READ) ? WTAP_OPEN_ERROR : WTAP_OPEN_NOT_MINE;

  if (!is_valid_id(GUINT16_TO_BE(version_id)))
     /* Not a stanag4607 file */
     return WTAP_OPEN_NOT_MINE;

  /* seek back to the start of the file  */
  if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
    return WTAP_OPEN_ERROR;

  wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_STANAG_4607;
  wth->file_encap = WTAP_ENCAP_STANAG_4607;
  wth->snapshot_length = 0; /* not known */

  stanag4607 = (stanag4607_t *)g_malloc(sizeof(stanag4607_t));
  wth->priv = (void *)stanag4607;
  stanag4607->base_secs = 0; /* unknown as of yet */

  wth->subtype_read = stanag4607_read;
  wth->subtype_seek_read = stanag4607_seek_read;
  wth->file_tsprec = WTAP_TSPREC_MSEC;

  return WTAP_OPEN_MINE;
}
Ejemplo n.º 6
0
/*
 * Read packet data into a Buffer, growing the buffer as necessary.
 *
 * This returns an error on a short read, even if the short read hit
 * the EOF immediately.  (The assumption is that each packet has a
 * header followed by raw packet data, and that we've already read the
 * header, so if we get an EOF trying to read the packet data, the file
 * has been cut short, even if the read didn't read any data at all.)
 */
gboolean
wtap_read_packet_bytes(FILE_T fh, Buffer *buf, guint length, int *err,
    gchar **err_info)
{
	ws_buffer_assure_space(buf, length);
	return wtap_read_bytes(fh, ws_buffer_start_ptr(buf), length, err,
	    err_info);
}
Ejemplo n.º 7
0
wtap_open_return_val i4btrace_open(wtap *wth, int *err, gchar **err_info)
{
	i4b_trace_hdr_t hdr;
	gboolean byte_swapped = FALSE;
	i4btrace_t *i4btrace;

	/* I4B trace files have no magic in the header... Sigh */
	if (!wtap_read_bytes(wth->fh, &hdr, sizeof(hdr), err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	/* Silly heuristic... */
	if (!I4B_HDR_IS_OK(hdr)) {
		/*
		 * OK, try byte-swapping the header fields.
		 */
		hdr.length = GUINT32_SWAP_LE_BE(hdr.length);
		hdr.unit = GUINT32_SWAP_LE_BE(hdr.unit);
		hdr.type = GUINT32_SWAP_LE_BE(hdr.type);
		hdr.dir = GUINT32_SWAP_LE_BE(hdr.dir);
		hdr.trunc = GUINT32_SWAP_LE_BE(hdr.trunc);
		if (!I4B_HDR_IS_OK(hdr)) {
			/*
			 * It doesn't look valid in either byte order.
			 */
			return WTAP_OPEN_NOT_MINE;
		}

		/*
		 * It looks valid byte-swapped, so assume it's a
		 * trace written in the opposite byte order.
		 */
		byte_swapped = TRUE;
	}

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

	/* Get capture start time */

	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_I4BTRACE;
	i4btrace = (i4btrace_t *)g_malloc(sizeof(i4btrace_t));
	wth->priv = (void *)i4btrace;
	wth->subtype_read = i4btrace_read;
	wth->subtype_seek_read = i4btrace_seek_read;
	wth->snapshot_length = 0;	/* not known */

	i4btrace->byte_swapped = byte_swapped;

	wth->file_encap = WTAP_ENCAP_ISDN;
	wth->file_tsprec = WTAP_TSPREC_USEC;

	return WTAP_OPEN_MINE;
}
Ejemplo n.º 8
0
static gboolean
snoop_read_shomiti_wireless_pseudoheader(FILE_T fh,
    union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info,
    int *header_size)
{
	shomiti_wireless_header whdr;
	int	rsize;

	if (!wtap_read_bytes(fh, &whdr, sizeof whdr, err, err_info))
		return FALSE;

	/* the 4th byte of the pad is actually a header length,
	 * we've already read 8 bytes of it, and it must never
	 * be less than 8.
	 *
	 * XXX - presumably that means that the header length
	 * doesn't include the length field, as we've read
	 * 12 bytes total.
	 *
	 * XXX - what's in the other 3 bytes of the padding?  Is it a
	 * 4-byte length field?
	 * XXX - is there anything in the rest of the header of interest?
	 * XXX - are there any files where the header is shorter than
	 * 4 bytes of length plus 8 bytes of information?
	 */
	if (whdr.pad[3] < 8) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("snoop: Header length in Surveyor record is %u, less than minimum of 8",
		    whdr.pad[3]);
		return FALSE;
	}
	/* Skip the header. */
	rsize = ((int) whdr.pad[3]) - 8;
	if (file_seek(fh, rsize, SEEK_CUR, err) == -1)
		return FALSE;

	memset(&pseudo_header->ieee_802_11, 0, sizeof(pseudo_header->ieee_802_11));
	pseudo_header->ieee_802_11.fcs_len = 4;
	pseudo_header->ieee_802_11.decrypted = FALSE;
	pseudo_header->ieee_802_11.datapad = FALSE;
	pseudo_header->ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;
	pseudo_header->ieee_802_11.has_channel = TRUE;
	pseudo_header->ieee_802_11.channel = whdr.channel;
	pseudo_header->ieee_802_11.has_data_rate = TRUE;
	pseudo_header->ieee_802_11.data_rate = whdr.rate;
	pseudo_header->ieee_802_11.has_signal_percent = TRUE;
	pseudo_header->ieee_802_11.signal_percent = whdr.signal;

	/* add back the header and don't forget the pad as well */
	*header_size = rsize + 8 + 4;

	return TRUE;
}
Ejemplo n.º 9
0
wtap_open_return_val hcidump_open(wtap *wth, int *err, gchar **err_info)
{
	struct dump_hdr dh;
	guint8 type;

	if (!wtap_read_bytes(wth->fh, &dh, DUMP_HDR_SIZE, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	if ((dh.in != 0 && dh.in != 1) || dh.pad != 0
	    || GUINT16_FROM_LE(dh.len) < 1)
		return WTAP_OPEN_NOT_MINE;

	if (!wtap_read_bytes(wth->fh, &type, 1, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	if (type < 1 || type > 4)
		return WTAP_OPEN_NOT_MINE;

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

	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_HCIDUMP;
	wth->file_encap = WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR;
	wth->snapshot_length = 0;

	wth->subtype_read = hcidump_read;
	wth->subtype_seek_read = hcidump_seek_read;
	wth->file_tsprec = WTAP_TSPREC_USEC;

	return WTAP_OPEN_MINE;
}
Ejemplo n.º 10
0
/* Read the next packet */
static gboolean
_5views_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err,
    gchar **err_info, gint64 *data_offset)
{
	t_5VW_TimeStamped_Header TimeStamped_Header;

	/*
	 * Keep reading until we see a record with a subtype of
	 * CST_5VW_FRAME_RECORD.
	 */
	do
	{
		*data_offset = file_tell(wth->fh);

		/* Read record header. */
		if (!_5views_read_header(wth, wth->fh, &TimeStamped_Header,
		    rec, err, err_info))
			return FALSE;

		if (TimeStamped_Header.RecSubType == CST_5VW_FRAME_RECORD) {
			/*
			 * OK, this is a packet.
			 */
			break;
		}

		/*
		 * Not a packet - skip to the next record.
		 */
		if (!wtap_read_bytes(wth->fh, NULL, TimeStamped_Header.RecSize, err, err_info))
			return FALSE;
	} while (1);

	if (rec->rec_header.packet_header.caplen > WTAP_MAX_PACKET_SIZE_STANDARD) {
		/*
		 * 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("5views: File has %u-byte packet, bigger than maximum of %u",
		    rec->rec_header.packet_header.caplen, WTAP_MAX_PACKET_SIZE_STANDARD);
		return FALSE;
	}

	return wtap_read_packet_bytes(wth->fh, buf,
	    rec->rec_header.packet_header.caplen, err, err_info);
}
Ejemplo n.º 11
0
static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
    int skip_len;

    *data_offset = file_tell(wth->fh);

    /* Read the packet. */
    skip_len = peektagged_read_packet(wth, wth->fh, &wth->phdr,
                                      wth->frame_buffer, err, err_info);
    if (skip_len == -1)
        return FALSE;

    if (skip_len != 0) {
        /* Skip extra junk at the end of the packet data. */
        if (!wtap_read_bytes(wth->fh, NULL, skip_len, err, err_info))
            return FALSE;
    }

    return TRUE;
}
Ejemplo n.º 12
0
wtap_open_return_val eyesdn_open(wtap *wth, int *err, gchar **err_info)
{
	char	magic[EYESDN_HDR_MAGIC_SIZE];

	/* Look for eyesdn header */
	if (!wtap_read_bytes(wth->fh, &magic, sizeof magic, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}
	if (memcmp(magic, eyesdn_hdr_magic, EYESDN_HDR_MAGIC_SIZE) != 0)
		return WTAP_OPEN_NOT_MINE;

	wth->file_encap = WTAP_ENCAP_PER_PACKET;
	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_EYESDN;
	wth->snapshot_length = 0; /* not known */
	wth->subtype_read = eyesdn_read;
	wth->subtype_seek_read = eyesdn_seek_read;
	wth->file_tsprec = WTAP_TSPREC_USEC;

	return WTAP_OPEN_MINE;
}
Ejemplo n.º 13
0
static gboolean
skip_to_next_packet(wtap *wth, int offset_to_next_packet, int current_offset_from_packet_header, int *err,
    char **err_info)
{
    int seek_increment;

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

    /* skip to the next packet header */
    seek_increment = offset_to_next_packet - current_offset_from_packet_header;
    if (seek_increment > 0) {
        if (!wtap_read_bytes(wth->fh, NULL, seek_increment, err, err_info))
            return FALSE;
    }

    return TRUE;
}
Ejemplo n.º 14
0
/* Read the next packet */
static gboolean radcom_read(wtap *wth, wtap_rec *rec, Buffer *buf,
			    int *err, gchar **err_info, gint64 *data_offset)
{
	char	fcs[2];

	*data_offset = file_tell(wth->fh);

	/* Read record. */
	if (!radcom_read_rec(wth, wth->fh, rec, buf, err, err_info)) {
		/* Read error or EOF */
		return FALSE;
	}

	if (wth->file_encap == WTAP_ENCAP_LAPB) {
		/* Read the FCS.
		   XXX - should we have some way of indicating the
		   presence and size of an FCS to our caller?
		   That'd let us handle other file types as well. */
		if (!wtap_read_bytes(wth->fh, &fcs, sizeof fcs, err, err_info))
			return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 15
0
static int
read_packet_header(wtap *wth, FILE_T fh, union wtap_pseudo_header *pseudo_header,
    packet_entry_header *packet_header, int *err, gchar **err_info)
{
    int offset;
    guint i;
    tlv_header tlvh;
    int seek_increment;
    tlv_wireless_info wireless_header;

    offset = 0;

    /* pull off the packet header */
    if (!wtap_read_bytes_or_eof(fh, packet_header, sizeof *packet_header,
                                err, err_info)) {
        if (*err != 0)
            return -1;
        return 0;    /* EOF */
    }
    offset += (int)sizeof *packet_header;
    PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(*packet_header);

    /* check the packet's magic number */
    if (packet_header->packet_magic != observer_packet_magic) {

        /*
         * Some files are zero-padded at the end. There is no warning of this
         * in the previous packet header information, such as setting
         * offset_to_next_packet to zero. So detect this situation by treating
         * an all-zero header as a sentinel. Return EOF when it is encountered,
         * rather than treat it as a bad record.
         */
        for (i = 0; i < sizeof *packet_header; i++) {
            if (((guint8*) packet_header)[i] != 0)
                break;
        }
        if (i == sizeof *packet_header) {
            *err = 0;
            return 0;    /* EOF */
        }

        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("Observer: bad record: Invalid magic number 0x%08x",
            packet_header->packet_magic);
        return -1;
    }

    /* initialize the pseudo header */
    switch (wth->file_encap) {
    case WTAP_ENCAP_ETHERNET:
        /* There is no FCS in the frame */
        pseudo_header->eth.fcs_len = 0;
        break;
    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
        memset(&pseudo_header->ieee_802_11, 0, sizeof(pseudo_header->ieee_802_11));
        pseudo_header->ieee_802_11.fcs_len = 0;
        pseudo_header->ieee_802_11.decrypted = FALSE;
        pseudo_header->ieee_802_11.datapad = FALSE;
        pseudo_header->ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;
        /* Updated below */
        break;
    }

    /* process extra information */
    for (i = 0; i < packet_header->number_of_information_elements; i++) {
        /* read the TLV header */
        if (!wtap_read_bytes(fh, &tlvh, sizeof tlvh, err, err_info))
            return -1;
        offset += (int)sizeof tlvh;
        TLV_HEADER_FROM_LE_IN_PLACE(tlvh);

        if (tlvh.length < sizeof tlvh) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)",
                tlvh.length, (unsigned long)sizeof tlvh);
            return -1;
        }

        /* process (or skip over) the current TLV */
        switch (tlvh.type) {
        case INFORMATION_TYPE_WIRELESS:
            if (!wtap_read_bytes(fh, &wireless_header, sizeof wireless_header,
                                 err, err_info))
                return -1;
            /* set decryption status */
            /* XXX - what other bits are there in conditions? */
            pseudo_header->ieee_802_11.decrypted = (wireless_header.conditions & WIRELESS_WEP_SUCCESS) != 0;
            pseudo_header->ieee_802_11.has_channel = TRUE;
            pseudo_header->ieee_802_11.channel = wireless_header.frequency;
            pseudo_header->ieee_802_11.has_data_rate = TRUE;
            pseudo_header->ieee_802_11.data_rate = wireless_header.rate;
            pseudo_header->ieee_802_11.has_signal_percent = TRUE;
            pseudo_header->ieee_802_11.signal_percent = wireless_header.strengthPercent;
            offset += (int)sizeof wireless_header;
            break;
        default:
            /* skip the TLV data */
            seek_increment = tlvh.length - (int)sizeof tlvh;
            if (seek_increment > 0) {
                if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1)
                    return -1;
            }
            offset += seek_increment;
        }
    }

    return offset;
}
Ejemplo n.º 16
0
static gboolean lanalyzer_read_trace_record(wtap *wth, FILE_T fh,
                                            struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
      char         LE_record_type[2];
      char         LE_record_length[2];
      guint16      record_type, record_length;
      int          record_data_size;
      int          packet_size;
      gchar        descriptor[DESCRIPTOR_LEN];
      lanalyzer_t *lanalyzer;
      guint16      time_low, time_med, time_high, true_size;
      guint64      t;
      time_t       tsecs;

      /* read the record type and length. */
      if (!wtap_read_bytes_or_eof(fh, LE_record_type, 2, err, err_info))
            return FALSE;
      if (!wtap_read_bytes(fh, LE_record_length, 2, err, err_info))
            return FALSE;

      record_type = pletoh16(LE_record_type);
      record_length = pletoh16(LE_record_length);

      /* Only Trace Packet Data Records should occur now that we're in
       * the middle of reading packets.  If any other record type exists
       * after a Trace Packet Data Record, mark it as an error. */
      if (record_type != RT_PacketData) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("lanalyzer: record type %u seen after trace summary record",
                                        record_type);
            return FALSE;
      }

      if (record_length < DESCRIPTOR_LEN) {
            /*
             * Uh-oh, the record isn't big enough to even have a
             * descriptor.
             */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("lanalyzer: file has a %u-byte record, too small to have even a packet descriptor",
                                        record_length);
            return FALSE;
      }
      record_data_size = record_length - DESCRIPTOR_LEN;

      /* Read the descriptor data */
      if (!wtap_read_bytes(fh, descriptor, DESCRIPTOR_LEN, err, err_info))
            return FALSE;

      true_size = pletoh16(&descriptor[4]);
      packet_size = pletoh16(&descriptor[6]);
      /*
       * The maximum value of packet_size is 65535, which is less than
       * WTAP_MAX_PACKET_SIZE will ever be, so we don't need to check
       * it.
       */

      /*
       * OK, is the frame data size greater than than what's left of the
       * record?
       */
      if (packet_size > record_data_size) {
            /*
             * Yes - treat this as an error.
             */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("lanalyzer: Record length is less than packet size");
            return FALSE;
      }

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

      time_low = pletoh16(&descriptor[8]);
      time_med = pletoh16(&descriptor[10]);
      time_high = pletoh16(&descriptor[12]);
      t = (((guint64)time_low) << 0) + (((guint64)time_med) << 16) +
            (((guint64)time_high) << 32);
      tsecs = (time_t) (t/2000000);
      lanalyzer = (lanalyzer_t *)wth->priv;
      phdr->ts.secs = tsecs + lanalyzer->start;
      phdr->ts.nsecs = ((guint32) (t - tsecs*2000000)) * 500;

      if (true_size - 4 >= packet_size) {
            /*
             * It appears that the "true size" includes the FCS;
             * make it reflect the non-FCS size (the "packet size"
             * appears never to include the FCS, even if no slicing
             * is done).
             */
            true_size -= 4;
      }
      phdr->len = true_size;
      phdr->caplen = packet_size;

      switch (wth->file_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, packet_size, err, err_info);
}
Ejemplo n.º 17
0
wtap_open_return_val network_instruments_open(wtap *wth, int *err, gchar **err_info)
{
    int offset;
    capture_file_header file_header;
    guint i;
    tlv_header tlvh;
    int seek_increment;
    int header_offset;
    packet_entry_header packet_header;
    observer_dump_private_state * private_state = NULL;

    offset = 0;

    /* read in the buffer file header */
    if (!wtap_read_bytes(wth->fh, &file_header, sizeof file_header,
                         err, err_info)) {
        if (*err != WTAP_ERR_SHORT_READ)
            return WTAP_OPEN_ERROR;
        return WTAP_OPEN_NOT_MINE;
    }
    offset += (int)sizeof file_header;
    CAPTURE_FILE_HEADER_FROM_LE_IN_PLACE(file_header);

    /* check if version info is present */
    if (memcmp(file_header.observer_version, network_instruments_magic, true_magic_length)!=0) {
        return WTAP_OPEN_NOT_MINE;
    }

    /* initialize the private state */
    private_state = (observer_dump_private_state *) g_malloc(sizeof(observer_dump_private_state));
    private_state->time_format = TIME_INFO_LOCAL;
    wth->priv = (void *) private_state;

    /* get the location of the first packet */
    /* v15 and newer uses high byte offset, in previous versions it will be 0 */
    header_offset = file_header.offset_to_first_packet + ((int)(file_header.offset_to_first_packet_high_byte)<<16);

    /* process extra information */
    for (i = 0; i < file_header.number_of_information_elements; i++) {
        /* for safety break if we've reached the first packet */
        if (offset >= header_offset)
            break;

        /* read the TLV header */
        if (!wtap_read_bytes(wth->fh, &tlvh, sizeof tlvh, err, err_info))
            return WTAP_OPEN_ERROR;
        offset += (int)sizeof tlvh;
        TLV_HEADER_FROM_LE_IN_PLACE(tlvh);

        if (tlvh.length < sizeof tlvh) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)",
                tlvh.length, (unsigned long)sizeof tlvh);
            return WTAP_OPEN_ERROR;
        }

        /* process (or skip over) the current TLV */
        switch (tlvh.type) {
        case INFORMATION_TYPE_TIME_INFO:
            if (!wtap_read_bytes(wth->fh, &private_state->time_format,
                                 sizeof private_state->time_format,
                                 err, err_info))
                return WTAP_OPEN_ERROR;
            private_state->time_format = GUINT32_FROM_LE(private_state->time_format);
            offset += (int)sizeof private_state->time_format;
            break;
        default:
            seek_increment = tlvh.length - (int)sizeof tlvh;
            if (seek_increment > 0) {
                if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
                    return WTAP_OPEN_ERROR;
            }
            offset += seek_increment;
        }
    }

    /* get to the first packet */
    if (header_offset < offset) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("Observer: bad record (offset to first packet %d < %d)",
            header_offset, offset);
        return WTAP_OPEN_ERROR;
    }
    seek_increment = header_offset - offset;
    if (seek_increment > 0) {
        if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
            return WTAP_OPEN_ERROR;
    }

    /* pull off the packet header */
    if (!wtap_read_bytes(wth->fh, &packet_header, sizeof packet_header,
                         err, err_info))
        return WTAP_OPEN_ERROR;
    PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(packet_header);

    /* check the packet's magic number */
    if (packet_header.packet_magic != observer_packet_magic) {
        *err = WTAP_ERR_UNSUPPORTED;
        *err_info = g_strdup_printf("Observer: unsupported packet version %ul", packet_header.packet_magic);
        return WTAP_OPEN_ERROR;
    }

    /* check the data link type */
    if (observer_to_wtap_encap(packet_header.network_type) == WTAP_ENCAP_UNKNOWN) {
        *err = WTAP_ERR_UNSUPPORTED;
        *err_info = g_strdup_printf("Observer: network type %u unknown or unsupported", packet_header.network_type);
        return WTAP_OPEN_ERROR;
    }
    wth->file_encap = observer_to_wtap_encap(packet_header.network_type);

    /* set up the rest of the capture parameters */
    private_state->packet_count = 0;
    private_state->network_type = wtap_to_observer_encap(wth->file_encap);
    wth->subtype_read = observer_read;
    wth->subtype_seek_read = observer_seek_read;
    wth->subtype_close = NULL;
    wth->subtype_sequential_close = NULL;
    wth->snapshot_length = 0;    /* not available in header */
    wth->file_tsprec = WTAP_TSPREC_NSEC;
    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETWORK_INSTRUMENTS;

    /* reset the pointer to the first packet */
    if (file_seek(wth->fh, header_offset, SEEK_SET, err) == -1)
        return WTAP_OPEN_ERROR;

    init_gmt_to_localtime_offset();

    return WTAP_OPEN_MINE;
}
Ejemplo n.º 18
0
static gboolean
snoop_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
    int *err, gchar **err_info)
{
	struct snoop_atm_hdr atm_phdr;
	guint8	vpi;
	guint16	vci;

	if (!wtap_read_bytes(fh, &atm_phdr, sizeof atm_phdr, err, err_info))
		return FALSE;

	vpi = atm_phdr.vpi;
	vci = pntoh16(&atm_phdr.vci);

	/*
	 * The lower 4 bits of the first byte of the header indicate
	 * the type of traffic, as per the "atmioctl.h" header in
	 * SunATM.
	 */
	switch (atm_phdr.flags & 0x0F) {

	case 0x01:	/* LANE */
		pseudo_header->atm.aal = AAL_5;
		pseudo_header->atm.type = TRAF_LANE;
		break;

	case 0x02:	/* RFC 1483 LLC multiplexed traffic */
		pseudo_header->atm.aal = AAL_5;
		pseudo_header->atm.type = TRAF_LLCMX;
		break;

	case 0x05:	/* ILMI */
		pseudo_header->atm.aal = AAL_5;
		pseudo_header->atm.type = TRAF_ILMI;
		break;

	case 0x06:	/* Signalling AAL */
		pseudo_header->atm.aal = AAL_SIGNALLING;
		pseudo_header->atm.type = TRAF_UNKNOWN;
		break;

	case 0x03:	/* MARS (RFC 2022) */
		pseudo_header->atm.aal = AAL_5;
		pseudo_header->atm.type = TRAF_UNKNOWN;
		break;

	case 0x04:	/* IFMP (Ipsilon Flow Management Protocol; see RFC 1954) */
		pseudo_header->atm.aal = AAL_5;
		pseudo_header->atm.type = TRAF_UNKNOWN;	/* XXX - TRAF_IPSILON? */
		break;

	default:
		/*
		 * Assume it's AAL5, unless it's VPI 0 and VCI 5, in which
		 * case assume it's AAL_SIGNALLING; we know nothing more
		 * about it.
		 *
		 * XXX - is this necessary?  Or are we guaranteed that
		 * all signalling traffic has a type of 0x06?
		 *
		 * XXX - is this guaranteed to be AAL5?  Or, if the type is
		 * 0x00 ("raw"), might it be non-AAL5 traffic?
		 */
		if (vpi == 0 && vci == 5)
			pseudo_header->atm.aal = AAL_SIGNALLING;
		else
			pseudo_header->atm.aal = AAL_5;
		pseudo_header->atm.type = TRAF_UNKNOWN;
		break;
	}
	pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;

	pseudo_header->atm.vpi = vpi;
	pseudo_header->atm.vci = vci;
	pseudo_header->atm.channel = (atm_phdr.flags & 0x80) ? 0 : 1;

	/* We don't have this information */
	pseudo_header->atm.flags = 0;
	pseudo_header->atm.cells = 0;
	pseudo_header->atm.aal5t_u2u = 0;
	pseudo_header->atm.aal5t_len = 0;
	pseudo_header->atm.aal5t_chksum = 0;

	return TRUE;
}
Ejemplo n.º 19
0
wtap_open_return_val lanalyzer_open(wtap *wth, int *err, gchar **err_info)
{
      LA_RecordHeader rec_header;
      char header_fixed[2];
      char *comment;
      char summary[210];
      guint16 board_type, mxslc;
      guint16 record_type, record_length;
      guint8 cr_day, cr_month;
      guint16 cr_year;
      struct tm tm;
      lanalyzer_t *lanalyzer;

      if (!wtap_read_bytes(wth->fh, &rec_header, LA_RecordHeaderSize,
                           err, err_info)) {
            if (*err != WTAP_ERR_SHORT_READ)
                  return WTAP_OPEN_ERROR;
            return WTAP_OPEN_NOT_MINE;
      }
      record_type = pletoh16(rec_header.record_type);
      record_length = pletoh16(rec_header.record_length); /* make sure to do this for while() loop */

      if (record_type != RT_HeaderRegular && record_type != RT_HeaderCyclic) {
            return WTAP_OPEN_NOT_MINE;
      }

      /* Read the major and minor version numbers */
      if (record_length < 2) {
            /*
             * Not enough room for the major and minor version numbers.
             * Just treat that as a "not a LANalyzer file" indication.
             */
            return WTAP_OPEN_NOT_MINE;
      }
      if (!wtap_read_bytes(wth->fh, &header_fixed, sizeof header_fixed,
                           err, err_info)) {
            if (*err != WTAP_ERR_SHORT_READ)
                  return WTAP_OPEN_ERROR;
            return WTAP_OPEN_NOT_MINE;
      }
      record_length -= sizeof header_fixed;

      if (record_length != 0) {
            /* Read the rest of the record as a comment. */
            comment = (char *)g_malloc(record_length + 1);
            if (!wtap_read_bytes(wth->fh, comment, record_length,
                                 err, err_info)) {
                  if (*err != WTAP_ERR_SHORT_READ) {
                      g_free(comment);
                      return WTAP_OPEN_ERROR;
                  }
                  g_free(comment);
                  return WTAP_OPEN_NOT_MINE;
            }
            wtap_optionblock_set_option_string(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, comment, record_length);
            g_free(comment);
      }

      /* If we made it this far, then the file is a LANAlyzer file.
       * Let's get some info from it. Note that we get wth->snapshot_length
       * from a record later in the file. */
      wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_LANALYZER;
      lanalyzer = (lanalyzer_t *)g_malloc(sizeof(lanalyzer_t));
      wth->priv = (void *)lanalyzer;
      wth->subtype_read = lanalyzer_read;
      wth->subtype_seek_read = lanalyzer_seek_read;
      wth->snapshot_length = 0;
      wth->file_tsprec = WTAP_TSPREC_NSEC;

      /* Read records until we find the start of packets */
      while (1) {
            if (!wtap_read_bytes_or_eof(wth->fh, &rec_header,
                                        LA_RecordHeaderSize, err, err_info)) {
                  if (*err == 0) {
                        /*
                         * End of file and no packets;
                         * accept this file.
                         */
                        return WTAP_OPEN_MINE;
                  }
                  return WTAP_OPEN_ERROR;
            }

            record_type = pletoh16(rec_header.record_type);
            record_length = pletoh16(rec_header.record_length);

            /*g_message("Record 0x%04X Length %d", record_type, record_length);*/
            switch (record_type) {
                  /* Trace Summary Record */
            case RT_Summary:
                  if (!wtap_read_bytes(wth->fh, summary,
                                       sizeof summary, err, err_info))
                        return WTAP_OPEN_ERROR;

                  /* Assume that the date of the creation of the trace file
                   * is the same date of the trace. Lanalyzer doesn't
                   * store the creation date/time of the trace, but only of
                   * the file. Unless you traced at 11:55 PM and saved at 00:05
                   * AM, the assumption that trace.date == file.date is true.
                   */
                  cr_day = summary[0];
                  cr_month = summary[1];
                  cr_year = pletoh16(&summary[2]);
                  /*g_message("Day %d Month %d Year %d (%04X)", cr_day, cr_month,
                    cr_year, cr_year);*/

                  /* Get capture start time. I learned how to do
                   * this from Guy's code in ngsniffer.c
                   */
                  tm.tm_year = cr_year - 1900;
                  tm.tm_mon = cr_month - 1;
                  tm.tm_mday = cr_day;
                  tm.tm_hour = 0;
                  tm.tm_min = 0;
                  tm.tm_sec = 0;
                  tm.tm_isdst = -1;
                  lanalyzer->start = mktime(&tm);
                  /*g_message("Day %d Month %d Year %d", tm.tm_mday,
                    tm.tm_mon, tm.tm_year);*/
                  mxslc = pletoh16(&summary[30]);
                  wth->snapshot_length = mxslc;

                  board_type = pletoh16(&summary[188]);
                  switch (board_type) {
                  case BOARD_325:
                        wth->file_encap = WTAP_ENCAP_ETHERNET;
                        break;
                  case BOARD_325TR:
                        wth->file_encap = WTAP_ENCAP_TOKEN_RING;
                        break;
                  default:
                        *err = WTAP_ERR_UNSUPPORTED;
                        *err_info = g_strdup_printf("lanalyzer: board type %u unknown",
                                                    board_type);
                        return WTAP_OPEN_ERROR;
                  }
                  break;

                  /* Trace Packet Data Record */
            case RT_PacketData:
                  /* Go back header number of bytes so that lanalyzer_read
                   * can read this header */
                  if (file_seek(wth->fh, -LA_RecordHeaderSize, SEEK_CUR, err) == -1) {
                        return WTAP_OPEN_ERROR;
                  }
                  return WTAP_OPEN_MINE;

            default:
                  if (file_seek(wth->fh, record_length, SEEK_CUR, err) == -1) {
                        return WTAP_OPEN_ERROR;
                  }
                  break;
            }
      }
}
Ejemplo n.º 20
0
wtap_open_return_val csids_open(wtap *wth, int *err, gchar **err_info)
{
  /* There is no file header. There is only a header for each packet
   * so we read a packet header and compare the caplen with iplen. They
   * should always be equal except with the weird byteswap version.
   *
   * THIS IS BROKEN-- anytime the caplen is 0x0101 or 0x0202 up to 0x0505
   * this will byteswap it. I need to fix this. XXX --mlh
   */

  int tmp,iplen;

  gboolean byteswap = FALSE;
  struct csids_header hdr;
  csids_t *csids;

  /* check the file to make sure it is a csids file. */
  if( !wtap_read_bytes( wth->fh, &hdr, sizeof( struct csids_header), err, err_info ) ) {
    if( *err != WTAP_ERR_SHORT_READ ) {
      return WTAP_OPEN_ERROR;
    }
    return WTAP_OPEN_NOT_MINE;
  }
  if( hdr.zeropad != 0 || hdr.caplen == 0 ) {
    return WTAP_OPEN_NOT_MINE;
  }
  hdr.seconds = pntoh32( &hdr.seconds );
  hdr.caplen = pntoh16( &hdr.caplen );
  if( !wtap_read_bytes( wth->fh, &tmp, 2, err, err_info ) ) {
    if( *err != WTAP_ERR_SHORT_READ ) {
      return WTAP_OPEN_ERROR;
    }
    return WTAP_OPEN_NOT_MINE;
  }
  if( !wtap_read_bytes(wth->fh, &iplen, 2, err, err_info ) ) {
    if( *err != WTAP_ERR_SHORT_READ ) {
      return WTAP_OPEN_ERROR;
    }
    return WTAP_OPEN_NOT_MINE;
  }
  iplen = pntoh16(&iplen);

  if ( iplen == 0 )
    return WTAP_OPEN_NOT_MINE;

  /* if iplen and hdr.caplen are equal, default to no byteswap. */
  if( iplen > hdr.caplen ) {
    /* maybe this is just a byteswapped version. the iplen ipflags */
    /* and ipid are swapped. We cannot use the normal swaps because */
    /* we don't know the host */
    iplen = GUINT16_SWAP_LE_BE(iplen);
    if( iplen <= hdr.caplen ) {
      /* we know this format */
      byteswap = TRUE;
    } else {
      /* don't know this one */
      return WTAP_OPEN_NOT_MINE;
    }
  } else {
    byteswap = FALSE;
  }

  /* no file header. So reset the fh to 0 so we can read the first packet */
  if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
    return WTAP_OPEN_ERROR;

  csids = (csids_t *)g_malloc(sizeof(csids_t));
  wth->priv = (void *)csids;
  csids->byteswapped = byteswap;
  wth->file_encap = WTAP_ENCAP_RAW_IP;
  wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_CSIDS;
  wth->snapshot_length = 0; /* not known */
  wth->subtype_read = csids_read;
  wth->subtype_seek_read = csids_seek_read;
  wth->file_tsprec = WTAP_TSPREC_SEC;

  return WTAP_OPEN_MINE;
}
Ejemplo n.º 21
0
wtap_open_return_val libpcap_open(wtap *wth, int *err, gchar **err_info)
{
	guint32 magic;
	struct pcap_hdr hdr;
	gboolean byte_swapped;
	gboolean modified;
	gboolean aix;
	int file_encap;
	gint64 first_packet_offset;
	libpcap_t *libpcap;
	static const int subtypes_modified[] = {
		WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029,
		WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915
	};
#define N_SUBTYPES_MODIFIED	G_N_ELEMENTS(subtypes_modified)
	static const int subtypes_standard[] = {
		WTAP_FILE_TYPE_SUBTYPE_PCAP,
		WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417,
		WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA
	};
#define N_SUBTYPES_STANDARD	G_N_ELEMENTS(subtypes_standard)
	static const int subtypes_nsec[] = {
		WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC
	};
#define N_SUBTYPES_NSEC		G_N_ELEMENTS(subtypes_nsec)
#define MAX_FIGURES_OF_MERIT \
	MAX(MAX(N_SUBTYPES_MODIFIED, N_SUBTYPES_STANDARD), N_SUBTYPES_NSEC)
	int figures_of_merit[MAX_FIGURES_OF_MERIT];
	const int *subtypes;
	int n_subtypes;
	int best_subtype;
	int i;

	/* Read in the number that should be at the start of a "libpcap" file */
	if (!wtap_read_bytes(wth->fh, &magic, sizeof magic, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	switch (magic) {

	case PCAP_MAGIC:
		/* Host that wrote it has our byte order, and was running
		   a program using either standard or ss990417 libpcap. */
		byte_swapped = FALSE;
		modified = FALSE;
		wth->file_tsprec = WTAP_TSPREC_USEC;
		break;

	case PCAP_MODIFIED_MAGIC:
		/* Host that wrote it has our byte order, and was running
		   a program using either ss990915 or ss991029 libpcap. */
		byte_swapped = FALSE;
		modified = TRUE;
		wth->file_tsprec = WTAP_TSPREC_USEC;
		break;

	case PCAP_SWAPPED_MAGIC:
		/* Host that wrote it has a byte order opposite to ours,
		   and was running a program using either standard or
		   ss990417 libpcap. */
		byte_swapped = TRUE;
		modified = FALSE;
		wth->file_tsprec = WTAP_TSPREC_USEC;
		break;

	case PCAP_SWAPPED_MODIFIED_MAGIC:
		/* Host that wrote it out has a byte order opposite to
		   ours, and was running a program using either ss990915
		   or ss991029 libpcap. */
		byte_swapped = TRUE;
		modified = TRUE;
		wth->file_tsprec = WTAP_TSPREC_USEC;
		break;

	case PCAP_NSEC_MAGIC:
		/* Host that wrote it has our byte order, and was writing
		   the file in a format similar to standard libpcap
		   except that the time stamps have nanosecond resolution. */
		byte_swapped = FALSE;
		modified = FALSE;
		wth->file_tsprec = WTAP_TSPREC_NSEC;
		break;

	case PCAP_SWAPPED_NSEC_MAGIC:
		/* Host that wrote it out has a byte order opposite to
		   ours, and was writing the file in a format similar to
		   standard libpcap except that the time stamps have
		   nanosecond resolution. */
		byte_swapped = TRUE;
		modified = FALSE;
		wth->file_tsprec = WTAP_TSPREC_NSEC;
		break;

	default:
		/* Not a "libpcap" type we know about. */
		return WTAP_OPEN_NOT_MINE;
	}

	/* Read the rest of the header. */
	if (!wtap_read_bytes(wth->fh, &hdr, sizeof hdr, err, err_info))
		return WTAP_OPEN_ERROR;

	if (byte_swapped) {
		/* Byte-swap the header fields about which we care. */
		hdr.version_major = GUINT16_SWAP_LE_BE(hdr.version_major);
		hdr.version_minor = GUINT16_SWAP_LE_BE(hdr.version_minor);
		hdr.snaplen = GUINT32_SWAP_LE_BE(hdr.snaplen);
		hdr.network = GUINT32_SWAP_LE_BE(hdr.network);
	}
	if (hdr.version_major < 2) {
		/* We only support version 2.0 and later. */
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("pcap: major version %u unsupported",
		    hdr.version_major);
		return WTAP_OPEN_ERROR;
	}

	/*
	 * AIX's non-standard tcpdump uses a minor version number of 2.
	 * Unfortunately, older versions of libpcap might have used
	 * that as well.
	 *
	 * The AIX libpcap uses RFC 1573 ifType values rather than
	 * DLT_ values in the header; the ifType values for LAN devices
	 * are:
	 *
	 *	Ethernet	6
	 *	Token Ring	9
	 *	FDDI		15
	 *
	 * which correspond to DLT_IEEE802 (used for Token Ring),
	 * DLT_PPP, and DLT_SLIP_BSDOS, respectively.  The ifType value
	 * for a loopback interface is 24, which currently isn't
	 * used by any version of libpcap I know about (and, as
	 * tcpdump.org are assigning DLT_ values above 100, and
	 * NetBSD started assigning values starting at 50, and
	 * the values chosen by other libpcaps appear to stop at
	 * 19, it's probably not going to be used by any libpcap
	 * in the future).
	 *
	 * We shall assume that if the minor version number is 2, and
	 * the network type is 6, 9, 15, or 24, that it's AIX libpcap.
	 *
	 * I'm assuming those older versions of libpcap didn't
	 * use DLT_IEEE802 for Token Ring, and didn't use DLT_SLIP_BSDOS
	 * as that came later.  It may have used DLT_PPP, however, in
	 * which case we're out of luck; we assume it's Token Ring
	 * in AIX libpcap rather than PPP in standard libpcap, as
	 * you're probably more likely to be handing an AIX libpcap
	 * token-ring capture than an old (pre-libpcap 0.4) PPP capture
	 * to Wireshark.
	 */
	aix = FALSE;	/* assume it's not AIX */
	if (hdr.version_major == 2 && hdr.version_minor == 2) {
		switch (hdr.network) {

		case 6:
			hdr.network = 1;	/* DLT_EN10MB, Ethernet */
			aix = TRUE;
			break;

		case 9:
			hdr.network = 6;	/* DLT_IEEE802, Token Ring */
			aix = TRUE;
			break;

		case 15:
			hdr.network = 10;	/* DLT_FDDI, FDDI */
			aix = TRUE;
			break;

		case 24:
			hdr.network = 0;	/* DLT_NULL, loopback */
			aix = TRUE;
			break;
		}
	}

	file_encap = wtap_pcap_encap_to_wtap_encap(hdr.network);
	if (file_encap == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
		    hdr.network);
		return WTAP_OPEN_ERROR;
	}

	/* This is a libpcap file */
	libpcap = (libpcap_t *)g_malloc(sizeof(libpcap_t));
	libpcap->byte_swapped = byte_swapped;
	libpcap->version_major = hdr.version_major;
	libpcap->version_minor = hdr.version_minor;
	wth->priv = (void *)libpcap;
	wth->subtype_read = libpcap_read;
	wth->subtype_seek_read = libpcap_seek_read;
	wth->file_encap = file_encap;
	wth->snapshot_length = hdr.snaplen;

	/* In file format version 2.3, the order of the "incl_len" and
	   "orig_len" fields in the per-packet header was reversed,
	   in order to match the BPF header layout.

	   Therefore, in files with versions prior to that, we must swap
	   those two fields.

	   Unfortunately, some files were, according to a comment in the
	   "libpcap" source, written with version 2.3 in their headers
	   but without the interchanged fields, so if "incl_len" is
	   greater than "orig_len" - which would make no sense - we
	   assume that we need to swap them in version 2.3 files
	   as well.

	   In addition, DG/UX's tcpdump uses version 543.0, and writes
	   the two fields in the pre-2.3 order. */
	switch (hdr.version_major) {

	case 2:
		if (hdr.version_minor < 3)
			libpcap->lengths_swapped = SWAPPED;
		else if (hdr.version_minor == 3)
			libpcap->lengths_swapped = MAYBE_SWAPPED;
		else
			libpcap->lengths_swapped = NOT_SWAPPED;
		break;

	case 543:
		libpcap->lengths_swapped = SWAPPED;
		break;

	default:
		libpcap->lengths_swapped = NOT_SWAPPED;
		break;
	}

	/*
	 * Is this AIX format?
	 */
	if (aix) {
		/*
		 * Yes.  Skip all the tests for other mutant formats,
		 * and for the ERF link-layer header type, and set the
		 * precision to nanosecond precision.
		 */
		wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX;
		wth->file_tsprec = WTAP_TSPREC_NSEC;
		return WTAP_OPEN_MINE;
	}

	/*
	 * No.  Let's look at the header for the first record,
	 * and see if, interpreting it as a standard header (if the
	 * magic number was standard) or a modified header (if the
	 * magic number was modified), the position where it says the
	 * header for the *second* record is contains a corrupted header.
	 *
	 * If so, then:
	 *
	 *	If this file had the standard magic number, it may be
	 *	an ss990417 capture file - in that version of Alexey's
	 *	patch, the packet header format was changed but the
	 *	magic number wasn't, and, alas, Red Hat appear to have
	 *	picked up that version of the patch for RH 6.1, meaning
	 *	RH 6.1 has a tcpdump that writes out files that can't
	 *	be read by any software that expects non-modified headers
	 *	if the magic number isn't the modified magic number (e.g.,
	 *	any normal version of tcpdump, and Wireshark if we don't
	 *	do this gross heuristic).
	 *
	 *	If this file had the modified magic number, it may be
	 *	an ss990915 capture file - in that version of Alexey's
	 *	patch, the magic number was changed, but the record
	 *	header had some extra fields, and, alas, SuSE appear
	 *	to have picked up that version of the patch for SuSE
	 *	6.3, meaning that programs expecting the standard per-
	 *	packet header in captures with the modified magic number
	 *	can't read dumps from its tcpdump.
	 *
	 * Oh, and if it has the standard magic number, it might, instead,
	 * be a Nokia libpcap file, so we may need to try that if
	 * neither normal nor ss990417 headers work.
	 */
	if (modified) {
		/*
		 * Well, we have the magic number from Alexey's
		 * later two patches.  Try the subtypes for that.
		 */
		subtypes = subtypes_modified;
		n_subtypes = N_SUBTYPES_MODIFIED;
	} else {
		if (wth->file_tsprec == WTAP_TSPREC_NSEC) {
			/*
			 * We have nanosecond-format libpcap's magic
			 * number.  Try the subtypes for that.
			 */
			subtypes = subtypes_nsec;
			n_subtypes = N_SUBTYPES_NSEC;
		} else {
			/*
			 * We have the regular libpcap magic number.
			 * Try the subtypes for that.
			 */
			subtypes = subtypes_standard;
			n_subtypes = N_SUBTYPES_STANDARD;
		}
	}

	/*
	 * Try all the subtypes.
	 */
	first_packet_offset = file_tell(wth->fh);
	for (i = 0; i < n_subtypes; i++) {
		wth->file_type_subtype = subtypes[i];
		figures_of_merit[i] = libpcap_try(wth, err, err_info);
		if (figures_of_merit[i] == -1) {
			/*
			 * Well, we couldn't even read it.
			 * Give up.
			 */
			return WTAP_OPEN_ERROR;
		}
		if (figures_of_merit[i] == 0) {
			/*
			 * This format doesn't have any issues.
			 * Put the seek pointer back, and finish.
			 */
			if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
				return WTAP_OPEN_ERROR;
			}
			goto done;
		}

		/*
		 * OK, we've recorded the figure of merit for this one;
		 * go back to the first packet and try the next one.
		 */
		if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
			return WTAP_OPEN_ERROR;
		}
	}

	/*
	 * OK, none are perfect; let's see which one is least bad.
	 */
	best_subtype = INT_MAX;
	for (i = 0; i < n_subtypes; i++) {
		/*
		 * Is this subtype better than the last one we saw?
		 */
		if (figures_of_merit[i] < best_subtype) {
			/*
			 * Yes.  Choose it until we find a better one.
			 */
			wth->file_type_subtype = subtypes[i];
			best_subtype = figures_of_merit[i];
		}
	}

done:
	/*
	 * We treat a DLT_ value of 13 specially - it appears that in
	 * Nokia libpcap format, it's some form of ATM with what I
	 * suspect is a pseudo-header (even though Nokia's IPSO is
	 * based on FreeBSD, which #defines DLT_SLIP_BSDOS as 13).
	 *
	 * If this is a Nokia capture, treat 13 as WTAP_ENCAP_ATM_PDUS,
	 * rather than as what we normally treat it.
	 */
	if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA &&
	    hdr.network == 13)
		wth->file_encap = WTAP_ENCAP_ATM_PDUS;

	if (wth->file_encap == WTAP_ENCAP_ERF) {
		/*
		 * Populate set of interface IDs for ERF format.
		 * Currently, this *has* to be done at open time.
		 */
		erf_populate_interfaces(wth);
	}
	return WTAP_OPEN_MINE;
}
Ejemplo n.º 22
0
/*
 * Opens an .xml file with Trace data formated according to 3GPP TS 32.423 and converts it to
 * an "Exported PDU type file with the entire xml file as the first "packet" appending the
 * raw messages as subsequent packages to be dissected by wireshark.
 */
static wtap_open_return_val
create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_423_file_info_t *file_info)
{
	int import_file_fd;
	wtap_dumper* wdh_exp_pdu;
	int   exp_pdu_file_err;

	/* pcapng defs */
	wtapng_section_t            *shb_hdr;
	wtapng_iface_descriptions_t *idb_inf;
	wtapng_if_descr_t            int_data;
	GString                     *os_info_str;
	char                        *appname;
	gint64 file_size;
	int packet_size;
	guint8 *packet_buf;
	int wrt_err;
	gchar *wrt_err_info;
	struct wtap_pkthdr phdr;

	gboolean do_random = FALSE;
	char *curr_pos, *next_pos;

	import_file_fd = create_tempfile(&(file_info->tmpname), "Wireshark_PDU_");

	/* Now open a file and dump to it */
	/* Create data for SHB  */
	os_info_str = g_string_new("");
	get_os_version_info(os_info_str);

	appname = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());

	shb_hdr = g_new(wtapng_section_t, 1);
	shb_hdr->section_length = -1;
	/* options */
	shb_hdr->opt_comment = g_strdup_printf("File converted to Exported PDU format during opening");
	/*
	* UTF-8 string containing the description of the hardware used to create
	* this section.
	*/
	shb_hdr->shb_hardware = NULL;
	/*
	* UTF-8 string containing the name of the operating system used to create
	* this section.
	*/
	shb_hdr->shb_os = g_string_free(os_info_str, FALSE);
	/*
	* UTF-8 string containing the name of the application used to create
	* this section.
	*/
	shb_hdr->shb_user_appl = appname;

	/* Create fake IDB info */
	idb_inf = g_new(wtapng_iface_descriptions_t, 1);
	idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));

	/* create the fake interface data */
	int_data.wtap_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
	int_data.time_units_per_second = 1000000; /* default microsecond resolution */
	int_data.link_type = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
	int_data.snap_len = WTAP_MAX_PACKET_SIZE;
	int_data.if_name = g_strdup("Fake IF");
	int_data.opt_comment = NULL;
	int_data.if_description = NULL;
	int_data.if_speed = 0;
	int_data.if_tsresol = 6;
	int_data.if_filter_str = NULL;
	int_data.bpf_filter_len = 0;
	int_data.if_filter_bpf_bytes = NULL;
	int_data.if_os = NULL;
	int_data.if_fcslen = -1;
	int_data.num_stat_entries = 0;          /* Number of ISB:s */
	int_data.interface_statistics = NULL;

	g_array_append_val(idb_inf->interface_data, int_data);

	wdh_exp_pdu = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU,
					  WTAP_MAX_PACKET_SIZE, FALSE, shb_hdr, idb_inf, NULL, &exp_pdu_file_err);
	if (wdh_exp_pdu == NULL) {
		return WTAP_OPEN_ERROR;
	}

	g_free(shb_hdr);
	g_free(appname);

	/* OK we've opend a new pcap-ng file and written the headers, time to do the packets, strt by finding the file size */

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

	if (file_size > MAX_FILE_SIZE) {
		/*
		* Don't blow up trying to allocate space for an
		* immensely-large file.
		*/
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("mime_file: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
			file_size, MAX_FILE_SIZE);
		return WTAP_OPEN_ERROR;
	}
	packet_size = (int)file_size;
	/* Allocate the packet buffer
	* (the whole file + Exported PDU tag "protocol" and
	* the string "xml" + 1 filler to end on 4 byte boundary for the tag
	* + End of options 4 bytes
	*/
	/* XXX add the length of exported bdu tag(s) here */
	packet_buf = (guint8 *)g_malloc(packet_size + 12);

	packet_buf[0] = 0;
	packet_buf[1] = 12; /* EXP_PDU_TAG_PROTO_NAME */
	packet_buf[2] = 0;
	packet_buf[3] = 4;
	packet_buf[4] = 0x78; /* "x" */
	packet_buf[5] = 0x6d; /* "m" */
	packet_buf[6] = 0x6c; /* "l" */
	packet_buf[7] = 0;
	/* End of options */
	packet_buf[8] = 0;
	packet_buf[9] = 0;
	packet_buf[10] = 0;
	packet_buf[11] = 0;


	if (!wtap_read_bytes(wth->fh, packet_buf + 12, packet_size, &wrt_err, &wrt_err_info)){
		return WTAP_OPEN_ERROR;
	}

	/* Create the packet header */
	memset(&phdr, 0, sizeof(struct wtap_pkthdr));
	phdr.rec_type = REC_TYPE_PACKET;
	phdr.presence_flags = 0; /* yes, we have no bananas^Wtime stamp */

	phdr.caplen = packet_size + 12;
	phdr.len = packet_size + 12;

	phdr.ts.secs = 0;
	phdr.ts.nsecs = 0;

	/* XXX: report errors! */
	if (!wtap_dump(wdh_exp_pdu, &phdr, packet_buf, &wrt_err, &wrt_err_info)) {
		switch (wrt_err) {

		case WTAP_ERR_UNWRITABLE_REC_DATA:
			g_free(wrt_err_info);
			break;

		default:
			break;
		}
		g_free(packet_buf);
		return WTAP_OPEN_ERROR;
	}

	/* Advance *packet_buf to point at the raw file data */
	curr_pos = packet_buf + 12;
	/* Lets add the raw messages as packets after the main "packet" with the whole file */
	while ((curr_pos = strstr(curr_pos, "<msg")) != NULL){
		wtap_open_return_val temp_val;

		curr_pos = curr_pos + 4;
		next_pos = strstr(curr_pos, "</msg>");
		if (!next_pos){
			/* Somethings wrong, bail out */
			break;
		}
		next_pos = next_pos + 6;
		/* Do we have a raw msg?) */
		curr_pos = strstr(curr_pos, "<rawMsg");
		if (!curr_pos){
			/* No rawMsg, continue */
			curr_pos = next_pos;
			continue;
		}
		curr_pos = curr_pos + 7;
		/* Add the raw msg*/
		temp_val = write_packet_data(wdh_exp_pdu, &phdr, &wrt_err, &wrt_err_info, curr_pos);
		if (temp_val != WTAP_OPEN_MINE){
			g_free(packet_buf);
			return temp_val;
		}
		curr_pos = next_pos;
	}

	/* Close the written file*/
	if (!wtap_dump_close(wdh_exp_pdu, err)){
		g_free(packet_buf);
		return WTAP_OPEN_ERROR;
	}

	g_free(packet_buf);
	/* Now open the file for reading */

	/* Find out if random read was requested */
	if (wth->random_fh){
		do_random = TRUE;
	}
	file_info->wth_tmp_file =
		wtap_open_offline(file_info->tmpname, WTAP_TYPE_AUTO, err, err_info, do_random);

	if (!file_info->wth_tmp_file){
		return WTAP_OPEN_ERROR;
	}

	return WTAP_OPEN_MINE;
}
Ejemplo n.º 23
0
/*
 * XXX - it would probably be cleaner to use a UCS-2 flavor of file_gets(),
 * rather than file_gets(), if we're reading a UCS-2 file.
 */
wtap_open_return_val
iseries_open (wtap * wth, int *err, gchar ** err_info)
{
  gint offset;
  char magic[ISERIES_LINE_LENGTH];

  /*
   * Check that file starts with a valid iSeries COMMS TRACE header
   * by scanning for it in the first line
   */
  if (!wtap_read_bytes (wth->fh, &magic, sizeof magic, err, err_info))
    {
      if (*err != WTAP_ERR_SHORT_READ)
        return WTAP_OPEN_ERROR;
      return WTAP_OPEN_NOT_MINE;
    }

  /*
   * Check if this is a little-endian UCS-2 Unicode formatted file by scanning
   * for the magic string
   */
  offset=0;
  while ((unsigned int)offset < (ISERIES_LINE_LENGTH - (sizeof iseries_hdr_magic_le_ucs_2)))
    {
      if (memcmp (magic + offset, iseries_hdr_magic_le_ucs_2, sizeof iseries_hdr_magic_le_ucs_2) == 0) {
        if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
          {
            return WTAP_OPEN_ERROR;
          }
        /*
         * Do some basic sanity checking to ensure we can handle the
         * contents of this trace
         */
        if (!iseries_check_file_type (wth, err, err_info, ISERIES_FORMAT_UNICODE))
          {
            if (*err == 0)
              return WTAP_OPEN_NOT_MINE;
            else
              return WTAP_OPEN_ERROR;
          }

        wth->file_encap        = WTAP_ENCAP_ETHERNET;
        wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_ISERIES;
        wth->snapshot_length   = 0;
        wth->subtype_read      = iseries_read;
        wth->subtype_seek_read = iseries_seek_read;
        wth->file_tsprec       = WTAP_TSPREC_USEC;

        if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
          {
            return WTAP_OPEN_ERROR;
          }
        return WTAP_OPEN_MINE;
      }
      offset += 1;
    }

    /*
     * Check if this is a ASCII formatted file by scanning for the magic string
     */
    offset=0;
    while ((unsigned int)offset < (ISERIES_LINE_LENGTH - sizeof iseries_hdr_magic_ascii))
      {
        if (memcmp (magic + offset, iseries_hdr_magic_ascii, sizeof iseries_hdr_magic_ascii) == 0)
          {
            if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
              {
                return WTAP_OPEN_ERROR;
              }
            /*
             * Do some basic sanity checking to ensure we can handle the
             * contents of this trace
             */
            if (!iseries_check_file_type (wth, err, err_info, ISERIES_FORMAT_ASCII))
              {
                if (*err == 0)
                  return WTAP_OPEN_NOT_MINE;
                else
                  return WTAP_OPEN_ERROR;
              }

            wth->file_encap        = WTAP_ENCAP_ETHERNET;
            wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_ISERIES;
            wth->snapshot_length   = 0;
            wth->subtype_read      = iseries_read;
            wth->subtype_seek_read = iseries_seek_read;
            wth->file_tsprec       = WTAP_TSPREC_USEC;

            if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
              {
                return WTAP_OPEN_ERROR;
              }
            return WTAP_OPEN_MINE;
          }
        offset += 1;
      }

    /* Neither ASCII or UNICODE so not supported */
    return WTAP_OPEN_NOT_MINE;
    }
Ejemplo n.º 24
0
wtap_open_return_val
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.
	*/

	if (!wtap_read_bytes(wth->fh, buffer, sizeof(buffer),
	    err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	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 WTAP_OPEN_NOT_MINE;
	}

  my_file_type:

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

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

	init_state(state);

	state->offset = 5;
	wth->file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_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->file_tsprec = WTAP_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 WTAP_OPEN_MINE;
}
Ejemplo n.º 25
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:
				if (!wtap_read_bytes(fh, &time_long, sizeof(guint32), err, err_info))
					return FALSE;
				state->offset += sizeof(guint32);
				state->timestamp = pntoh32(&time_long);
				state->tenths = 0;
				break;

			case PPPD_TIME_STEP_LONG:
				if (!wtap_read_bytes(fh, &time_long, sizeof(guint32), err, err_info))
					return FALSE;
				state->offset += sizeof(guint32);
				state->tenths += pntoh32(&time_long);

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

				break;

			case PPPD_TIME_STEP_SHORT:
				if (!wtap_read_bytes(fh, &time_short, sizeof(guint8), err, err_info))
					return FALSE;
				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;
}
Ejemplo n.º 26
0
wtap_open_return_val k12_open(wtap *wth, int *err, gchar **err_info) {
    k12_src_desc_t* rec;
    guint8 header_buffer[K12_FILE_HDR_LEN];
    guint8* read_buffer;
    guint32 type;
    long offset;
    long len;
    guint port_type;
    guint32 rec_len;
    guint32 hwpart_len;
    guint32 name_len;
    guint32 stack_len;
    guint i;
    k12_t* file_data;

#ifdef DEBUG_K12
    gchar* env_level = getenv("K12_DEBUG_LEVEL");
    env_file = getenv("K12_DEBUG_FILENAME");
    if ( env_file ) {
        dbg_out = ws_fopen(env_file,"w");
        if (dbg_out == NULL) {
                dbg_out = stderr;
                K12_DBG(1,("unable to open K12 DEBUG FILENAME for writing!  Logging to standard error"));
        }
    }
    else
        dbg_out = stderr;
    if ( env_level ) debug_level = (unsigned int)strtoul(env_level,NULL,10);
    K12_DBG(1,("k12_open: ENTER debug_level=%u",debug_level));
#endif

    if ( !wtap_read_bytes(wth->fh,header_buffer,K12_FILE_HDR_LEN,err,err_info) ) {
        K12_DBG(1,("k12_open: FILE HEADER TOO SHORT OR READ ERROR"));
        if (*err != WTAP_ERR_SHORT_READ) {
            return WTAP_OPEN_ERROR;
        }
        return WTAP_OPEN_NOT_MINE;
    }

    if ( memcmp(header_buffer,k12_file_magic,8) != 0 ) {
        K12_DBG(1,("k12_open: BAD MAGIC"));
        return WTAP_OPEN_NOT_MINE;
    }

    offset = K12_FILE_HDR_LEN;

    file_data = new_k12_file_data();

    file_data->file_len = pntoh32( header_buffer + 0x8);
    if (memiszero(header_buffer + 0x10, K12_FILE_HDR_LEN - 0x10)) {
        /*
         * The rest of the file header is all zeroes.  That means
         * this is a file written by the old Wireshark code, and
         * a count of records in the file is at an offset of 0x0C.
         */
        file_data->num_of_records = pntoh32( header_buffer + 0x0C );
    } else {
        /*
         * There's at least one non-zero byte in the rest of the
         * header.  The value 8192 is at 0xC (page size?), and
         * what appears to be the number of records in the file
         * is at an offset of 0x24 and at an offset of 0x2c.
         *
         * If the two values are not the same, we fail; if that's
         * the case, we need to see the file to figure out which
         * of those two values, if any, is the count.
         */
        file_data->num_of_records = pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_1 );
        if ( file_data->num_of_records != pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_2 ) ) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("k12: two different record counts, %u at 0x%02x and %u at 0x%02x",
                                        file_data->num_of_records,
                                        K12_FILE_HDR_RECORD_COUNT_1,
                                        pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_2 ),
                                        K12_FILE_HDR_RECORD_COUNT_2 );
            return WTAP_OPEN_ERROR;
        }
    }

    K12_DBG(5,("k12_open: FILE_HEADER OK: offset=%x file_len=%i records=%i",
            offset,
            file_data->file_len,
            file_data->num_of_records ));

    do {
        if ( file_data->num_of_records == 0 ) {
            *err = WTAP_ERR_SHORT_READ;
            destroy_k12_file_data(file_data);
            return WTAP_OPEN_ERROR;
        }

        len = get_record(file_data, wth->fh, offset, FALSE, err, err_info);

        if ( len < 0 ) {
            K12_DBG(1,("k12_open: BAD HEADER RECORD",len));
            destroy_k12_file_data(file_data);
            return WTAP_OPEN_ERROR;
        }
        if ( len == 0 ) {
            K12_DBG(1,("k12_open: BAD HEADER RECORD",len));
            *err = WTAP_ERR_SHORT_READ;
            destroy_k12_file_data(file_data);
            return WTAP_OPEN_ERROR;
        }

        read_buffer = file_data->seq_read_buff;

        rec_len = pntoh32( read_buffer + K12_RECORD_LEN );
        if (rec_len < K12_RECORD_TYPE + 4) {
            /* Record isn't long enough to have a type field */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("k12_open: record length %u < %u",
                                        rec_len, K12_RECORD_TYPE + 4);
            return WTAP_OPEN_ERROR;
        }
        type = pntoh32( read_buffer + K12_RECORD_TYPE );

        if ( (type & K12_MASK_PACKET) == K12_REC_PACKET ||
             (type & K12_MASK_PACKET) == K12_REC_D0020) {
            /*
             * we are at the first packet record, rewind and leave.
             */
            if (file_seek(wth->fh, offset, SEEK_SET, err) == -1) {
                destroy_k12_file_data(file_data);
                return WTAP_OPEN_ERROR;
            }
            K12_DBG(5,("k12_open: FIRST PACKET offset=%x",offset));
            break;
        }

        switch (type) {

        case K12_REC_SRCDSC:
        case K12_REC_SRCDSC2:
            rec = g_new0(k12_src_desc_t,1);

            if (rec_len < K12_SRCDESC_HWPART) {
                /*
                 * Record isn't long enough to have the fixed-length portion
                 * of the source descriptor field.
                 */
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u",
                                            rec_len, K12_SRCDESC_HWPART);
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }
            port_type = read_buffer[K12_SRCDESC_PORT_TYPE];
            hwpart_len = pntoh16( read_buffer + K12_SRCDESC_HWPARTLEN );
            name_len = pntoh16( read_buffer + K12_SRCDESC_NAMELEN );
            stack_len = pntoh16( read_buffer + K12_SRCDESC_STACKLEN );

            rec->input = pntoh32( read_buffer + K12_RECORD_SRC_ID );

            K12_DBG(5,("k12_open: INTERFACE RECORD offset=%x interface=%x",offset,rec->input));

            if (name_len == 0) {
                K12_DBG(5,("k12_open: failed (name_len == 0 in source description"));
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_NOT_MINE;
            }
            if (stack_len == 0) {
                K12_DBG(5,("k12_open: failed (stack_len == 0 in source description"));
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_NOT_MINE;
            }
            if (rec_len < K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len) {
                /*
                 * Record isn't long enough to have the full source descriptor
                 * field, including the variable-length parts.
                 */
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u (%u + %u + %u + %u)",
                                            rec_len,
                                            K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len,
                                            K12_SRCDESC_HWPART, hwpart_len, name_len, stack_len);
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }

            if (hwpart_len) {
                if (hwpart_len < 4) {
                    /* Hardware part isn't long enough to have a type field */
                    *err = WTAP_ERR_BAD_FILE;
                    *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < 4",
                                                hwpart_len);
                    destroy_k12_file_data(file_data);
                    g_free(rec);
                    return WTAP_OPEN_ERROR;
                }
                switch(( rec->input_type = pntoh32( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_HWPARTTYPE ) )) {
                    case K12_PORT_DS0S:
                        /* This appears to be variable-length */
                        rec->input_info.ds0mask = 0x00000000;
                        if (hwpart_len > K12_SRCDESC_DS0_MASK) {
                            for (i = 0; i < hwpart_len - K12_SRCDESC_DS0_MASK; i++) {
                                rec->input_info.ds0mask |= ( *(read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_DS0_MASK + i) == 0xff ) ? 1U<<(31-i) : 0x0;
                            }
                        }
                        break;
                    case K12_PORT_ATMPVC:
                        if (hwpart_len < K12_SRCDESC_ATM_VCI + 2) {
                            /* Hardware part isn't long enough to have ATM information */
                            *err = WTAP_ERR_BAD_FILE;
                            *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < %u",
                                                        hwpart_len,
                                                        K12_SRCDESC_ATM_VCI + 2);
                            destroy_k12_file_data(file_data);
                            g_free(rec);
                            return WTAP_OPEN_ERROR;
                        }

                        rec->input_info.atm.vp = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VPI );
                        rec->input_info.atm.vc = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VCI );
                        break;
                    default:
                        break;
                }
            } else {
                /* Record viewer generated files don't have this information */
                if (port_type >= 0x14
                    && port_type <= 0x17) {
                    /* For ATM2_E1DS1, ATM2_E3DS3,
                       ATM2_STM1EL and ATM2_STM1OP */
                    rec->input_type = K12_PORT_ATMPVC;
                    rec->input_info.atm.vp = 0;
                    rec->input_info.atm.vc = 0;
                }
            }

            if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len - 1] != '\0') {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated link-layer name");
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }
            if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len - 1] != '\0') {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated stack path");
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }
            rec->input_name = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len, name_len);
            rec->stack_file = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len + name_len, stack_len);

            ascii_strdown_inplace (rec->stack_file);

            g_hash_table_insert(file_data->src_by_id,GUINT_TO_POINTER(rec->input),rec);
            g_hash_table_insert(file_data->src_by_name,rec->stack_file,rec);
            break;

        case K12_REC_STK_FILE:
            K12_DBG(1,("k12_open: K12_REC_STK_FILE"));
            K12_DBG(1,("Field 1: 0x%08x",pntoh32( read_buffer + 0x08 )));
            K12_DBG(1,("Field 2: 0x%08x",pntoh32( read_buffer + 0x0c )));
            K12_ASCII_DUMP(1, read_buffer, rec_len, 16);
            break;

        default:
            K12_DBG(1,("k12_open: RECORD TYPE 0x%08x",type));
            break;
        }
        offset += len;
        file_data->num_of_records--;
    } while(1);

    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_K12;
    wth->file_encap = WTAP_ENCAP_K12;
    wth->snapshot_length = 0;
    wth->subtype_read = k12_read;
    wth->subtype_seek_read = k12_seek_read;
    wth->subtype_close = k12_close;
    wth->priv = (void *)file_data;
    wth->file_tsprec = WTAP_TSPREC_NSEC;

    return WTAP_OPEN_MINE;
}
Ejemplo n.º 27
0
/*
 * get_record: Get the next record into a buffer
 *   Every 8192 bytes 16 bytes are inserted in the file,
 *   even in the middle of a record.
 *   This reads the next record without the eventual 16 bytes.
 *   returns the length of the record + the stuffing (if any)
 *
 *   Returns number of bytes read on success, 0 on EOF, -1 on error;
 *   if -1 is returned, *err is set to the error indication and, for
 *   errors where that's appropriate, *err_info is set to an additional
 *   error string.
 *
 * XXX: works at most with 8191 bytes per record
 */
static gint get_record(k12_t *file_data, FILE_T fh, gint64 file_offset,
                       gboolean is_random, int *err, gchar **err_info) {
    guint8 *buffer = is_random ? file_data->rand_read_buff : file_data->seq_read_buff;
    guint buffer_len = is_random ? file_data->rand_read_buff_len : file_data->seq_read_buff_len;
    guint total_read = 0;
    guint left;
    guint8* writep;
#ifdef DEBUG_K12
    guint actual_len;
#endif

    /*
     * Where the next unknown 16 bytes are stuffed to the file.
     * Following the file header, they appear every 8192 bytes,
     * starting right after the file header, so if the file offset
     * relative to the file header is a multiple of 8192, the
     * 16-byte blob is there.
     */
    guint junky_offset = 8192 - (gint) ( (file_offset - K12_FILE_HDR_LEN) % 8192 );

    K12_DBG(6,("get_record: ENTER: junky_offset=%" G_GINT64_MODIFIER "d, file_offset=%" G_GINT64_MODIFIER "d",junky_offset,file_offset));

    /* no buffer is given, lets create it */
    if (buffer == NULL) {
        buffer = (guint8*)g_malloc(8192);
        buffer_len = 8192;
        if (is_random) {
            file_data->rand_read_buff = buffer;
            file_data->rand_read_buff_len = buffer_len;
        } else {
            file_data->seq_read_buff = buffer;
            file_data->seq_read_buff_len = buffer_len;
        }
    }

    if ( junky_offset == 8192 ) {
        /*
         * We're at the beginning of one of the 16-byte blobs,
         * so we first need to skip the blob.
         *
         * XXX - what if the blob is in the middle of the record
         * length?  If the record length is always a multiple of
         * 4 bytes, that won't happen.
         */
        if ( ! wtap_read_bytes( fh, NULL, K12_FILE_BLOB_LEN, err, err_info ) )
            return -1;
        total_read += K12_FILE_BLOB_LEN;
    }

    /*
     * Read the record length.
     */
    if ( !wtap_read_bytes( fh, buffer, 4, err, err_info ) )
        return -1;
    total_read += 4;

    left = pntoh32(buffer + K12_RECORD_LEN);
#ifdef DEBUG_K12
    actual_len = left;
#endif
    junky_offset -= 4;

    K12_DBG(5,("get_record: GET length=%u",left));

    /*
     * Record length must be at least large enough for the length
     * and type, hence 8 bytes.
     *
     * XXX - is WTAP_MAX_PACKET_SIZE_STANDARD the right check for a maximum
     * record size?  Should we report this error differently?
     */
    if (left < 8) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("k12: Record length %u is less than 8 bytes long",left);
        return -1;
    }
    if (left > WTAP_MAX_PACKET_SIZE_STANDARD) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("k12: Record length %u is greater than the maximum %u",left,WTAP_MAX_PACKET_SIZE_STANDARD);
        return -1;
    }

    /*
     * XXX - calculate the lowest power of 2 >= left, rather than just
     * looping.
     */
    while (left > buffer_len) {
        buffer = (guint8*)g_realloc(buffer,buffer_len*=2);
        if (is_random) {
            file_data->rand_read_buff = buffer;
            file_data->rand_read_buff_len = buffer_len;
        } else {
            file_data->seq_read_buff = buffer;
            file_data->seq_read_buff_len = buffer_len;
        }
    }

    writep = buffer + 4;
    left -= 4;

    /* Read the rest of the record. */
    do {
        K12_DBG(6,("get_record: looping left=%d junky_offset=%" G_GINT64_MODIFIER "d",left,junky_offset));

        if (junky_offset > left) {
            /*
             * The next 16-byte blob is past the end of this record.
             * Just read the rest of the record.
             */
            if ( !wtap_read_bytes( fh, writep, left, err, err_info ) )
                return -1;
            total_read += left;
            break;
        } else {
            /*
             * The next 16-byte blob is part of this record.
             * Read up to the blob.
             */
            if ( !wtap_read_bytes( fh, writep, junky_offset, err, err_info ) )
                return -1;

            total_read += junky_offset;
            writep += junky_offset;

            /*
             * Skip the blob.
             */
            if ( !wtap_read_bytes( fh, NULL, K12_FILE_BLOB_LEN, err, err_info ) )
                return -1;
            total_read += K12_FILE_BLOB_LEN;

            left -= junky_offset;
            junky_offset = 8192;
        }

    } while(left);

    K12_HEX_ASCII_DUMP(5,file_offset, "GOT record", buffer, actual_len);
    return total_read;
}
Ejemplo n.º 28
0
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
                               Buffer *buf, int *err, gchar **err_info)
{
  stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv;
  guint32 millisecs, secs, nsecs;
  gint64 offset = 0;
  guint8 stanag_pkt_hdr[PKT_HDR_SIZE+SEG_HDR_SIZE];
  guint32 packet_size;

  *err = 0;

  /* Combined packet header and segment header */
  if (!wtap_read_bytes_or_eof(fh, stanag_pkt_hdr, sizeof stanag_pkt_hdr, err, err_info))
    return FALSE;
  offset += sizeof stanag_pkt_hdr;

  if (!is_valid_id(pntoh16(&stanag_pkt_hdr[0]))) {
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup("Bad version number");
    return FALSE;
  }

  rec->rec_type = REC_TYPE_PACKET;

  /* The next 4 bytes are the packet length */
  packet_size = pntoh32(&stanag_pkt_hdr[2]);
  if (packet_size > WTAP_MAX_PACKET_SIZE_STANDARD) {
    /*
     * 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("stanag4607: File has %" G_GUINT32_FORMAT "d-byte packet, "
      "bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE_STANDARD);
    return FALSE;
  }
  if (packet_size < PKT_HDR_SIZE+SEG_HDR_SIZE) {
    /*
     * Probably a corrupt capture file; don't, for example, loop
     * infinitely if the size is zero.
     */
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup_printf("stanag4607: File has %" G_GUINT32_FORMAT "d-byte packet, "
      "smaller than minimum of %u", packet_size, PKT_HDR_SIZE+SEG_HDR_SIZE);
    return FALSE;
  }
  rec->rec_header.packet_header.caplen = packet_size;
  rec->rec_header.packet_header.len = packet_size;

  /* Sadly, the header doesn't contain times; but some segments do */
  /* So, get the segment header, which is just past the 32-byte header. */
  rec->presence_flags = WTAP_HAS_TS;

  /* If no time specified, it's the last baseline time */
  rec->ts.secs = stanag4607->base_secs;
  rec->ts.nsecs = 0;
  millisecs = 0;

#define MISSION_SEGMENT 1
#define DWELL_SEGMENT 2
#define JOB_DEFINITION_SEGMENT 5
#define PLATFORM_LOCATION_SEGMENT 13
  if (MISSION_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 mseg[39];
    struct tm tm;

    if (!wtap_read_bytes(fh, &mseg, sizeof mseg, err, err_info))
      return FALSE;
    offset += sizeof mseg;

    tm.tm_year = pntoh16(&mseg[35]) - 1900;
    tm.tm_mon = mseg[37] - 1;
    tm.tm_mday = mseg[38];
    tm.tm_hour = 0;
    tm.tm_min = 0;
    tm.tm_sec = 0;
    tm.tm_isdst = -1;
    stanag4607->base_secs = mktime(&tm);
    rec->ts.secs = stanag4607->base_secs;
  }
  else if (PLATFORM_LOCATION_SEGMENT == stanag_pkt_hdr[32]) {
    if (!wtap_read_bytes(fh, &millisecs, sizeof millisecs, err, err_info))
      return FALSE;
    offset += sizeof millisecs;
    millisecs = g_ntohl(millisecs);
  }
  else if (DWELL_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 dseg[19];
    if (!wtap_read_bytes(fh, &dseg, sizeof dseg, err, err_info))
      return FALSE;
    offset += sizeof dseg;
    millisecs = pntoh32(&dseg[15]);
  }
  if (0 != millisecs) {
    secs = millisecs/1000;
    nsecs = (millisecs - 1000 * secs) * 1000000;
    rec->ts.secs = stanag4607->base_secs + secs;
    rec->ts.nsecs = nsecs;
  }

  /* wind back to the start of the packet ... */
  if (file_seek(fh, - offset, SEEK_CUR, err) == -1)
    return FALSE;

  return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
}
Ejemplo n.º 29
0
wtap_open_return_val peektagged_open(wtap *wth, int *err, gchar **err_info)
{
    peektagged_section_header_t ap_hdr;
    int ret;
    guint32 fileVersion = 0;
    guint32 mediaType;
    guint32 mediaSubType = 0;
    int file_encap;
    static const int peektagged_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_PEEKTAGGED_ENCAPS (sizeof peektagged_encap / sizeof peektagged_encap[0])
    peektagged_t *peektagged;

    if (!wtap_read_bytes(wth->fh, &ap_hdr, (int)sizeof(ap_hdr), err, err_info)) {
        if (*err != WTAP_ERR_SHORT_READ)
            return WTAP_OPEN_ERROR;
        return WTAP_OPEN_NOT_MINE;
    }

    if (memcmp (ap_hdr.section_id, "\177ver", sizeof(ap_hdr.section_id)) != 0)
        return WTAP_OPEN_NOT_MINE;      /* 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, err_info);
    if (ret == -1)
        return WTAP_OPEN_ERROR;
    if (ret == 0) {
        /* 0 means EOF, which means "not a valid Peek tagged file" */
        return WTAP_OPEN_NOT_MINE;
    }
    ret = wtap_file_read_number (wth, &fileVersion, err, err_info);
    if (ret == -1)
        return WTAP_OPEN_ERROR;
    if (ret == 0) {
        /* 0 means EOF, which means "not a valid Peek tagged file" */
        return WTAP_OPEN_NOT_MINE;
    }

    /* If we got this far, we assume it's a Peek tagged file. */
    if (fileVersion != 9) {
        /* We only support version 9. */
        *err = WTAP_ERR_UNSUPPORTED;
        *err_info = g_strdup_printf("peektagged: version %u unsupported",
            fileVersion);
        return WTAP_OPEN_ERROR;
    }

    /*
     * 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, err_info);
    if (ret == -1)
        return WTAP_OPEN_ERROR;
    if (ret == 0) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("peektagged: <MediaType> tag not found");
        return WTAP_OPEN_ERROR;
    }
    /* 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, err_info);
    if (ret == -1)
        return WTAP_OPEN_ERROR;
    if (ret == 0) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("peektagged: <MediaType> value not found");
        return WTAP_OPEN_ERROR;
    }

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

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

    /* skip 8 zero bytes */
    if (!wtap_read_bytes (wth->fh, NULL, 8, err, err_info)) {
        return WTAP_OPEN_ERROR;
    }

    /*
     * This is an Peek tagged file.
     */
    file_encap = peektagged_encap[mediaSubType];

    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED;
    wth->file_encap = file_encap;
    wth->subtype_read = peektagged_read;
    wth->subtype_seek_read = peektagged_seek_read;
    wth->file_tsprec = WTAP_TSPREC_NSEC;

    peektagged = (peektagged_t *)g_malloc(sizeof(peektagged_t));
    wth->priv = (void *)peektagged;
    switch (mediaSubType) {

    case PEEKTAGGED_NST_ETHERNET:
    case PEEKTAGGED_NST_802_11:
    case PEEKTAGGED_NST_802_11_2:
        peektagged->has_fcs = FALSE;
        break;

    case PEEKTAGGED_NST_802_11_WITH_FCS:
        peektagged->has_fcs = TRUE;
        break;
    }

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

    return WTAP_OPEN_MINE;
}
Ejemplo n.º 30
0
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
                               Buffer *buf, int *err, gchar **err_info)
{
  stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv;
  guint32 millisecs, secs, nsecs;
  gint64 offset = 0;
  guint8 stanag_pkt_hdr[37];
  guint32 packet_size;

  *err = 0;

  /* Combined packet header and segment header */
  if (!wtap_read_bytes_or_eof(fh, stanag_pkt_hdr, sizeof stanag_pkt_hdr, err, err_info))
    return FALSE;
  offset += sizeof stanag_pkt_hdr;

  if (!is_valid_id(pntoh16(&stanag_pkt_hdr[0]))) {
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup("Bad version number");
    return FALSE;
  }

  phdr->rec_type = REC_TYPE_PACKET;

  /* The next 4 bytes are the packet length */
  packet_size = pntoh32(&stanag_pkt_hdr[2]);
  phdr->caplen = packet_size;
  phdr->len = packet_size;

  /* Sadly, the header doesn't contain times; but some segments do */
  /* So, get the segment header, which is just past the 32-byte header. */
  phdr->presence_flags = WTAP_HAS_TS;

  /* If no time specified, it's the last baseline time */
  phdr->ts.secs = stanag4607->base_secs;
  phdr->ts.nsecs = 0;
  millisecs = 0;

#define MISSION_SEGMENT 1
#define DWELL_SEGMENT 2
#define JOB_DEFINITION_SEGMENT 5
#define PLATFORM_LOCATION_SEGMENT 13
  if (MISSION_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 mseg[39];
    struct tm tm;

    if (!wtap_read_bytes(fh, &mseg, sizeof mseg, err, err_info))
      return FALSE;
    offset += sizeof mseg;

    tm.tm_year = pntoh16(&mseg[35]) - 1900;
    tm.tm_mon = mseg[37] - 1;
    tm.tm_mday = mseg[38];
    tm.tm_hour = 0;
    tm.tm_min = 0;
    tm.tm_sec = 0;
    tm.tm_isdst = -1;
    stanag4607->base_secs = mktime(&tm);
    phdr->ts.secs = stanag4607->base_secs;
  }
  else if (PLATFORM_LOCATION_SEGMENT == stanag_pkt_hdr[32]) {
    if (!wtap_read_bytes(fh, &millisecs, sizeof millisecs, err, err_info))
      return FALSE;
    offset += sizeof millisecs;
    millisecs = g_ntohl(millisecs);
  }
  else if (DWELL_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 dseg[19];
    if (!wtap_read_bytes(fh, &dseg, sizeof dseg, err, err_info))
      return FALSE;
    offset += sizeof dseg;
    millisecs = pntoh32(&dseg[15]);
  }
  if (0 != millisecs) {
    secs = millisecs/1000;
    nsecs = (millisecs - 1000 * secs) * 1000000;
    phdr->ts.secs = stanag4607->base_secs + secs;
    phdr->ts.nsecs = nsecs;
  }

  /* wind back to the start of the packet ... */
  if (file_seek(fh, - offset, SEEK_CUR, err) == -1)
    return FALSE;

  return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
}