Beispiel #1
0
static int vsock_addr_to_str(const address* addr, gchar *buf, int buf_len)
{
    const guint8 *addrp = (const guint8 *)addr->data;

    if(pletoh64(&addrp[0])==2){
        g_strlcpy(buf, "host", buf_len);
    } else {
        g_snprintf(buf, buf_len, "%" G_GINT64_MODIFIER "u", pletoh64(&addrp[0]));
    }

    return (int)(strlen(buf)+1);
}
Beispiel #2
0
uint64_t Tvbuff::tvb_get_letoh64(tvbuff_t *tvb,int offset)
{
    const uint8_t* ptr;
    ptr = ensure_contiguous(tvb,offset,sizeof(uint64_t));
    return pletoh64(ptr);
}
Beispiel #3
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;
}
Beispiel #4
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;
}