Example #1
0
void
capture_pktap(const guchar *pd, int len, packet_counts *ld)
{
	guint32  hdrlen, rectype, dlt;

	hdrlen = pletoh32(pd);
	if (hdrlen < MIN_PKTAP_HDR_LEN || !BYTES_ARE_IN_FRAME(0, len, hdrlen)) {
		ld->other++;
		return;
	}

	rectype = pletoh32(pd+4);
	if (rectype != PKT_REC_PACKET) {
		ld->other++;
		return;
	}

	dlt = pletoh32(pd+4);

	/* XXX - We should probably combine this with capture_info.c:capture_info_packet() */
	switch (dlt) {

	case 1: /* DLT_EN10MB */
		capture_eth(pd, hdrlen, len, ld);
		return;

	default:
		break;
	}

	ld->other++;
}
Example #2
0
static gboolean logcat_read_packet(struct logcat_phdr *logcat, FILE_T fh,
    struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
    gint                 bytes_read;
    gint                 packet_size;
    guint16              payload_length;
    guint                tmp[2];
    guint8              *pd;

    bytes_read = file_read(&tmp, 2, fh);
    if (bytes_read != 2) {
        *err = file_error(fh, err_info);
        if (*err == 0 && bytes_read != 0)
            *err = WTAP_ERR_SHORT_READ;
        return FALSE;
    }
    payload_length = pletoh16(tmp);

    if (logcat->version == 1) {
        packet_size = 5 * 4 + payload_length;
    } else if (logcat->version == 2) {
        packet_size = 6 * 4 + payload_length;
    } else {
        return FALSE;
    }

    buffer_assure_space(buf, packet_size);
    pd = buffer_start_ptr(buf);

    /* Copy the first two bytes of the packet. */
    memcpy(pd, tmp, 2);

    /* Read the rest of the packet. */
    bytes_read = file_read(pd + 2, packet_size - 2, fh);
    if (bytes_read != packet_size - 2) {
        *err = file_error(fh, err_info);
        if (*err == 0)
            *err = WTAP_ERR_SHORT_READ;
        return FALSE;
    }

    phdr->rec_type = REC_TYPE_PACKET;
    phdr->presence_flags = WTAP_HAS_TS;
    phdr->ts.secs = (time_t) pletoh32(pd + 12);
    phdr->ts.nsecs = (int) pletoh32(pd + 16);
    phdr->caplen = packet_size;
    phdr->len = packet_size;

    phdr->pseudo_header.logcat.version = logcat->version;

    return TRUE;
}
Example #3
0
/* Read the header of the next packet.  Return TRUE on success, FALSE
   on error. */
static gboolean
_5views_read_header(wtap *wth, FILE_T fh, t_5VW_TimeStamped_Header *hdr,
    struct wtap_pkthdr *phdr, int *err, gchar **err_info)
{
	int	bytes_read, bytes_to_read;

	bytes_to_read = sizeof(t_5VW_TimeStamped_Header);

	/* Read record header. */
	bytes_read = file_read(hdr, bytes_to_read, fh);
	if (bytes_read != bytes_to_read) {
		*err = file_error(fh, err_info);
		if (*err == 0 && bytes_read != 0) {
			*err = WTAP_ERR_SHORT_READ;
		}
		return FALSE;
	}

	hdr->Key = pletoh32(&hdr->Key);
	if (hdr->Key != CST_5VW_RECORDS_HEADER_KEY) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("5views: Time-stamped header has bad key value 0x%08X",
		    hdr->Key);
		return FALSE;
	}

	hdr->RecSubType = pletoh32(&hdr->RecSubType);
	hdr->RecSize = pletoh32(&hdr->RecSize);
	hdr->Utc = pletoh32(&hdr->Utc);
	hdr->NanoSecondes = pletoh32(&hdr->NanoSecondes);

	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	phdr->ts.secs = hdr->Utc;
	phdr->ts.nsecs = hdr->NanoSecondes;
	phdr->caplen = hdr->RecSize;
	phdr->len = hdr->RecSize;

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

	return TRUE;
}
Example #4
0
/* Read the header of the next packet.  Return TRUE on success, FALSE
   on error. */
static gboolean
_5views_read_header(wtap *wth, FILE_T fh, t_5VW_TimeStamped_Header *hdr,
    wtap_rec *rec, int *err, gchar **err_info)
{
	/* Read record header. */
	if (!wtap_read_bytes_or_eof(fh, hdr, (unsigned int)sizeof(t_5VW_TimeStamped_Header),
	    err, err_info))
		return FALSE;

	hdr->Key = pletoh32(&hdr->Key);
	if (hdr->Key != CST_5VW_RECORDS_HEADER_KEY) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("5views: Time-stamped header has bad key value 0x%08X",
		    hdr->Key);
		return FALSE;
	}

	hdr->RecSubType = pletoh32(&hdr->RecSubType);
	hdr->RecSize = pletoh32(&hdr->RecSize);
	hdr->Utc = pletoh32(&hdr->Utc);
	hdr->NanoSecondes = pletoh32(&hdr->NanoSecondes);

	rec->rec_type = REC_TYPE_PACKET;
	rec->presence_flags = WTAP_HAS_TS;
	rec->ts.secs = hdr->Utc;
	rec->ts.nsecs = hdr->NanoSecondes;
	rec->rec_header.packet_header.caplen = hdr->RecSize;
	rec->rec_header.packet_header.len = hdr->RecSize;

	switch (wth->file_encap) {

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

	return TRUE;
}
Example #5
0
static gboolean
aethra_read_rec_header(wtap *wth, FILE_T fh, struct aethrarec_hdr *hdr,
    struct wtap_pkthdr *phdr, int *err, gchar **err_info)
{
	aethra_t *aethra = (aethra_t *)wth->priv;
	guint32 rec_size;
	guint32	packet_size;
	guint32	msecs;

	/* Read record header. */
	if (!wtap_read_bytes_or_eof(fh, hdr, sizeof *hdr, err, err_info))
		return FALSE;

	rec_size = pletoh16(hdr->rec_size);
	if (rec_size < (sizeof *hdr - sizeof hdr->rec_size)) {
		/* The record is shorter than a record header. */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("aethra: File has %u-byte record, less than minimum of %u",
		    rec_size,
		    (unsigned int)(sizeof *hdr - sizeof hdr->rec_size));
		return FALSE;
	}
	if (rec_size > WTAP_MAX_PACKET_SIZE) {
		/*
		 * Probably a corrupt capture file; return an error,
		 * so that our caller doesn't blow up trying to allocate
		 * space for an immensely-large packet.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("aethra: File has %u-byte packet, bigger than maximum of %u",
		    rec_size, WTAP_MAX_PACKET_SIZE);
		return FALSE;
	}

	packet_size = rec_size - (guint32)(sizeof *hdr - sizeof hdr->rec_size);

	msecs = pletoh32(hdr->timestamp);
	phdr->rec_type = REC_TYPE_PACKET;
	phdr->presence_flags = WTAP_HAS_TS;
	phdr->ts.secs = aethra->start + (msecs / 1000);
	phdr->ts.nsecs = (msecs % 1000) * 1000000;
	phdr->caplen = packet_size;
	phdr->len = packet_size;
	phdr->pseudo_header.isdn.uton = (hdr->flags & AETHRA_U_TO_N);
	phdr->pseudo_header.isdn.channel = 0;	/* XXX - D channel */

	return TRUE;
}
Example #6
0
static gboolean
aethra_read_rec_header(wtap *wth, FILE_T fh, struct aethrarec_hdr *hdr,
    struct wtap_pkthdr *phdr, int *err, gchar **err_info)
{
	aethra_t *aethra = (aethra_t *)wth->priv;
	int	bytes_read;
	guint32 rec_size;
	guint32	packet_size;
	guint32	msecs;

	/* Read record header. */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(hdr, sizeof *hdr, fh);
	if (bytes_read != sizeof *hdr) {
		*err = file_error(fh, err_info);
		if (*err == 0 && bytes_read != 0)
			*err = WTAP_ERR_SHORT_READ;
		return FALSE;
	}

	rec_size = pletoh16(hdr->rec_size);
	if (rec_size < (sizeof *hdr - sizeof hdr->rec_size)) {
		/* The record is shorter than a record header. */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("aethra: File has %u-byte record, less than minimum of %u",
		    rec_size,
		    (unsigned int)(sizeof *hdr - sizeof hdr->rec_size));
		return FALSE;
	}

	packet_size = rec_size - (guint32)(sizeof *hdr - sizeof hdr->rec_size);

	msecs = pletoh32(hdr->timestamp);
	phdr->presence_flags = WTAP_HAS_TS;
	phdr->ts.secs = aethra->start + (msecs / 1000);
	phdr->ts.nsecs = (msecs % 1000) * 1000000;
	phdr->caplen = packet_size;
	phdr->len = packet_size;
	phdr->pseudo_header.isdn.uton = (hdr->flags & AETHRA_U_TO_N);
	phdr->pseudo_header.isdn.channel = 0;	/* XXX - D channel */

	return TRUE;
}
Example #7
0
int _5views_open(wtap *wth, int *err, gchar **err_info)
{
	int bytes_read;
	t_5VW_Capture_Header Capture_Header;
	int encap = WTAP_ENCAP_UNKNOWN;

	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&Capture_Header.Info_Header, sizeof(t_5VW_Info_Header), wth->fh);
	if (bytes_read != sizeof(t_5VW_Info_Header)) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}

	/*	Check whether that's 5Views format or not */
	if(Capture_Header.Info_Header.Signature != CST_5VW_INFO_HEADER_KEY)
	{
		return 0;
	}

	/* Check Version */
	Capture_Header.Info_Header.Version =
	    pletoh32(&Capture_Header.Info_Header.Version);
	switch (Capture_Header.Info_Header.Version) {

	case CST_5VW_INFO_RECORD_VERSION:
		break;

	default:
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("5views: header version %u unsupported", Capture_Header.Info_Header.Version);
		return -1;
	}

	/* Check File Type */
	Capture_Header.Info_Header.FileType =
	    pletoh32(&Capture_Header.Info_Header.FileType);
	if((Capture_Header.Info_Header.FileType & CST_5VW_CAPTURE_FILE_TYPE_MASK) != CST_5VW_CAPTURE_FILEID)
	{
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("5views: file is not a capture file (filetype is %u)", Capture_Header.Info_Header.Version);
		return -1;
	}

	/* Check possible Encap */
	switch (Capture_Header.Info_Header.FileType) {
	case CST_5VW_CAPTURE_ETH_FILEID:
		encap = WTAP_ENCAP_ETHERNET;
		break;
/*	case CST_5VW_CAPTURE_WAN_FILEID:
		break;
*/
	default:
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("5views: network type %u unknown or unsupported",
		    Capture_Header.Info_Header.FileType);
		return -1;
	}

	/* read the remaining header information */
	bytes_read = file_read(&Capture_Header.HeaderDateCreation, sizeof (t_5VW_Capture_Header) - sizeof(t_5VW_Info_Header), wth->fh);
	if (bytes_read != sizeof (t_5VW_Capture_Header)- sizeof(t_5VW_Info_Header) ) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		return -1;
	}

	/* This is a 5views capture file */
	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_5VIEWS;
	wth->subtype_read = _5views_read;
	wth->subtype_seek_read = _5views_seek_read;
	wth->file_encap = encap;
	wth->snapshot_length = 0;	/* not available in header */
	wth->tsprecision = WTAP_FILE_TSPREC_NSEC;

	return 1;
}
Example #8
0
/*
 * Read the packet.
 *
 * XXX - we should supply the additional radio information;
 * the pseudo-header should probably be supplied in a fashion
 * similar to the radiotap radio header, so that the 802.11
 * dissector can determine which, if any, information items
 * are present.
 */
static int
peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
                       Buffer *buf, int *err, gchar **err_info)
{
    peektagged_t *peektagged = (peektagged_t *)wth->priv;
    gboolean read_a_tag = FALSE;
    guint8 tag_value[6];
    guint16 tag;
    gboolean saw_length = FALSE;
    guint32 length = 0;
    guint32 sliceLength = 0;
    gboolean saw_timestamp_lower = FALSE;
    gboolean saw_timestamp_upper = FALSE;
    peektagged_utime timestamp;
    guint32 ext_flags = 0;
    gboolean saw_data_rate_or_mcs_index = FALSE;
    guint32 data_rate_or_mcs_index = 0;
    gint channel;
    guint frequency;
    struct ieee_802_11_phdr ieee_802_11;
    guint i;
    int skip_len = 0;
    guint64 t;

    timestamp.upper = 0;
    timestamp.lower = 0;
    memset(&ieee_802_11, 0, sizeof ieee_802_11);
    ieee_802_11.fcs_len = -1; /* Unknown */
    ieee_802_11.decrypted = FALSE;
    ieee_802_11.datapad = FALSE;
    ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;

    /* Extract the fields from the packet header */
    do {
        /* Get the tag and value.
           XXX - this assumes all values are 4 bytes long. */
        if (!wtap_read_bytes_or_eof(fh, tag_value, sizeof tag_value, err, err_info)) {
            if (*err == 0) {
                /*
                 * Short read if we've read something already;
                 * just an EOF if we haven't.
                 */
                if (read_a_tag)
                    *err = WTAP_ERR_SHORT_READ;
            }
            return -1;
        }
        read_a_tag = TRUE;
        tag = pletoh16(&tag_value[0]);
        switch (tag) {

        case TAG_PEEKTAGGED_LENGTH:
            if (saw_length) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("peektagged: record has two length fields");
                return -1;
            }
            length = pletoh32(&tag_value[2]);
            saw_length = TRUE;
            break;

        case TAG_PEEKTAGGED_TIMESTAMP_LOWER:
            if (saw_timestamp_lower) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("peektagged: record has two timestamp-lower fields");
                return -1;
            }
            timestamp.lower = pletoh32(&tag_value[2]);
            saw_timestamp_lower = TRUE;
            break;

        case TAG_PEEKTAGGED_TIMESTAMP_UPPER:
            if (saw_timestamp_upper) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("peektagged: record has two timestamp-upper fields");
                return -1;
            }
            timestamp.upper = pletoh32(&tag_value[2]);
            saw_timestamp_upper = TRUE;
            break;

        case TAG_PEEKTAGGED_FLAGS_AND_STATUS:
            /* XXX - not used yet */
            break;

        case TAG_PEEKTAGGED_CHANNEL:
            ieee_802_11.has_channel = TRUE;
            ieee_802_11.channel = pletoh32(&tag_value[2]);
            break;

        case TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX:
            data_rate_or_mcs_index = pletoh32(&tag_value[2]);
            saw_data_rate_or_mcs_index = TRUE;
            break;

        case TAG_PEEKTAGGED_SIGNAL_PERC:
            ieee_802_11.has_signal_percent = TRUE;
            ieee_802_11.signal_percent = pletoh32(&tag_value[2]);
            break;

        case TAG_PEEKTAGGED_SIGNAL_DBM:
            ieee_802_11.has_signal_dbm = TRUE;
            ieee_802_11.signal_dbm = pletoh32(&tag_value[2]);
            break;

        case TAG_PEEKTAGGED_NOISE_PERC:
            ieee_802_11.has_noise_percent = TRUE;
            ieee_802_11.noise_percent = pletoh32(&tag_value[2]);
            break;

        case TAG_PEEKTAGGED_NOISE_DBM:
            ieee_802_11.has_noise_dbm = TRUE;
            ieee_802_11.noise_dbm = pletoh32(&tag_value[2]);
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x000A:
            /*
             * XXX - seen in some 802.11 captures.
             * Always seems to have the value 0 or 5.
             */
            break;

        case TAG_PEEKTAGGED_CENTER_FREQUENCY:
            /* XXX - also seen in an EtherPeek capture; value unknown */
            ieee_802_11.has_frequency = TRUE;
            ieee_802_11.frequency = pletoh32(&tag_value[2]);
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x000E:
            /*
             * XXX - seen in some 802.11 captures.
             * Usually has the value 4, but, in some packets, has the
             * values 6 or 302.
             *
             * Is this the mysterious "band" field that shows up in
             * some "Peek remote" protocol captures, with values in
             * the 30x or 40x ranges?  It's not always associated
             * with the "extended flags" tag for HT/VHT information,
             * so it's probably not 11n/11ac-specific.  Values other
             * than 4 appear, in my captures, only in packets with
             * the "extended flags" tag.  302 appeared in a packet
             * with EXT_FLAG_MCS_INDEX_USED; 6 appeared in packets
             * without EXT_FLAG_MCS_INDEX_USED.
             */
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x000F:
            /*
             * XXX - seen in some 802.11 captures; dB or dBm value?
             * Multiple antennas?
             */
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x0010:
            /*
             * XXX - seen in some 802.11 captures; dB or dBm value?
             * Multiple antennas?
             */
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x0011:
            /*
             * XXX - seen in some 802.11 captures; dB or dBm value?
             * Multiple antennas?
             */
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x0012:
            /*
             * XXX - seen in some 802.11 captures; dB or dBm value?
             * Multiple antennas?
             */
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x0013:
            /*
             * XXX - seen in some 802.11 captures; dB or dBm value?
             * Multiple antennas?
             */
            break;

        case TAG_PEEKTAGGED_UNKNOWN_0x0014:
            /*
             * XXX - seen in some 802.11 captures; dB or dBm value?
             * Multiple antennas?
             */
            break;

        case TAG_PEEKTAGGED_EXT_FLAGS:
            /*
             * We assume this is present for HT and VHT frames and absent
             * for other frames.
             */
            ext_flags = pletoh32(&tag_value[2]);
            if (ext_flags & EXT_FLAG_802_11ac) {
                ieee_802_11.phy = PHDR_802_11_PHY_11AC;
                /*
                 * XXX - this probably has only one user, so only
                 * one MCS index and only one NSS, but where's the
                 * NSS?
                 */
                for (i = 0; i < 4; i++)
                    ieee_802_11.phy_info.info_11ac.nss[i] = 0;

                switch (ext_flags & EXT_FLAGS_GI) {

                case EXT_FLAG_HALF_GI:
                    ieee_802_11.phy_info.info_11ac.has_short_gi = TRUE;
                    ieee_802_11.phy_info.info_11ac.short_gi = 1;
                    break;

                case EXT_FLAG_FULL_GI:
                    ieee_802_11.phy_info.info_11ac.has_short_gi = TRUE;
                    ieee_802_11.phy_info.info_11ac.short_gi = 0;
                    break;

                default:
                    /* Mutually exclusive flags set or nothing set */
                    break;
                }
            } else {
                ieee_802_11.phy = PHDR_802_11_PHY_11N;
                switch (ext_flags & EXT_FLAGS_BANDWIDTH) {

                case 0:
                    ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
                    ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_MHZ;
                    break;

                case EXT_FLAG_20_MHZ_LOWER:
                    ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
                    ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20L;
                    break;

                case EXT_FLAG_20_MHZ_UPPER:
                    ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
                    ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20U;
                    break;

                case EXT_FLAG_40_MHZ:
                    ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
                    ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_40_MHZ;
                    break;

                default:
                    /* Mutually exclusive flags set */
                    break;
                }

                switch (ext_flags & EXT_FLAGS_GI) {

                case EXT_FLAG_HALF_GI:
                    ieee_802_11.phy_info.info_11n.has_short_gi = TRUE;
                    ieee_802_11.phy_info.info_11n.short_gi = 1;
                    break;

                case EXT_FLAG_FULL_GI:
                    ieee_802_11.phy_info.info_11n.has_short_gi = TRUE;
                    ieee_802_11.phy_info.info_11n.short_gi = 0;
                    break;

                default:
                    /* Mutually exclusive flags set or nothing set */
                    break;
                }
            }
            break;

        case TAG_PEEKTAGGED_SLICE_LENGTH:
            sliceLength = pletoh32(&tag_value[2]);
            break;

        default:
            break;
        }
    } while (tag != TAG_PEEKTAGGED_SLICE_LENGTH);       /* last tag */

    if (!saw_length) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("peektagged: record has no length field");
        return -1;
    }
    if (!saw_timestamp_lower) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("peektagged: record has no timestamp-lower field");
        return -1;
    }
    if (!saw_timestamp_upper) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("peektagged: record has no timestamp-upper field");
        return -1;
    }

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

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

    phdr->rec_type = REC_TYPE_PACKET;
    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    phdr->len    = length;
    phdr->caplen = sliceLength;

    /* calculate and fill in packet time stamp */
    t = (((guint64) timestamp.upper) << 32) + timestamp.lower;
    if (!nsfiletime_to_nstime(&phdr->ts, t)) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("peektagged: time stamp outside supported range");
        return -1;
    }

    switch (wth->file_encap) {

    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
        if (saw_data_rate_or_mcs_index) {
            if (ext_flags & EXT_FLAG_MCS_INDEX_USED) {
                /*
                 * It's an MCS index.
                 *
                 * XXX - what about 11ac?
                 */
                if (!(ext_flags & EXT_FLAG_802_11ac)) {
                    ieee_802_11.phy_info.info_11n.has_mcs_index = TRUE;
                    ieee_802_11.phy_info.info_11n.mcs_index = data_rate_or_mcs_index;
                }
            } else {
                /* It's a data rate. */
                ieee_802_11.has_data_rate = TRUE;
                ieee_802_11.data_rate = data_rate_or_mcs_index;
            }
        }
        if (ieee_802_11.has_frequency && !ieee_802_11.has_channel) {
            /* Frequency, but no channel; try to calculate the channel. */
            channel = ieee80211_mhz_to_chan(ieee_802_11.frequency);
            if (channel != -1) {
                ieee_802_11.has_channel = TRUE;
                ieee_802_11.channel = channel;
            }
        } else if (ieee_802_11.has_channel && !ieee_802_11.has_frequency) {
            /*
             * If it's 11 legacy DHSS, 11b, or 11g, it's 2.4 GHz,
             * so we can calculate the frequency.
             *
             * If it's 11a, it's 5 GHz, so we can calculate the
             * frequency.
             */
            switch (ieee_802_11.phy) {

            case PHDR_802_11_PHY_11_DSSS:
            case PHDR_802_11_PHY_11B:
            case PHDR_802_11_PHY_11G:
                frequency = ieee80211_chan_to_mhz(ieee_802_11.channel, TRUE);
                break;

            case PHDR_802_11_PHY_11A:
                frequency = ieee80211_chan_to_mhz(ieee_802_11.channel, FALSE);
                break;

            default:
                /* We don't know the band. */
                frequency = 0;
                break;
            }
            if (frequency != 0) {
                ieee_802_11.has_frequency = TRUE;
                ieee_802_11.frequency = frequency;
            }
        }
        phdr->pseudo_header.ieee_802_11 = ieee_802_11;
        if (peektagged->has_fcs)
            phdr->pseudo_header.ieee_802_11.fcs_len = 4;
        else {
            if (phdr->len < 4 || phdr->caplen < 4) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup_printf("peektagged: 802.11 packet has length < 4");
                return FALSE;
            }
            phdr->pseudo_header.ieee_802_11.fcs_len = 0;
            phdr->len -= 4;
            phdr->caplen -= 4;
            skip_len = 4;
        }
        phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
        phdr->pseudo_header.ieee_802_11.datapad = FALSE;
        break;

    case WTAP_ENCAP_ETHERNET:
        /*
         * The last 4 bytes appear to be 0 in the captures I've seen;
         * are there any captures where it's an FCS?
         */
        if (phdr->len < 4 || phdr->caplen < 4) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("peektagged: Ethernet packet has length < 4");
            return FALSE;
        }
        phdr->pseudo_header.eth.fcs_len = 0;
        phdr->len -= 4;
        phdr->caplen -= 4;
        skip_len = 4;
        break;
    }

    /* Read the packet data. */
    if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
        return -1;

    return skip_len;
}
Example #9
0
/*
 * Read the packet.
 *
 * XXX - we should supply the additional radio information;
 * the pseudo-header should probably be supplied in a fashion
 * similar to the radiotap radio header, so that the 802.11
 * dissector can determine which, if any, information items
 * are present.
 */
static int
peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
                       Buffer *buf, int *err, gchar **err_info)
{
    peektagged_t *peektagged = (peektagged_t *)wth->priv;
    gboolean read_a_tag = FALSE;
    guint8 tag_value[6];
    guint16 tag;
    gboolean saw_length = FALSE;
    guint32 length = 0;
    guint32 sliceLength = 0;
    gboolean saw_timestamp_lower = FALSE;
    gboolean saw_timestamp_upper = FALSE;
    peektagged_utime timestamp;
    guint32 ext_flags = 0;
    gboolean saw_data_rate_or_mcs_index = FALSE;
    guint32 data_rate_or_mcs_index = 0;
    struct ieee_802_11_phdr ieee_802_11;
    int skip_len = 0;
    double  t;

    timestamp.upper = 0;
    timestamp.lower = 0;
    memset(&ieee_802_11, 0, sizeof ieee_802_11);

    /* Extract the fields from the packet header */
    do {
	/* Get the tag and value.
	   XXX - this assumes all values are 4 bytes long. */
	if (!wtap_read_bytes_or_eof(fh, tag_value, sizeof tag_value, err, err_info)) {
	    if (*err == 0) {
		/*
		 * Short read if we've read something already;
		 * just an EOF if we haven't.
		 */
		if (read_a_tag)
		    *err = WTAP_ERR_SHORT_READ;
	    }
	    return -1;
	}
	read_a_tag = TRUE;
	tag = pletoh16(&tag_value[0]);
	switch (tag) {

	case TAG_PEEKTAGGED_LENGTH:
	    if (saw_length) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup("peektagged: record has two length fields");
		return -1;
	    }
	    length = pletoh32(&tag_value[2]);
	    saw_length = TRUE;
	    break;

	case TAG_PEEKTAGGED_TIMESTAMP_LOWER:
	    if (saw_timestamp_lower) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup("peektagged: record has two timestamp-lower fields");
		return -1;
	    }
	    timestamp.lower = pletoh32(&tag_value[2]);
	    saw_timestamp_lower = TRUE;
	    break;

	case TAG_PEEKTAGGED_TIMESTAMP_UPPER:
	    if (saw_timestamp_upper) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup("peektagged: record has two timestamp-upper fields");
		return -1;
	    }
	    timestamp.upper = pletoh32(&tag_value[2]);
	    saw_timestamp_upper = TRUE;
	    break;

	case TAG_PEEKTAGGED_FLAGS_AND_STATUS:
	    /* XXX - not used yet */
	    break;

	case TAG_PEEKTAGGED_CHANNEL:
	    ieee_802_11.presence_flags |= PHDR_802_11_HAS_CHANNEL;
	    ieee_802_11.channel = pletoh32(&tag_value[2]);
	    break;

	case TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX:
	    data_rate_or_mcs_index = pletoh32(&tag_value[2]);
	    saw_data_rate_or_mcs_index = TRUE;
	    break;

	case TAG_PEEKTAGGED_SIGNAL_PERC:
	    ieee_802_11.presence_flags |= PHDR_802_11_HAS_SIGNAL_PERCENT;
	    ieee_802_11.signal_percent = pletoh32(&tag_value[2]);
	    break;

	case TAG_PEEKTAGGED_SIGNAL_DBM:
	    ieee_802_11.presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM;
	    ieee_802_11.signal_dbm = pletoh32(&tag_value[2]);
	    break;

	case TAG_PEEKTAGGED_NOISE_PERC:
	    ieee_802_11.presence_flags |= PHDR_802_11_HAS_NOISE_PERCENT;
	    ieee_802_11.noise_percent = pletoh32(&tag_value[2]);
	    break;

	case TAG_PEEKTAGGED_NOISE_DBM:
	    ieee_802_11.presence_flags |= PHDR_802_11_HAS_NOISE_DBM;
	    ieee_802_11.noise_dbm = pletoh32(&tag_value[2]);
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x000A:
	    /* XXX - seen in an OmniPeek 802.11n capture; value unknown */
	    break;

	case TAG_PEEKTAGGED_CENTER_FREQUENCY:
	    /* XXX - also seen in an EtherPeek capture; value unknown */
	    ieee_802_11.presence_flags |= PHDR_802_11_HAS_FREQUENCY;
	    ieee_802_11.frequency = pletoh32(&tag_value[2]);
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x000E:
	    /* XXX - seen in an AiroPeek/OmniPeek capture; value unknown */
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x000F:
	    /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x0010:
	    /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x0011:
	    /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x0012:
	    /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x0013:
	    /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
	    break;

	case TAG_PEEKTAGGED_UNKNOWN_0x0014:
	    /* XXX - seen in an AiroPeek/OmniPeek capture; value unknown */
	    break;

	case TAG_PEEKTAGGED_EXT_FLAGS:
	    ext_flags = pletoh32(&tag_value[2]);
	    break;

	case TAG_PEEKTAGGED_SLICE_LENGTH:
	    sliceLength = pletoh32(&tag_value[2]);
	    break;

	default:
	    break;
        }
    } while (tag != TAG_PEEKTAGGED_SLICE_LENGTH);	/* last tag */

    if (!saw_length) {
	*err = WTAP_ERR_BAD_FILE;
	*err_info = g_strdup("peektagged: record has no length field");
	return -1;
    }
    if (!saw_timestamp_lower) {
	*err = WTAP_ERR_BAD_FILE;
	*err_info = g_strdup("peektagged: record has no timestamp-lower field");
	return -1;
    }
    if (!saw_timestamp_upper) {
	*err = WTAP_ERR_BAD_FILE;
	*err_info = g_strdup("peektagged: record has no timestamp-upper field");
	return -1;
    }

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

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

    phdr->rec_type = REC_TYPE_PACKET;
    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    phdr->len    = length;
    phdr->caplen = sliceLength;

    /* calculate and fill in packet time stamp */
    t =  (double) timestamp.lower +
	 (double) timestamp.upper * 4294967296.0;
    t *= 1.0e-9;
    t -= TIME_FIXUP_CONSTANT;
    phdr->ts.secs  = (time_t) t;
    phdr->ts.nsecs = (guint32) ((t - phdr->ts.secs)*1000000000);

    switch (wth->file_encap) {

    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
	if (saw_data_rate_or_mcs_index) {
	    if (ext_flags & EXT_FLAG_MCS_INDEX_USED) {
		/* It's an MCS index. */
		ieee_802_11.presence_flags |= PHDR_802_11_HAS_MCS_INDEX;
		ieee_802_11.mcs_index = data_rate_or_mcs_index;

		/*
		 * Fill in other 802.11n information.
		 */
		switch (ext_flags & EXT_FLAGS_BANDWIDTH) {

		case 0:
		    ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH;
		    ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_20_MHZ;
		    break;

		case EXT_FLAG_20_MHZ_LOWER:
		    ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH;
		    ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_20_20L;
		    break;

		case EXT_FLAG_20_MHZ_UPPER:
		    ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH;
		    ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_20_20U;
		    break;

		case EXT_FLAG_40_MHZ:
		    ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH;
		    ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_40_MHZ;
		    break;

		default:
		    /* Mutually exclusive flags set */
		    break;
		}

		switch (ext_flags & EXT_FLAGS_GI) {

		case EXT_FLAG_HALF_GI:
		    ieee_802_11.presence_flags |= PHDR_802_11_HAS_SHORT_GI;
		    ieee_802_11.short_gi = 1;
		    break;

		case EXT_FLAG_FULL_GI:
		    ieee_802_11.presence_flags |= PHDR_802_11_HAS_SHORT_GI;
		    ieee_802_11.short_gi = 0;
		    break;

		default:
		    /* Mutually exclusive flags set */
		    break;
		}
	    } else {
		/* It's a data rate */
		ieee_802_11.presence_flags |= PHDR_802_11_HAS_DATA_RATE;
		ieee_802_11.data_rate = data_rate_or_mcs_index;
	    }
	}
	phdr->pseudo_header.ieee_802_11 = ieee_802_11;
	if (peektagged->has_fcs)
	    phdr->pseudo_header.ieee_802_11.fcs_len = 4;
	else {
	    if (phdr->len < 4 || phdr->caplen < 4) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("peektagged: 802.11 packet has length < 4");
		return FALSE;
	    }
	    phdr->pseudo_header.ieee_802_11.fcs_len = 0;
	    phdr->len -= 4;
	    phdr->caplen -= 4;
	    skip_len = 4;
	}
	phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
	break;

    case WTAP_ENCAP_ETHERNET:
	/*
	 * The last 4 bytes appear to be 0 in the captures I've seen;
	 * are there any captures where it's an FCS?
	 */
	if (phdr->len < 4 || phdr->caplen < 4) {
	    *err = WTAP_ERR_BAD_FILE;
	    *err_info = g_strdup_printf("peektagged: Ethernet packet has length < 4");
	    return FALSE;
	}
	phdr->pseudo_header.eth.fcs_len = 0;
	phdr->len -= 4;
	phdr->caplen -= 4;
	skip_len = 4;
	break;
    }

    /* Read the packet data. */
    if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
        return -1;

    return skip_len;
}
Example #10
0
static gboolean netmon_process_rec_header(wtap *wth, FILE_T fh,
    struct wtap_pkthdr *phdr, int *err, gchar **err_info)
{
	netmon_t *netmon = (netmon_t *)wth->priv;
	int	hdr_size = 0;
	union {
		struct netmonrec_1_x_hdr hdr_1_x;
		struct netmonrec_2_x_hdr hdr_2_x;
	}	hdr;
	int	bytes_read;
	gint64	delta = 0;	/* signed - frame times can be before the nominal start */
	gint64	t;
	time_t	secs;
	guint32	nsecs;
	guint32	packet_size = 0;
	guint32 orig_size = 0;

	/* Read record header. */
	switch (netmon->version_major) {

	case 1:
		hdr_size = sizeof (struct netmonrec_1_x_hdr);
		break;

	case 2:
		hdr_size = sizeof (struct netmonrec_2_x_hdr);
		break;
	}
	errno = WTAP_ERR_CANT_READ;

	bytes_read = file_read(&hdr, hdr_size, fh);
	if (bytes_read != hdr_size) {
		*err = file_error(fh, err_info);
		if (*err == 0 && bytes_read != 0) {
			*err = WTAP_ERR_SHORT_READ;
		}
		return FALSE;
	}

	switch (netmon->version_major) {

	case 1:
		orig_size = pletoh16(&hdr.hdr_1_x.orig_len);
		packet_size = pletoh16(&hdr.hdr_1_x.incl_len);
		break;

	case 2:
		orig_size = pletoh32(&hdr.hdr_2_x.orig_len);
		packet_size = pletoh32(&hdr.hdr_2_x.incl_len);
		break;
	}
	if (packet_size > WTAP_MAX_PACKET_SIZE) {
		/*
		 * Probably a corrupt capture file; don't blow up trying
		 * to allocate space for an immensely-large packet.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return FALSE;
	}

	/*
	 * If this is an ATM packet, the first
	 * "sizeof (struct netmon_atm_hdr)" bytes have destination and
	 * source addresses (6 bytes - MAC addresses of some sort?)
	 * and the VPI and VCI; read them and generate the pseudo-header
	 * from them.
	 */
	switch (wth->file_encap) {

	case WTAP_ENCAP_ATM_PDUS:
		if (packet_size < sizeof (struct netmon_atm_hdr)) {
			/*
			 * Uh-oh, the packet isn't big enough to even
			 * have a pseudo-header.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("netmon: ATM file has a %u-byte packet, too small to have even an ATM pseudo-header",
			    packet_size);
			return FALSE;
		}
		if (!netmon_read_atm_pseudoheader(fh, &phdr->pseudo_header,
		    err, err_info))
			return FALSE;	/* Read error */

		/*
		 * Don't count the pseudo-header as part of the packet.
		 */
		orig_size -= (guint)sizeof (struct netmon_atm_hdr);
		packet_size -= (guint)sizeof (struct netmon_atm_hdr);
		break;

	default:
		break;
	}

	switch (netmon->version_major) {

	case 1:
		/*
		 * According to Paul Long, this offset is unsigned.
		 * It's 32 bits, so the maximum value will fit in
		 * a gint64 such as delta, even after multiplying
		 * it by 1000000.
		 *
		 * pletoh32() returns a guint32; we cast it to gint64
		 * before multiplying, so that the product doesn't
		 * overflow a guint32.
		 */
		delta = ((gint64)pletoh32(&hdr.hdr_1_x.ts_delta))*1000000;
		break;

	case 2:
		/*
		 * OK, this is weird.  Microsoft's documentation
		 * says this is in microseconds and is a 64-bit
		 * unsigned number, but it can be negative; they
		 * say what appears to amount to "treat it as an
		 * unsigned number, multiply it by 10, and then
		 * interpret the resulting 64-bit quantity as a
		 * signed number".  That operation can turn a
		 * value with the uppermost bit 0 to a value with
		 * the uppermost bit 1, hence turning a large
		 * positive number-of-microseconds into a small
		 * negative number-of-100-nanosecond-increments.
		 */
		delta = pletoh64(&hdr.hdr_2_x.ts_delta)*10;

		/*
		 * OK, it's now a signed value in 100-nanosecond
		 * units.  Now convert it to nanosecond units.
		 */
		delta *= 100;
		break;
	}
	secs = 0;
	t = netmon->start_nsecs + delta;
	while (t < 0) {
		/*
		 * Propagate a borrow into the seconds.
		 * The seconds is a time_t, and can be < 0
		 * (unlikely, as Windows didn't exist before
		 * January 1, 1970, 00:00:00 UTC), while the
		 * nanoseconds should be positive, as in
		 * "nanoseconds since the instant of time
		 * represented by the seconds".
		 *
		 * We do not want t to be negative, as, according
		 * to the C90 standard, "if either operand [of /
		 * or %] is negative, whether the result of the
		 * / operator is the largest integer less than or
		 * equal to the algebraic quotient or the smallest
		 * greater than or equal to the algebraic quotient
		 * is implementation-defined, as is the sign of
		 * the result of the % operator", and we want
		 * the result of the division and remainder
		 * operations to be the same on all platforms.
		 */
		t += 1000000000;
		secs--;
	}
	secs += (time_t)(t/1000000000);
	nsecs = (guint32)(t%1000000000);
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	phdr->ts.secs = netmon->start_secs + secs;
	phdr->ts.nsecs = nsecs;
	phdr->caplen = packet_size;
	phdr->len = orig_size;

	return TRUE;
}
Example #11
0
static gboolean
radcom_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf,
		int *err, gchar **err_info)
{
	struct radcomrec_hdr hdr;
	guint16 data_length, real_length, length;
	guint32 sec;
	struct tm tm;
	guint8	atmhdr[8];

	if (!wtap_read_bytes_or_eof(fh, &hdr, sizeof hdr, err, err_info))
		return FALSE;

	data_length = pletoh16(&hdr.data_length);
	if (data_length == 0) {
		/*
		 * The last record appears to have 0 in its "data_length"
		 * field, but non-zero values in other fields, so we
		 * check for that and treat it as an EOF indication.
		 */
		*err = 0;
		return FALSE;
	}
	length = pletoh16(&hdr.length);
	real_length = pletoh16(&hdr.real_length);
	/*
	 * The maximum value of length is 65535, which is less than
	 * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check
	 * it.
	 */

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

	tm.tm_year = pletoh16(&hdr.date.year)-1900;
	tm.tm_mon = (hdr.date.month&0x0f)-1;
	tm.tm_mday = hdr.date.day;
	sec = pletoh32(&hdr.date.sec);
	tm.tm_hour = sec/3600;
	tm.tm_min = (sec%3600)/60;
	tm.tm_sec = sec%60;
	tm.tm_isdst = -1;
	rec->ts.secs = mktime(&tm);
	rec->ts.nsecs = pletoh32(&hdr.date.usec) * 1000;

	switch (wth->file_encap) {

	case WTAP_ENCAP_ETHERNET:
		/* XXX - is there an FCS? */
		rec->rec_header.packet_header.pseudo_header.eth.fcs_len = -1;
		break;

	case WTAP_ENCAP_LAPB:
		rec->rec_header.packet_header.pseudo_header.dte_dce.flags = (hdr.dce & 0x1) ?
		    0x00 : FROM_DCE;
		length -= 2; /* FCS */
		real_length -= 2;
		break;

	case WTAP_ENCAP_ATM_RFC1483:
		/*
		 * XXX - is this stuff a pseudo-header?
		 * The direction appears to be in the "hdr.dce" field.
		 */
		if (!wtap_read_bytes(fh, atmhdr, sizeof atmhdr, err,
		    err_info))
			return FALSE;	/* Read error */
		length -= 8;
		real_length -= 8;
		break;
	}

	rec->rec_header.packet_header.len = real_length;
	rec->rec_header.packet_header.caplen = length;

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

	return TRUE;
}
Example #12
0
static gboolean
visual_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
        Buffer *buf, int *err, gchar **err_info)
{
    struct visual_read_info *visual = (struct visual_read_info *)wth->priv;
    struct visual_pkt_hdr vpkt_hdr;
    int bytes_read;
    guint32 packet_size;
    struct visual_atm_hdr vatm_hdr;
    double  t;
    time_t  secs;
    guint32 usecs;
    guint32 packet_status;
    guint8 *pd;

    /* Read the packet header. */
    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(&vpkt_hdr, (unsigned int)sizeof vpkt_hdr, fh);
    if (bytes_read < 0 || (size_t)bytes_read != sizeof vpkt_hdr)
    {
        *err = file_error(fh, err_info);
        if (*err == 0 && bytes_read != 0)
        {
            *err = WTAP_ERR_SHORT_READ;
        }
        return FALSE;
    }

    /* Get the included length of data. This includes extra headers + payload */
    packet_size = pletoh16(&vpkt_hdr.incl_len);

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

    /* Set the packet time and length. */
    t = visual->start_time;
    t += ((double)pletoh32(&vpkt_hdr.ts_delta))*1000;
    secs = (time_t)(t/1000000);
    usecs = (guint32)(t - secs*1000000);
    phdr->ts.secs = secs;
    phdr->ts.nsecs = usecs * 1000;

    phdr->len = pletoh16(&vpkt_hdr.orig_len);

    packet_status = pletoh32(&vpkt_hdr.status);

    /* Do encapsulation-specific processing.

       Most Visual capture types include the FCS in the original length
       value, but don't include the FCS as part of the payload or captured
       length.  This is different from the model used in most other capture
       file formats, including pcap and pcap-ng in cases where the FCS isn't
       captured (which are the typical cases), and causes the RTP audio
       payload save to fail since then captured len != orig len.

       We adjust the original length to remove the FCS bytes we counted based
       on the file encapsualtion type.  The only downside to this fix is
       throughput calculations will be slightly lower as it won't include
       the FCS bytes.  However, as noted, that problem also exists with
       other capture formats.

       We also set status flags.  The only status currently supported for
       all encapsulations is direction.  This either goes in the p2p or the
       X.25 pseudo header.  It would probably be better to move this up
       into the phdr. */
    switch (wth->file_encap)
    {
    case WTAP_ENCAP_ETHERNET:
        /* Ethernet has a 4-byte FCS. */
        if (phdr->len < 4)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Ethernet packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 4;

        /* XXX - the above implies that there's never an FCS; should this
           set the FCS length to 0? */
        phdr->pseudo_header.eth.fcs_len = -1;
        break;

    case WTAP_ENCAP_CHDLC_WITH_PHDR:
        /* This has a 2-byte FCS. */
        if (phdr->len < 2)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Cisco HDLC packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 2;

        phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE;
        break;

    case WTAP_ENCAP_PPP_WITH_PHDR:
        /* No FCS.
           XXX - true?  Note that PPP can negotiate no FCS, a 2-byte FCS,
           or a 4-byte FCS. */
        phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE;
        break;

    case WTAP_ENCAP_FRELAY_WITH_PHDR:
        /* This has a 2-byte FCS. */
        if (phdr->len < 2)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 2;

        phdr->pseudo_header.x25.flags =
            (packet_status & PS_SENT) ? 0x00 : FROM_DCE;
        break;

    case WTAP_ENCAP_LAPB:
        /* This has a 2-byte FCS. */
        if (phdr->len < 2)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 2;

        phdr->pseudo_header.x25.flags =
            (packet_status & PS_SENT) ? 0x00 : FROM_DCE;
        break;

    case WTAP_ENCAP_ATM_PDUS:
        /* ATM original length doesn't include any FCS. Do nothing to
           the packet length.

           ATM packets have an additional packet header; read and
           process it. */
        errno = WTAP_ERR_CANT_READ;
        bytes_read = file_read(&vatm_hdr, (unsigned int)sizeof vatm_hdr, fh);
        if (bytes_read < 0 || (size_t)bytes_read != sizeof vatm_hdr)
        {
            *err = file_error(fh, err_info);
            if (*err == 0)
            {
                *err = WTAP_ERR_SHORT_READ;
            }
            return FALSE;
        }

        /* Remove ATM header from length of included bytes in capture, as
           this header was appended by the processor doing the packet
           reassembly, and was not transmitted across the wire */
        packet_size -= (guint32)sizeof vatm_hdr;

        /* Set defaults */
        phdr->pseudo_header.atm.type = TRAF_UNKNOWN;
        phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN;
        phdr->pseudo_header.atm.aal5t_len = 0;

        /* Next two items not supported. Defaulting to zero */
        phdr->pseudo_header.atm.aal5t_u2u = 0;
        phdr->pseudo_header.atm.aal5t_chksum = 0;

        /* Flags appear only to convey that packet is a raw cell. Set to 0 */
        phdr->pseudo_header.atm.flags = 0;

        /* Not supported. Defaulting to zero */
        phdr->pseudo_header.atm.aal2_cid = 0;

        switch(vatm_hdr.category & VN_CAT_TYPE_MASK )
        {
        case VN_AAL1:
            phdr->pseudo_header.atm.aal = AAL_1;
            break;

        case VN_AAL2:
            phdr->pseudo_header.atm.aal = AAL_2;
            break;

        case VN_AAL34:
            phdr->pseudo_header.atm.aal = AAL_3_4;
            break;

        case VN_AAL5:
            phdr->pseudo_header.atm.aal = AAL_5;
            phdr->pseudo_header.atm.type = TRAF_LLCMX;
            phdr->pseudo_header.atm.aal5t_len = pntoh32(&vatm_hdr.data_length);
            break;

        case VN_OAM:
        /* Marking next 3 as OAM versus unknown */
        case VN_O191:
        case VN_IDLE:
        case VN_RM:
            phdr->pseudo_header.atm.aal = AAL_OAMCELL;
            break;

        case VN_UNKNOWN:
        default:
            phdr->pseudo_header.atm.aal = AAL_UNKNOWN;
            break;
        }
        phdr->pseudo_header.atm.vpi = pntoh16(&vatm_hdr.vpi) & 0x0FFF;
        phdr->pseudo_header.atm.vci = pntoh16(&vatm_hdr.vci);
        phdr->pseudo_header.atm.cells = pntoh16(&vatm_hdr.cell_count);

        /* Using bit value of 1 (DCE -> DTE) to indicate From Network */
        phdr->pseudo_header.atm.channel = vatm_hdr.info & FROM_NETWORK;
        break;

    /* Not sure about token ring. Just leaving alone for now. */
    case WTAP_ENCAP_TOKEN_RING:
    default:
        break;
    }

    phdr->caplen = packet_size;

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

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

    if (wth->file_encap == WTAP_ENCAP_CHDLC_WITH_PHDR)
    {
        /* Fill in the encapsulation.  Visual files have a media type in the
           file header and an encapsulation type in each packet header.  Files
           with a media type of HDLC can be either Cisco EtherType or PPP.

           The encapsulation hint values we've seen are:

             2 - seen in an Ethernet capture
             13 - seen in a PPP capture; possibly also seen in Cisco HDLC
                  captures
             14 - seen in a PPP capture; probably seen only for PPP.

           According to bug 2005, the collection probe can be configured
           for PPP, in which case the encapsulation hint is 14, or can
           be configured for auto-detect, in which case the encapsulation
           hint is 13, and the encapsulation must be guessed from the
           packet contents.  Auto-detect is the default. */
        pd = ws_buffer_start_ptr(buf);

        /* If PPP is specified in the encap hint, then use that */
        if (vpkt_hdr.encap_hint == 14)
        {
            /* But first we need to examine the first three octets to
               try to determine the proper encapsulation, see RFC 2364. */
            if (packet_size >= 3 &&
                (0xfe == pd[0]) && (0xfe == pd[1]) && (0x03 == pd[2]))
            {
                /* It is actually LLC encapsulated PPP */
                phdr->pkt_encap = WTAP_ENCAP_ATM_RFC1483;
            }
            else
            {
                /* It is actually PPP */
                phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR;
            }
        }
        else
        {
            /* Otherwise, we need to examine the first two octets to
               try to determine the encapsulation. */
            if (packet_size >= 2 && (0xff == pd[0]) && (0x03 == pd[1]))
            {
                /* It is actually PPP */
                phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR;
            }
        }
    }

    return TRUE;
}
Example #13
0
/* Open a file for reading */
int visual_open(wtap *wth, int *err, gchar **err_info)
{
    int bytes_read;
    char magic[sizeof visual_magic];
    struct visual_file_hdr vfile_hdr;
    struct visual_read_info * visual;
    int encap;

    /* Check the magic string at the start of the file */
    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(magic, sizeof magic, wth->fh);
    if (bytes_read != sizeof magic)
    {
        *err = file_error(wth->fh, err_info);
        if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
            return -1;
        return 0;
    }
    if (memcmp(magic, visual_magic, sizeof visual_magic) != 0)
    {
        return 0;
    }

    /* Read the rest of the file header. */
    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(&vfile_hdr, sizeof vfile_hdr, wth->fh);
    if (bytes_read != sizeof vfile_hdr)
    {
        *err = file_error(wth->fh, err_info);
        if (*err == 0)
            *err = WTAP_ERR_SHORT_READ;
        return -1;
    }

    /* Verify the file version is known */
    vfile_hdr.file_version = pletoh16(&vfile_hdr.file_version);
    if (vfile_hdr.file_version != 1)
    {
        *err = WTAP_ERR_UNSUPPORTED;
        *err_info = g_strdup_printf("visual: file version %u unsupported", vfile_hdr.file_version);
        return -1;
    }

    /* Translate the encapsulation type; these values are SNMP ifType
       values, as found in http://www.iana.org/assignments/smi-numbers.

       Note that a file with media type 22 ("propPointToPointSerial") may
       contain Cisco HDLC or PPP over HDLC.  This will get sorted out after
       the first packet is read.

       XXX - should we use WTAP_ENCAP_PER_PACKET for that? */
    switch (pletoh16(&vfile_hdr.media_type))
    {
    case  6:	/* ethernet-csmacd */
        encap = WTAP_ENCAP_ETHERNET;
        break;

    case  9:	/* IEEE802.5 */
        encap = WTAP_ENCAP_TOKEN_RING;
        break;

    case 16:	/* lapb */
        encap = WTAP_ENCAP_LAPB;
        break;

    case 22:	/* propPointToPointSerial */
    case 118:	/* HDLC */
        encap = WTAP_ENCAP_CHDLC_WITH_PHDR;
        break;

    case 32:	/* frame-relay */
        encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
        break;

    case 37:	/* ATM */
       encap = WTAP_ENCAP_ATM_PDUS;
       break;

    default:
        *err = WTAP_ERR_UNSUPPORTED_ENCAP;
        *err_info = g_strdup_printf("visual: network type %u unknown or unsupported",
                                     vfile_hdr.media_type);
        return -1;
    }

    /* Fill in the wiretap struct with data from the file header */
    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_VISUAL_NETWORKS;
    wth->file_encap = encap;
    wth->snapshot_length = pletoh16(&vfile_hdr.max_length);

    /* Set up the pointers to the handlers for this file type */
    wth->subtype_read = visual_read;
    wth->subtype_seek_read = visual_seek_read;
    wth->tsprecision = WTAP_FILE_TSPREC_USEC;

    /* Add Visual-specific information to the wiretap struct for later use. */
    visual = (struct visual_read_info *)g_malloc(sizeof(struct visual_read_info));
    wth->priv = (void *)visual;
    visual->num_pkts = pletoh32(&vfile_hdr.num_pkts);
    visual->start_time = ((double) pletoh32(&vfile_hdr.start_time)) * 1000000;
    visual->current_pkt = 1;

    return 1;
}
Example #14
0
 * no longer make any big-endian machines (Macs use x86, iOS machines
 * use ARM and run it little-endian), so that might be by definition
 * or they might be host-endian.
 *
 * If a big-endian PKTAP file ever shows up, and it comes from a
 * big-endian machine, presumably these are host-endian, and we need
 * to just fetch the fields in host byte order here but byte-swap them
 * to host byte order in libwiretap.
 */

static gboolean
capture_pktap(const guchar *pd, int offset _U_, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
{
	guint32  hdrlen, rectype, dlt;

	hdrlen = pletoh32(pd);
	if (hdrlen < MIN_PKTAP_HDR_LEN || !BYTES_ARE_IN_FRAME(0, len, hdrlen))
		return FALSE;

	rectype = pletoh32(pd+4);
	if (rectype != PKT_REC_PACKET)
		return FALSE;

	dlt = pletoh32(pd+4);

	/* XXX - We should probably combine this with capture_info.c:capture_info_packet() */
	switch (dlt) {

	case 1: /* DLT_EN10MB */
		return call_capture_dissector(eth_cap_handle, pd, hdrlen, len, cpinfo, pseudo_header);
Example #15
0
wtap_open_return_val radcom_open(wtap *wth, int *err, gchar **err_info)
{
	guint8 r_magic[8], t_magic[11], search_encap[7];
	struct frame_date start_date;
#if 0
	guint32 sec;
	struct tm tm;
#endif

	/* Read in the string that should be at the start of a RADCOM file */
	if (!wtap_read_bytes(wth->fh, r_magic, 8, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	/* XXX: bytes 2 and 3 of the "magic" header seem to be different in some
	 * captures. We force them to our standard value so that the test
	 * succeeds (until we find if they have a special meaning, perhaps a
	 * version number ?) */
	r_magic[1] = 0xD2;
	r_magic[2] = 0x00;
	if (memcmp(r_magic, radcom_magic, 8) != 0) {
		return WTAP_OPEN_NOT_MINE;
	}

	/* Look for the "Active Time" string. The "frame_date" structure should
	 * be located 32 bytes before the beginning of this string */
	if (!wtap_read_bytes(wth->fh, t_magic, 11, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}
	while (memcmp(t_magic, active_time_magic, 11) != 0)
	{
		if (file_seek(wth->fh, -10, SEEK_CUR, err) == -1)
			return WTAP_OPEN_ERROR;
		if (!wtap_read_bytes(wth->fh, t_magic, 11, err, err_info)) {
			if (*err != WTAP_ERR_SHORT_READ)
				return WTAP_OPEN_ERROR;
			return WTAP_OPEN_NOT_MINE;
		}
	}
	if (file_seek(wth->fh, -43, SEEK_CUR, err) == -1)
		return WTAP_OPEN_ERROR;

	/* Get capture start time */
	if (!wtap_read_bytes(wth->fh, &start_date, sizeof(struct frame_date),
	    err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	/* So what time is this? */
	if (!wtap_read_bytes(wth->fh, NULL, sizeof(struct frame_date),
	    err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

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

		if (memcmp(encap_magic, search_encap, 4) == 0)
			break;

		/*
		 * OK, that's not it, go forward 1 byte - reading
		 * the magic moved us forward 4 bytes, so seeking
		 * backward 3 bytes moves forward 1 byte - and
		 * try the 4 bytes at that offset.
		 */
		if (file_seek(wth->fh, -3, SEEK_CUR, err) == -1)
			return WTAP_OPEN_ERROR;
	}
	if (!wtap_read_bytes(wth->fh, NULL, 12, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}
	if (!wtap_read_bytes(wth->fh, search_encap, 4, err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	/* This is a radcom file */
	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_RADCOM;
	wth->subtype_read = radcom_read;
	wth->subtype_seek_read = radcom_seek_read;
	wth->snapshot_length = 0; /* not available in header, only in frame */
	wth->file_tsprec = WTAP_TSPREC_USEC;

#if 0
	tm.tm_year = pletoh16(&start_date.year)-1900;
	tm.tm_mon = start_date.month-1;
	tm.tm_mday = start_date.day;
	sec = pletoh32(&start_date.sec);
	tm.tm_hour = sec/3600;
	tm.tm_min = (sec%3600)/60;
	tm.tm_sec = sec%60;
	tm.tm_isdst = -1;
#endif

	if (memcmp(search_encap, "LAPB", 4) == 0)
		wth->file_encap = WTAP_ENCAP_LAPB;
	else if (memcmp(search_encap, "Ethe", 4) == 0)
		wth->file_encap = WTAP_ENCAP_ETHERNET;
	else if (memcmp(search_encap, "ATM/", 4) == 0)
		wth->file_encap = WTAP_ENCAP_ATM_RFC1483;
	else {
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("radcom: network type \"%.4s\" unknown", search_encap);
		return WTAP_OPEN_ERROR;
	}

#if 0
	if (!wtap_read_bytes(wth->fh, &next_date, sizeof(struct frame_date),
	    err, err_info))
		return WTAP_OPEN_ERROR;

	while (memcmp(&start_date, &next_date, 4)) {
		if (file_seek(wth->fh, 1-sizeof(struct frame_date), SEEK_CUR, err) == -1)
			return WTAP_OPEN_ERROR;
		if (!wtap_read_bytes(wth->fh, &next_date, sizeof(struct frame_date),
		    err, err_info))
			return WTAP_OPEN_ERROR;
	}
#endif

	if (wth->file_encap == WTAP_ENCAP_ETHERNET) {
		if (!wtap_read_bytes(wth->fh, NULL, 294, err, err_info))
			return WTAP_OPEN_ERROR;
	} else if (wth->file_encap == WTAP_ENCAP_LAPB) {
		if (!wtap_read_bytes(wth->fh, NULL, 297, err, err_info))
			return WTAP_OPEN_ERROR;
	} else if (wth->file_encap == WTAP_ENCAP_ATM_RFC1483) {
		if (!wtap_read_bytes(wth->fh, NULL, 504, err, err_info))
			return WTAP_OPEN_ERROR;
	}

	return WTAP_OPEN_MINE;
}
Example #16
0
int netmon_open(wtap *wth, int *err, gchar **err_info)
{
	int bytes_read;
	char magic[MAGIC_SIZE];
	struct netmon_hdr hdr;
	int file_type;
	struct tm tm;
	guint32 frame_table_offset;
	guint32 frame_table_length;
	guint32 frame_table_size;
	guint32 *frame_table;
#ifdef WORDS_BIGENDIAN
	unsigned int i;
#endif
	netmon_t *netmon;

	/* Read in the string that should be at the start of a Network
	 * Monitor file */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(magic, MAGIC_SIZE, wth->fh);
	if (bytes_read != MAGIC_SIZE) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}

	if (memcmp(magic, netmon_1_x_magic, MAGIC_SIZE) != 0 &&
	    memcmp(magic, netmon_2_x_magic, MAGIC_SIZE) != 0) {
		return 0;
	}

	/* Read the rest of the header. */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
	if (bytes_read != sizeof hdr) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		return -1;
	}

	switch (hdr.ver_major) {

	case 1:
		file_type = WTAP_FILE_TYPE_SUBTYPE_NETMON_1_x;
		break;

	case 2:
		file_type = WTAP_FILE_TYPE_SUBTYPE_NETMON_2_x;
		break;

	default:
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("netmon: major version %u unsupported", hdr.ver_major);
		return -1;
	}

	hdr.network = pletoh16(&hdr.network);
	if (hdr.network >= NUM_NETMON_ENCAPS
	    || netmon_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
		    hdr.network);
		return -1;
	}

	/* This is a netmon file */
	wth->file_type_subtype = file_type;
	netmon = (netmon_t *)g_malloc(sizeof(netmon_t));
	wth->priv = (void *)netmon;
	wth->subtype_read = netmon_read;
	wth->subtype_seek_read = netmon_seek_read;
	wth->subtype_sequential_close = netmon_sequential_close;

	/* NetMon capture file formats v2.1+ use per-packet encapsulation types.  NetMon 3 sets the value in
	 * the header to 1 (Ethernet) for backwards compability. */
	if((hdr.ver_major == 2 && hdr.ver_minor >= 1) || hdr.ver_major > 2)
		wth->file_encap = WTAP_ENCAP_PER_PACKET;
	else
		wth->file_encap = netmon_encap[hdr.network];

	wth->snapshot_length = 0;	/* not available in header */
	/*
	 * Convert the time stamp to a "time_t" and a number of
	 * milliseconds.
	 */
	tm.tm_year = pletoh16(&hdr.ts_year) - 1900;
	tm.tm_mon = pletoh16(&hdr.ts_month) - 1;
	tm.tm_mday = pletoh16(&hdr.ts_day);
	tm.tm_hour = pletoh16(&hdr.ts_hour);
	tm.tm_min = pletoh16(&hdr.ts_min);
	tm.tm_sec = pletoh16(&hdr.ts_sec);
	tm.tm_isdst = -1;
	netmon->start_secs = mktime(&tm);
	/*
	 * XXX - what if "secs" is -1?  Unlikely, but if the capture was
	 * done in a time zone that switches between standard and summer
	 * time sometime other than when we do, and thus the time was one
	 * that doesn't exist here because a switch from standard to summer
	 * time zips over it, it could happen.
	 *
	 * On the other hand, if the capture was done in a different time
	 * zone, this won't work right anyway; unfortunately, the time
	 * zone isn't stored in the capture file (why the hell didn't
	 * they stuff a FILETIME, which is the number of 100-nanosecond
	 * intervals since 1601-01-01 00:00:00 "UTC", there, instead
	 * of stuffing a SYSTEMTIME, which is time-zone-dependent, there?).
	 */
	netmon->start_nsecs = pletoh16(&hdr.ts_msec)*1000000;

	netmon->version_major = hdr.ver_major;
	netmon->version_minor = hdr.ver_minor;

	/*
	 * No frame table allocated yet; initialize these in case we
	 * get an error before allocating it or when trying to allocate
	 * it, so that the attempt to release the private data on failure
	 * doesn't crash.
	 */
	netmon->frame_table_size = 0;
	netmon->frame_table = NULL;

	/*
	 * Get the offset of the frame index table.
	 */
	frame_table_offset = pletoh32(&hdr.frametableoffset);

	/*
	 * It appears that some NetMon 2.x files don't have the
	 * first packet starting exactly 128 bytes into the file.
	 *
	 * Furthermore, it also appears that there are "holes" in
	 * the file, i.e. frame N+1 doesn't always follow immediately
	 * after frame N.
	 *
	 * Therefore, we must read the frame table, and use the offsets
	 * in it as the offsets of the frames.
	 */
	frame_table_length = pletoh32(&hdr.frametablelength);
	frame_table_size = frame_table_length / (guint32)sizeof (guint32);
	if ((frame_table_size * sizeof (guint32)) != frame_table_length) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: frame table length is %u, which is not a multiple of the size of an entry",
		    frame_table_length);
		return -1;
	}
	if (frame_table_size == 0) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: frame table length is %u, which means it's less than one entry in size",
		    frame_table_length);
		return -1;
	}
	/*
	 * XXX - clamp the size of the frame table, so that we don't
	 * attempt to allocate a huge frame table and fail.
	 *
	 * Given that file offsets in the frame table are 32-bit,
	 * a NetMon file cannot be bigger than 2^32 bytes.
	 * Given that a NetMon 1.x-format packet header is 8 bytes,
	 * that means a NetMon file cannot have more than
	 * 512*2^20 packets.  We'll pick that as the limit for
	 * now; it's 1/8th of a 32-bit address space, which is
	 * probably not going to exhaust the address space all by
	 * itself, and probably won't exhaust the backing store.
	 */
	if (frame_table_size > 512*1024*1024) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: frame table length is %u, which is larger than we support",
		    frame_table_length);
		return -1;
	}
	if (file_seek(wth->fh, frame_table_offset, SEEK_SET, err) == -1) {
		return -1;
	}
	frame_table = (guint32 *)g_try_malloc(frame_table_length);
	if (frame_table_length != 0 && frame_table == NULL) {
		*err = ENOMEM;	/* we assume we're out of memory */
		return -1;
	}
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(frame_table, frame_table_length, wth->fh);
	if ((guint32)bytes_read != frame_table_length) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		g_free(frame_table);
		return -1;
	}
	netmon->frame_table_size = frame_table_size;
	netmon->frame_table = frame_table;

#ifdef WORDS_BIGENDIAN
	/*
	 * OK, now byte-swap the frame table.
	 */
	for (i = 0; i < frame_table_size; i++)
		frame_table[i] = pletoh32(&frame_table[i]);
#endif

	/* Set up to start reading at the first frame. */
	netmon->current_frame = 0;
	switch (netmon->version_major) {

	case 1:
		/*
		 * Version 1.x of the file format supports
		 * millisecond precision.
		 */
		wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
		break;

	case 2:
		/*
		 * Version 1.x of the file format supports
		 * 100-nanosecond precision; we don't
		 * currently support that, so say
		 * "nanosecond precision" for now.
		 */
		wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
		break;
	}
	return 1;
}
Example #17
0
static process_record_retval
netmon_process_record(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	netmon_t *netmon = (netmon_t *)wth->priv;
	int	hdr_size = 0;
	union {
		struct netmonrec_1_x_hdr hdr_1_x;
		struct netmonrec_2_x_hdr hdr_2_x;
	}	hdr;
	int	bytes_read;
	gint64	delta = 0;	/* signed - frame times can be before the nominal start */
	gint64	t;
	time_t	secs;
	int	nsecs;
	guint32	packet_size = 0;
	guint32 orig_size = 0;
	int	trlr_size;
	union {
		struct netmonrec_2_1_trlr trlr_2_1;
		struct netmonrec_2_2_trlr trlr_2_2;
		struct netmonrec_2_3_trlr trlr_2_3;
	}	trlr;
	guint16 network;
	int	pkt_encap;

	/* Read record header. */
	switch (netmon->version_major) {

	case 1:
		hdr_size = sizeof (struct netmonrec_1_x_hdr);
		break;

	case 2:
		hdr_size = sizeof (struct netmonrec_2_x_hdr);
		break;
	}
	errno = WTAP_ERR_CANT_READ;

	bytes_read = file_read(&hdr, hdr_size, fh);
	if (bytes_read != hdr_size) {
		*err = file_error(fh, err_info);
		if (*err == 0 && bytes_read != 0) {
			*err = WTAP_ERR_SHORT_READ;
		}
		return FAILURE;
	}

	switch (netmon->version_major) {

	case 1:
		orig_size = pletoh16(&hdr.hdr_1_x.orig_len);
		packet_size = pletoh16(&hdr.hdr_1_x.incl_len);
		break;

	case 2:
		orig_size = pletoh32(&hdr.hdr_2_x.orig_len);
		packet_size = pletoh32(&hdr.hdr_2_x.incl_len);
		break;
	}
	if (packet_size > WTAP_MAX_PACKET_SIZE) {
		/*
		 * Probably a corrupt capture file; don't blow up trying
		 * to allocate space for an immensely-large packet.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return FAILURE;
	}

	phdr->rec_type = REC_TYPE_PACKET;

	/*
	 * If this is an ATM packet, the first
	 * "sizeof (struct netmon_atm_hdr)" bytes have destination and
	 * source addresses (6 bytes - MAC addresses of some sort?)
	 * and the VPI and VCI; read them and generate the pseudo-header
	 * from them.
	 */
	switch (wth->file_encap) {

	case WTAP_ENCAP_ATM_PDUS:
		if (packet_size < sizeof (struct netmon_atm_hdr)) {
			/*
			 * Uh-oh, the packet isn't big enough to even
			 * have a pseudo-header.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("netmon: ATM file has a %u-byte packet, too small to have even an ATM pseudo-header",
			    packet_size);
			return FAILURE;
		}
		if (!netmon_read_atm_pseudoheader(fh, &phdr->pseudo_header,
		    err, err_info))
			return FAILURE;	/* Read error */

		/*
		 * Don't count the pseudo-header as part of the packet.
		 */
		orig_size -= (guint)sizeof (struct netmon_atm_hdr);
		packet_size -= (guint)sizeof (struct netmon_atm_hdr);
		break;

	default:
		break;
	}

	switch (netmon->version_major) {

	case 1:
		/*
		 * According to Paul Long, this offset is unsigned.
		 * It's 32 bits, so the maximum value will fit in
		 * a gint64 such as delta, even after multiplying
		 * it by 1000000.
		 *
		 * pletoh32() returns a guint32; we cast it to gint64
		 * before multiplying, so that the product doesn't
		 * overflow a guint32.
		 */
		delta = ((gint64)pletoh32(&hdr.hdr_1_x.ts_delta))*1000000;
		break;

	case 2:
		/*
		 * OK, this is weird.  Microsoft's documentation
		 * says this is in microseconds and is a 64-bit
		 * unsigned number, but it can be negative; they
		 * say what appears to amount to "treat it as an
		 * unsigned number, multiply it by 10, and then
		 * interpret the resulting 64-bit quantity as a
		 * signed number".  That operation can turn a
		 * value with the uppermost bit 0 to a value with
		 * the uppermost bit 1, hence turning a large
		 * positive number-of-microseconds into a small
		 * negative number-of-100-nanosecond-increments.
		 */
		delta = pletoh64(&hdr.hdr_2_x.ts_delta)*10;

		/*
		 * OK, it's now a signed value in 100-nanosecond
		 * units.  Now convert it to nanosecond units.
		 */
		delta *= 100;
		break;
	}
	secs = 0;
	t = netmon->start_nsecs + delta;
	while (t < 0) {
		/*
		 * Propagate a borrow into the seconds.
		 * The seconds is a time_t, and can be < 0
		 * (unlikely, as Windows didn't exist before
		 * January 1, 1970, 00:00:00 UTC), while the
		 * nanoseconds should be positive, as in
		 * "nanoseconds since the instant of time
		 * represented by the seconds".
		 *
		 * We do not want t to be negative, as, according
		 * to the C90 standard, "if either operand [of /
		 * or %] is negative, whether the result of the
		 * / operator is the largest integer less than or
		 * equal to the algebraic quotient or the smallest
		 * greater than or equal to the algebraic quotient
		 * is implementation-defined, as is the sign of
		 * the result of the % operator", and we want
		 * the result of the division and remainder
		 * operations to be the same on all platforms.
		 */
		t += 1000000000;
		secs--;
	}
	secs += (time_t)(t/1000000000);
	nsecs = (int)(t%1000000000);
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	phdr->ts.secs = netmon->start_secs + secs;
	phdr->ts.nsecs = nsecs;
	phdr->caplen = packet_size;
	phdr->len = orig_size;

	/*
	 * Read the packet data.
	 */
	if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
		return FAILURE;

	/*
	 * For version 2.1 and later, there's additional information
	 * after the frame data.
	 */
	if ((netmon->version_major == 2 && netmon->version_minor >= 1) ||
	    netmon->version_major > 2) {
		if (netmon->version_major > 2) {
			/*
			 * Asssume 2.3 format, for now.
			 */
			trlr_size = (int)sizeof (struct netmonrec_2_3_trlr);
		} else {
			switch (netmon->version_minor) {

			case 1:
				trlr_size = (int)sizeof (struct netmonrec_2_1_trlr);
				break;

			case 2:
				trlr_size = (int)sizeof (struct netmonrec_2_2_trlr);
				break;

			default:
				trlr_size = (int)sizeof (struct netmonrec_2_3_trlr);
				break;
			}
		}

		errno = WTAP_ERR_CANT_READ;
		bytes_read = file_read(&trlr, trlr_size, fh);
		if (bytes_read != trlr_size) {
			*err = file_error(fh, err_info);
			if (*err == 0 && bytes_read != 0) {
				*err = WTAP_ERR_SHORT_READ;
			}
			return FAILURE;
		}

		network = pletoh16(trlr.trlr_2_1.network);
		if ((network & 0xF000) == NETMON_NET_PCAP_BASE) {
			/*
			 * Converted pcap file - the LINKTYPE_ value
			 * is the network value with 0xF000 masked off.
			 */
			network &= 0x0FFF;
			pkt_encap = wtap_pcap_encap_to_wtap_encap(network);
			if (pkt_encap == WTAP_ENCAP_UNKNOWN) {
				*err = WTAP_ERR_UNSUPPORTED;
				*err_info = g_strdup_printf("netmon: converted pcap network type %u unknown or unsupported",
				    network);
				return FAILURE;
			}
		} else if (network < NUM_NETMON_ENCAPS) {
			/*
			 * Regular NetMon encapsulation.
			 */
			pkt_encap = netmon_encap[network];
			if (pkt_encap == WTAP_ENCAP_UNKNOWN) {
				*err = WTAP_ERR_UNSUPPORTED;
				*err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
				    network);
				return FAILURE;
			}
		} else {
			/*
			 * Special packet type for metadata.
			 */
			switch (network) {

			case NETMON_NET_NETEVENT:
				/*
				 * Event Tracing event.
				 *
				 * http://msdn.microsoft.com/en-us/library/aa363759(VS.85).aspx
				 */
				return RETRY;

			case NETMON_NET_NETWORK_INFO_EX:
				/*
				 * List of adapters on which the capture
				 * was done.
				 */
				return RETRY;

			case NETMON_NET_PAYLOAD_HEADER:
				/*
				 * Header for a fake frame constructed
				 * by reassembly.
				 */
				return RETRY;

			case NETMON_NET_NETWORK_INFO:
				/*
				 * List of adapters on which the capture
				 * was done.
				 */
				return RETRY;

			case NETMON_NET_DNS_CACHE:
				/*
				 * List of resolved IP addresses.
				 */
				return RETRY;

			case NETMON_NET_NETMON_FILTER:
				/*
				 * NetMon capture or display filter
				 * string.
				 */
				return RETRY;

			default:
				*err = WTAP_ERR_UNSUPPORTED;
				*err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
				    network);
				return FAILURE;
			}
		}

		phdr->pkt_encap = pkt_encap;
		if (netmon->version_major > 2 || netmon->version_minor > 2) {
			guint64 d;

			d = pletoh64(trlr.trlr_2_3.utc_timestamp);

			/*
			 * Get the time as seconds and nanoseconds.
			 * and overwrite the time stamp obtained
			 * from the record header.
			 */
			if (!filetime_to_nstime(&phdr->ts, d)) {
				*err = WTAP_ERR_BAD_FILE;
				*err_info = g_strdup_printf("netmon: time stamp outside supported range");
				return FAILURE;
			}
		}
	}

	netmon_set_pseudo_header_info(phdr, buf);
	return SUCCESS;
}