Exemplo n.º 1
0
/* Read IPFIX message header from file.  Return true on success.  Set *err to
 * 0 on EOF, any other value for "real" errors (EOF is ok, since return
 * value is still FALSE)
 */
static gboolean
ipfix_read_message_header(ipfix_message_header_t *pfx_hdr, FILE_T fh, int *err, gchar **err_info)
{
    if (!wtap_read_bytes_or_eof(fh, pfx_hdr, IPFIX_MSG_HDR_SIZE, err, err_info))
        return FALSE;

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

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

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

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

    return TRUE;
}
Exemplo n.º 2
0
static gboolean hcidump_process_packet(FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct dump_hdr dh;
	int packet_size;

	if (!wtap_read_bytes_or_eof(fh, &dh, DUMP_HDR_SIZE, err, err_info))
		return FALSE;

	packet_size = GUINT16_FROM_LE(dh.len);
	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("hcidump: File has %u-byte packet, bigger than maximum of %u",
			packet_size, WTAP_MAX_PACKET_SIZE);
		return FALSE;
	}

	phdr->rec_type = REC_TYPE_PACKET;
	phdr->presence_flags = WTAP_HAS_TS;
	phdr->ts.secs = GUINT32_FROM_LE(dh.ts_sec);
	phdr->ts.nsecs = GUINT32_FROM_LE(dh.ts_usec) * 1000;
	phdr->caplen = packet_size;
	phdr->len = packet_size;

	phdr->pseudo_header.p2p.sent = (dh.in ? FALSE : TRUE);

	return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
}
Exemplo n.º 3
0
static gboolean
commview_read_header(commview_header_t *cv_hdr, FILE_T fh, int *err,
    gchar **err_info)
{
	if (!wtap_read_bytes_or_eof(fh, &cv_hdr->data_len, 2, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->source_data_len, 2, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->version, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->year, 2, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->month, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->day, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->hours, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->minutes, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->seconds, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->usecs, 4, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->flags, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->signal_level_percent, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->rate, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->band, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->channel, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->direction, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->signal_level_dbm, 1, err, err_info))
		return FALSE;
	if (!wtap_read_bytes(fh, &cv_hdr->noise_level, 1, err, err_info))
		return FALSE;

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

	return TRUE;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
static gboolean
csids_read_packet(FILE_T fh, csids_t *csids, wtap_rec *rec,
                  Buffer *buf, int *err, gchar **err_info)
{
  struct csids_header hdr;
  guint8 *pd;

  if( !wtap_read_bytes_or_eof( fh, &hdr, sizeof( struct csids_header), err, err_info ) )
    return FALSE;
  hdr.seconds = pntoh32(&hdr.seconds);
  hdr.caplen = pntoh16(&hdr.caplen);
  /*
   * The maximum value of hdr.caplen 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;
  rec->rec_header.packet_header.len = hdr.caplen;
  rec->rec_header.packet_header.caplen = hdr.caplen;
  rec->ts.secs = hdr.seconds;
  rec->ts.nsecs = 0;

  if( !wtap_read_packet_bytes( fh, buf, rec->rec_header.packet_header.caplen, err, err_info ) )
    return FALSE;

  pd = ws_buffer_start_ptr( buf );
  if( csids->byteswapped ) {
    if( rec->rec_header.packet_header.caplen >= 2 ) {
      PBSWAP16(pd);   /* the ip len */
      if( rec->rec_header.packet_header.caplen >= 4 ) {
        PBSWAP16(pd+2); /* ip id */
        if( rec->rec_header.packet_header.caplen >= 6 )
          PBSWAP16(pd+4); /* ip flags and fragoff */
      }
    }
  }

  return TRUE;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/*
 * See
 *
 *	http://www.opengroup.org/onlinepubs/9638599/apdxf.htm
 *
 * for the "dlpi.h" header file specified by The Open Group, which lists
 * the DL_ values for various protocols; Solaris 7 uses the same values.
 *
 * See
 *
 *	http://www.iana.org/assignments/snoop-datalink-types/snoop-datalink-types.xml
 *
 * for the IETF list of snoop datalink types.
 *
 * The page at
 *
 *	http://mrpink.lerc.nasa.gov/118x/support.html
 *
 * had links to modified versions of "tcpdump" and "libpcap" for SUNatm
 * DLPI support; they suggested that the 3.0 verson of SUNatm uses those
 * values.  The Wayback Machine archived that page, but not the stuff
 * to which it linked, unfortunately.
 *
 * It also has a link to "convert.c", which is a program to convert files
 * from the format written by the "atmsnoop" program that comes with the
 * SunATM package to regular "snoop" format, claims that "SunATM 2.1 claimed
 * to be DL_FDDI (don't ask why).  SunATM 3.0 claims to be DL_IPATM, which
 * is 0x12".
 *
 * It also says that "ATM Mac header is 12 bytes long.", and seems to imply
 * that in an "atmsnoop" file, the header contains 2 bytes (direction and
 * VPI?), 2 bytes of VCI, 6 bytes of something, and 2 bytes of Ethernet
 * type; if those 6 bytes are 2 bytes of DSAP, 2 bytes of LSAP, 1 byte
 * of LLC control, and 3 bytes of SNAP OUI, that'd mean that an ATM
 * pseudo-header in an "atmsnoop" file is probably 1 byte of direction,
 * 1 byte of VPI, and 2 bytes of VCI.
 *
 * The aforementioned page also has a link to some capture files from
 * "atmsnoop"; this version of "snoop.c" appears to be able to read them.
 *
 * Source to an "atmdump" package, which includes a modified version of
 * "libpcap" to handle SunATM DLPI and an ATM driver for FreeBSD, and
 * also includes "atmdump", which is a modified "tcpdump", was available
 * at
 *
 *	ftp://ftp.cs.ndsu.nodak.edu/pub/freebsd/atm/atm-bpf.tgz
 *
 * (the host name is no longer valid) and that code also indicated that
 * DL_IPATM is used, and that an ATM packet handed up from the Sun driver
 * for the Sun SBus ATM card on Solaris 2.5.1 has 1 byte of direction,
 * 1 byte of VPI, 2 bytes of VCI, and then the ATM PDU, and suggests that
 * the direction flag is 0x80 for "transmitted" (presumably meaning
 * DTE->DCE) and presumably not 0x80 for "received" (presumably meaning
 * DCE->DTE).  That code was used as the basis for the SunATM support in
 * later versions of libpcap and tcpdump, and it worked at the time the
 * development was done with the SunATM code on the system on which the
 * development was done.
 *
 * In fact, the "direction" byte appears to have some other stuff, perhaps
 * a traffic type, in the lower 7 bits, with the 8th bit indicating the
 * direction.  That appears to be the case.
 *
 * I don't know what the encapsulation of any of the other types is, so I
 * leave them all as WTAP_ENCAP_UNKNOWN, except for those for which Brian
 * Ginsbach has supplied information about the way UNICOS/mp uses them.
 * I also don't know whether "snoop" can handle any of them (it presumably
 * can't handle ATM, otherwise Sun wouldn't have supplied "atmsnoop"; even
 * if it can't, this may be useful reference information for anybody doing
 * code to use DLPI to do raw packet captures on those network types.
 *
 *	http://web.archive.org/web/20010906213807/http://www.shomiti.com/support/TNCapFileFormat.htm
 *
 * gives information on Shomiti's mutant flavor of snoop.  For some unknown
 * reason, they decided not to just Go With The DLPI Flow, and instead used
 * the types unspecified in RFC 1461 for their own nefarious purposes, such
 * as distinguishing 10MB from 100MB from 1000MB Ethernet and distinguishing
 * 4MB from 16MB Token Ring, and distinguishing both of them from the
 * "Shomiti" versions of same.
 */
wtap_open_return_val snoop_open(wtap *wth, int *err, gchar **err_info)
{
	char magic[sizeof snoop_magic];
	struct snoop_hdr hdr;
	struct snooprec_hdr rec_hdr;
	guint padbytes;
	gboolean is_shomiti;
	static const int snoop_encap[] = {
		WTAP_ENCAP_ETHERNET,	/* IEEE 802.3 */
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.4 Token Bus */
		WTAP_ENCAP_TOKEN_RING,
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.6 Metro Net */
		WTAP_ENCAP_ETHERNET,
		WTAP_ENCAP_UNKNOWN,	/* HDLC */
		WTAP_ENCAP_UNKNOWN,	/* Character Synchronous, e.g. bisync */
		WTAP_ENCAP_UNKNOWN,	/* IBM Channel-to-Channel */
		WTAP_ENCAP_FDDI_BITSWAPPED,
		WTAP_ENCAP_NULL,	/* Other */
		WTAP_ENCAP_UNKNOWN,	/* Frame Relay LAPF */
		WTAP_ENCAP_UNKNOWN,	/* Multi-protocol over Frame Relay */
		WTAP_ENCAP_UNKNOWN,	/* Character Async (e.g., SLIP and PPP?) */
		WTAP_ENCAP_UNKNOWN,	/* X.25 Classical IP */
		WTAP_ENCAP_NULL,	/* software loopback */
		WTAP_ENCAP_UNKNOWN,	/* not defined in "dlpi.h" */
		WTAP_ENCAP_IP_OVER_FC,	/* Fibre Channel */
		WTAP_ENCAP_UNKNOWN,	/* ATM */
		WTAP_ENCAP_ATM_PDUS,	/* ATM Classical IP */
		WTAP_ENCAP_UNKNOWN,	/* X.25 LAPB */
		WTAP_ENCAP_UNKNOWN,	/* ISDN */
		WTAP_ENCAP_UNKNOWN,	/* HIPPI */
		WTAP_ENCAP_UNKNOWN,	/* 100VG-AnyLAN Ethernet */
		WTAP_ENCAP_UNKNOWN,	/* 100VG-AnyLAN Token Ring */
		WTAP_ENCAP_UNKNOWN,	/* "ISO 8802/3 and Ethernet" */
		WTAP_ENCAP_UNKNOWN,	/* 100BaseT (but that's just Ethernet) */
		WTAP_ENCAP_IP_OVER_IB,	/* Infiniband */
	};
	#define NUM_SNOOP_ENCAPS (sizeof snoop_encap / sizeof snoop_encap[0])
	#define SNOOP_PRIVATE_BIT 0x80000000
	static const int snoop_private_encap[] = {
		WTAP_ENCAP_UNKNOWN,	/* Not Used */
		WTAP_ENCAP_UNKNOWN,	/* IPv4 Tunnel Link */
		WTAP_ENCAP_UNKNOWN,	/* IPv6 Tunnel Link */
		WTAP_ENCAP_UNKNOWN,	/* Virtual network interface */
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.11 */
		WTAP_ENCAP_IPNET,	/* ipnet(7D) link */
		WTAP_ENCAP_UNKNOWN,	/* IPMP stub interface */
		WTAP_ENCAP_UNKNOWN,	/* 6to4 Tunnel Link */
	};
	#define NUM_SNOOP_PRIVATE_ENCAPS (sizeof snoop_private_encap / sizeof snoop_private_encap[0])
	static const int shomiti_encap[] = {
		WTAP_ENCAP_ETHERNET,	/* IEEE 802.3 */
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.4 Token Bus */
		WTAP_ENCAP_TOKEN_RING,
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.6 Metro Net */
		WTAP_ENCAP_ETHERNET,
		WTAP_ENCAP_UNKNOWN,	/* HDLC */
		WTAP_ENCAP_UNKNOWN,	/* Character Synchronous, e.g. bisync */
		WTAP_ENCAP_UNKNOWN,	/* IBM Channel-to-Channel */
		WTAP_ENCAP_FDDI_BITSWAPPED,
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_ETHERNET,	/* Fast Ethernet */
		WTAP_ENCAP_TOKEN_RING,	/* 4MB 802.5 token ring */
		WTAP_ENCAP_ETHERNET,	/* Gigabit Ethernet */
		WTAP_ENCAP_TOKEN_RING,	/* "IEEE 802.5 Shomiti" */
		WTAP_ENCAP_TOKEN_RING,	/* "4MB IEEE 802.5 Shomiti" */
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_IEEE_802_11_WITH_RADIO, /* IEEE 802.11 with Radio Header */
		WTAP_ENCAP_ETHERNET,	/* 10 Gigabit Ethernet */
	};
	#define NUM_SHOMITI_ENCAPS (sizeof shomiti_encap / sizeof shomiti_encap[0])
	int file_encap;
	gint64 saved_offset;

	/* Read in the string that should be at the start of a "snoop" 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;
	}

	if (memcmp(magic, snoop_magic, sizeof snoop_magic) != 0) {
		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;

	/*
	 * Make sure it's a version we support.
	 */
	hdr.version = g_ntohl(hdr.version);
	switch (hdr.version) {

	case 2:		/* Solaris 2.x and later snoop, and Shomiti
			   Surveyor prior to 3.0, or 3.0 and later
			   with NDIS card */
	case 3:		/* Surveyor 3.0 and later, with Shomiti CMM2 hardware */
	case 4:		/* Surveyor 3.0 and later, with Shomiti GAM hardware */
	case 5:		/* Surveyor 3.0 and later, with Shomiti THG hardware */
		break;

	default:
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("snoop: version %u unsupported", hdr.version);
		return WTAP_OPEN_ERROR;
	}

	/*
	 * Oh, this is lovely.
	 *
	 * I suppose Shomiti could give a bunch of lawyerly noise about
	 * how "well, RFC 1761 said they were unassigned, and that's
	 * the standard, not the DLPI header file, so it's perfectly OK
	 * for us to use them, blah blah blah", but it's still irritating
	 * as hell that they used the unassigned-in-RFC-1761 values for
	 * their own purposes - especially given that Sun also used
	 * one of them in atmsnoop.
	 *
	 * We can't determine whether it's a Shomiti capture based on
	 * the version number, as, according to their documentation on
	 * their capture file format, Shomiti uses a version number of 2
	 * if the data "was captured using an NDIS card", which presumably
	 * means "captured with an ordinary boring network card via NDIS"
	 * as opposed to "captured with our whizzo special capture
	 * hardware".
	 *
	 * The only way I can see to determine that is to check how much
	 * padding there is in the first packet - if there's enough
	 * padding for a Shomiti trailer, it's probably a Shomiti
	 * capture, and otherwise, it's probably from Snoop.
	 */

	/*
	 * Start out assuming it's not a Shomiti capture.
	 */
	is_shomiti = FALSE;

	/* Read first record header. */
	saved_offset = file_tell(wth->fh);
	if (!wtap_read_bytes_or_eof(wth->fh, &rec_hdr, sizeof rec_hdr, err, err_info)) {
		if (*err != 0)
			return WTAP_OPEN_ERROR;

		/*
		 * The file ends after the record header, which means this
		 * is a capture with no packets.
		 *
		 * We assume it's a snoop file; the actual type of file is
		 * irrelevant, as there are no records in it, and thus no
		 * extra information if it's a Shomiti capture, and no
		 * link-layer headers whose type we have to know, and no
		 * Ethernet frames that might have an FCS.
		 */
	} else {
		/*
		 * Compute the number of bytes of padding in the
		 * record.  If it's at least the size of a Shomiti
		 * trailer record, we assume this is a Shomiti
		 * capture.  (Some atmsnoop captures appear
		 * to have 4 bytes of padding, and at least one
		 * snoop capture appears to have 6 bytes of padding;
		 * the Shomiti header is larger than either of those.)
		 */
		if (g_ntohl(rec_hdr.rec_len) >
		    (sizeof rec_hdr + g_ntohl(rec_hdr.incl_len))) {
			/*
			 * Well, we have padding; how much?
			 */
			padbytes = g_ntohl(rec_hdr.rec_len) -
			    ((guint)sizeof rec_hdr + g_ntohl(rec_hdr.incl_len));

			/*
			 * Is it at least the size of a Shomiti trailer?
			 */
			is_shomiti =
			    (padbytes >= sizeof (struct shomiti_trailer));
		}
	}

	/*
	 * Seek back to the beginning of the first record.
	 */
	if (file_seek(wth->fh, saved_offset, SEEK_SET, err) == -1)
		return WTAP_OPEN_ERROR;

	hdr.network = g_ntohl(hdr.network);
	if (is_shomiti) {
		if (hdr.network >= NUM_SHOMITI_ENCAPS
		    || shomiti_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) {
			*err = WTAP_ERR_UNSUPPORTED;
			*err_info = g_strdup_printf("snoop: Shomiti network type %u unknown or unsupported",
			    hdr.network);
			return WTAP_OPEN_ERROR;
		}
		file_encap = shomiti_encap[hdr.network];

		/* This is a Shomiti file */
		wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SHOMITI;
	} else if (hdr.network & SNOOP_PRIVATE_BIT) {
		if ((hdr.network^SNOOP_PRIVATE_BIT) >= NUM_SNOOP_PRIVATE_ENCAPS
		    || snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT] == WTAP_ENCAP_UNKNOWN) {
			*err = WTAP_ERR_UNSUPPORTED;
			*err_info = g_strdup_printf("snoop: private network type %u unknown or unsupported",
			    hdr.network);
			return WTAP_OPEN_ERROR;
		}
		file_encap = snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT];

		/* This is a snoop file */
		wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SNOOP;
	} else {
		if (hdr.network >= NUM_SNOOP_ENCAPS
		    || snoop_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) {
			*err = WTAP_ERR_UNSUPPORTED;
			*err_info = g_strdup_printf("snoop: network type %u unknown or unsupported",
			    hdr.network);
			return WTAP_OPEN_ERROR;
		}
		file_encap = snoop_encap[hdr.network];

		/* This is a snoop file */
		wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SNOOP;
	}

	/*
	 * We don't currently use the extra information in Shomiti
	 * records, so we use the same routines to read snoop and
	 * Shomiti files.
	 */
	wth->subtype_read = snoop_read;
	wth->subtype_seek_read = snoop_seek_read;
	wth->file_encap = file_encap;
	wth->snapshot_length = 0;	/* not available in header */
	wth->file_tsprec = WTAP_TSPREC_USEC;
	return WTAP_OPEN_MINE;
}
Exemplo n.º 8
0
static int
snoop_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct snooprec_hdr hdr;
	guint32 rec_size;
	guint32	packet_size;
	guint32 orig_size;
	int header_size;

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

	rec_size = g_ntohl(hdr.rec_len);
	orig_size = g_ntohl(hdr.orig_len);
	packet_size = g_ntohl(hdr.incl_len);
	if (orig_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("snoop: File has %u-byte original length, bigger than maximum of %u",
		    orig_size, WTAP_MAX_PACKET_SIZE);
		return -1;
	}
	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("snoop: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return -1;
	}
	if (packet_size > rec_size) {
		/*
		 * Probably a corrupt capture file.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("snoop: File has %u-byte packet, bigger than record size %u",
		    packet_size, rec_size);
		return -1;
	}

	switch (wth->file_encap) {

	case WTAP_ENCAP_ATM_PDUS:
		/*
		 * This is an ATM packet, so the first four bytes are
		 * the direction of the packet (transmit/receive), the
		 * VPI, and the VCI; read them and generate the
		 * pseudo-header from them.
		 */
		if (packet_size < sizeof (struct snoop_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("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header",
			    packet_size);
			return -1;
		}
		if (!snoop_read_atm_pseudoheader(fh, &phdr->pseudo_header,
		    err, err_info))
			return -1;	/* Read error */

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

	case WTAP_ENCAP_ETHERNET:
		/*
		 * If this is a snoop file, we assume there's no FCS in
		 * this frame; if this is a Shomit file, we assume there
		 * is.  (XXX - or should we treat it a "maybe"?)
		 */
		if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_SHOMITI)
			phdr->pseudo_header.eth.fcs_len = 4;
		else
			phdr->pseudo_header.eth.fcs_len = 0;
		break;

	case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
		if (packet_size < sizeof (shomiti_wireless_header)) {
			/*
			 * Uh-oh, the packet isn't big enough to even
			 * have a pseudo-header.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("snoop: Shomiti wireless file has a %u-byte packet, too small to have even a wireless pseudo-header",
			    packet_size);
			return -1;
		}
		if (!snoop_read_shomiti_wireless_pseudoheader(fh,
		    &phdr->pseudo_header, err, err_info, &header_size))
			return -1;	/* Read error */

		/*
		 * Don't count the pseudo-header as part of the packet.
		 */
		rec_size -= header_size;
		orig_size -= header_size;
		packet_size -= header_size;
		break;
	}

	phdr->rec_type = REC_TYPE_PACKET;
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	phdr->ts.secs = g_ntohl(hdr.ts_sec);
	phdr->ts.nsecs = g_ntohl(hdr.ts_usec) * 1000;
	phdr->caplen = packet_size;
	phdr->len = orig_size;

	if (rec_size < (sizeof hdr + packet_size)) {
		/*
		 * What, *negative* padding?  Bogus.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("snoop: File has %u-byte record with packet size of %u",
		    rec_size, packet_size);
		return -1;
	}

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

	/*
	 * If this is ATM LANE traffic, try to guess what type of LANE
	 * traffic it is based on the packet contents.
	 */
	if (wth->file_encap == WTAP_ENCAP_ATM_PDUS &&
	    phdr->pseudo_header.atm.type == TRAF_LANE) {
		atm_guess_lane_type(phdr, ws_buffer_start_ptr(buf));
	}

	return rec_size - ((guint)sizeof hdr + packet_size);
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
/* Read the header of the next packet.

   Return FALSE on an error, TRUE on success. */
static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
    struct pcaprec_ss990915_hdr *hdr)
{
	int bytes_to_read;
	guint32 temp;
	libpcap_t *libpcap;

	switch (wth->file_type_subtype) {

	case WTAP_FILE_TYPE_SUBTYPE_PCAP:
	case WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX:
	case WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC:
		bytes_to_read = sizeof (struct pcaprec_hdr);
		break;

	case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417:
	case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029:
		bytes_to_read = sizeof (struct pcaprec_modified_hdr);
		break;

	case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915:
		bytes_to_read = sizeof (struct pcaprec_ss990915_hdr);
		break;

	case WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA:
		bytes_to_read = sizeof (struct pcaprec_nokia_hdr);
		break;

	default:
		g_assert_not_reached();
		bytes_to_read = 0;
	}
	if (!wtap_read_bytes_or_eof(fh, hdr, bytes_to_read, err, err_info))
		return FALSE;

	libpcap = (libpcap_t *)wth->priv;
	if (libpcap->byte_swapped) {
		/* Byte-swap the record header fields. */
		hdr->hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr->hdr.ts_sec);
		hdr->hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr->hdr.ts_usec);
		hdr->hdr.incl_len = GUINT32_SWAP_LE_BE(hdr->hdr.incl_len);
		hdr->hdr.orig_len = GUINT32_SWAP_LE_BE(hdr->hdr.orig_len);
	}

	/* Swap the "incl_len" and "orig_len" fields, if necessary. */
	switch (libpcap->lengths_swapped) {

	case NOT_SWAPPED:
		break;

	case MAYBE_SWAPPED:
		if (hdr->hdr.incl_len <= hdr->hdr.orig_len) {
			/*
			 * The captured length is <= the actual length,
			 * so presumably they weren't swapped.
			 */
			break;
		}
		/* FALLTHROUGH */

	case SWAPPED:
		temp = hdr->hdr.orig_len;
		hdr->hdr.orig_len = hdr->hdr.incl_len;
		hdr->hdr.incl_len = temp;
		break;
	}

	return TRUE;
}
Exemplo n.º 12
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);
}
Exemplo n.º 13
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);
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
0
wtap_open_return_val nettl_open(wtap *wth, int *err, gchar **err_info)
{
    struct nettl_file_hdr file_hdr;
    guint16 dummy[2];
    int subsys;
    nettl_t *nettl;

    memset(&file_hdr, 0, sizeof(file_hdr));

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

    if (memcmp(file_hdr.magic, nettl_magic_hpux9, MAGIC_SIZE) &&
        memcmp(file_hdr.magic, nettl_magic_hpux10, MAGIC_SIZE)) {
        return WTAP_OPEN_NOT_MINE;
    }

    /* Read the rest of the file header */
    if (!wtap_read_bytes(wth->fh, file_hdr.file_name, FILE_HDR_SIZE - MAGIC_SIZE,
                         err, err_info))
        return WTAP_OPEN_ERROR;

    /* This is an nettl file */
    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETTL;
    nettl = g_new(nettl_t,1);
    wth->priv = (void *)nettl;
    if (file_hdr.os_vers[2] == '1' && file_hdr.os_vers[3] == '1')
        nettl->is_hpux_11 = TRUE;
    else
        nettl->is_hpux_11 = FALSE;
    wth->subtype_read = nettl_read;
    wth->subtype_seek_read = nettl_seek_read;
    wth->snapshot_length = 0;   /* not available */

    /* read the first header to take a guess at the file encap */
    if (!wtap_read_bytes_or_eof(wth->fh, dummy, 4, err, err_info)) {
        if (*err == 0) {
            /* EOF, so no records */
            return WTAP_OPEN_NOT_MINE;
        }
        return WTAP_OPEN_ERROR;
    }

    subsys = g_ntohs(dummy[1]);
    switch (subsys) {
        case NETTL_SUBSYS_HPPB_FDDI :
        case NETTL_SUBSYS_EISA_FDDI :
        case NETTL_SUBSYS_PCI_FDDI :
        case NETTL_SUBSYS_HSC_FDDI :
                wth->file_encap = WTAP_ENCAP_NETTL_FDDI;
                break;
        case NETTL_SUBSYS_TOKEN :
        case NETTL_SUBSYS_PCI_TR :
                wth->file_encap = WTAP_ENCAP_NETTL_TOKEN_RING;
                break;
        case NETTL_SUBSYS_NS_LS_IP :
        case NETTL_SUBSYS_NS_LS_LOOPBACK :
        case NETTL_SUBSYS_NS_LS_TCP :
        case NETTL_SUBSYS_NS_LS_UDP :
        case NETTL_SUBSYS_NS_LS_IPV6 :
                wth->file_encap = WTAP_ENCAP_NETTL_RAW_IP;
                break;
        case NETTL_SUBSYS_NS_LS_ICMP :
                wth->file_encap = WTAP_ENCAP_NETTL_RAW_ICMP;
                break;
        case NETTL_SUBSYS_NS_LS_ICMPV6 :
                wth->file_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6;
                break;
        case NETTL_SUBSYS_NS_LS_TELNET :
                wth->file_encap = WTAP_ENCAP_NETTL_RAW_TELNET;
                break;
        default:
                /* If this assumption is bad, the read will catch it */
                wth->file_encap = WTAP_ENCAP_NETTL_ETHERNET;
    }

    if (file_seek(wth->fh, FILE_HDR_SIZE, SEEK_SET, err) == -1) {
        return WTAP_OPEN_ERROR;
    }
    wth->file_tsprec = WTAP_TSPREC_USEC;

    return WTAP_OPEN_MINE;
}
Exemplo n.º 16
0
static int peekclassic_read_packet_v7(wtap *wth, FILE_T fh,
    struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
	guint8 ep_pkt[PEEKCLASSIC_V7_PKT_SIZE];
#if 0
	guint16 protoNum;
#endif
	guint16 length;
	guint16 sliceLength;
#if 0
	guint8  flags;
#endif
	guint8  status;
	guint64 timestamp;
	time_t tsecs;
	guint32 tusecs;
	guint8 radio_info[RADIO_INFO_SIZE];

	if (!wtap_read_bytes_or_eof(fh, ep_pkt, sizeof(ep_pkt), err, err_info))
		return -1;

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

	/* force sliceLength to be the actual length of the packet */
	if (0 == sliceLength) {
		sliceLength = length;
	}
	/*
	 * The maximum value of sliceLength and length are 65535, which
	 * are less than WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't
	 * need to check them.
	 */

	/* fill in packet header values */
	phdr->rec_type = REC_TYPE_PACKET;
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	tsecs = (time_t) (timestamp/1000000);
	tusecs = (guint32) (timestamp - tsecs*1000000);
	phdr->ts.secs  = tsecs - mac2unix;
	phdr->ts.nsecs = tusecs * 1000;
	phdr->len    = length;
	phdr->caplen = sliceLength;

	switch (wth->file_encap) {

	case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
		memset(&phdr->pseudo_header.ieee_802_11, 0, sizeof(phdr->pseudo_header.ieee_802_11));
		phdr->pseudo_header.ieee_802_11.fcs_len = 0;		/* no FCS */
		phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
		phdr->pseudo_header.ieee_802_11.datapad = FALSE;
		phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;

		/*
		 * Now process the radio information pseudo-header.
		 * It's a 4-byte pseudo-header, consisting of:
		 *
		 *   1 byte of data rate, in units of 500 kb/s;
		 *
		 *   1 byte of channel number;
		 *
		 *   1 byte of signal strength as a percentage of
		 *   the maximum, i.e. (RXVECTOR RSSI/RXVECTOR RSSI_Max)*100,
		 *   or, at least, that's what I infer it is, given what
		 *   the WildPackets note "Converting Signal Strength
		 *   Percentage to dBm Values" says (it also says that
		 *   the conversion the percentage to a dBm value is
		 *   an adapter-dependent process, so, as we don't know
		 *   what type of adapter was used to do the capture,
		 *   we can't do the conversion);
		 *
		 *   1 byte of unknown content (padding?).
		 */
		if (phdr->len < RADIO_INFO_SIZE || phdr->caplen < RADIO_INFO_SIZE) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("peekclassic: 802.11 packet has length < 4");
			return -1;
		}
		phdr->len -= RADIO_INFO_SIZE;
		phdr->caplen -= RADIO_INFO_SIZE;
		sliceLength -= RADIO_INFO_SIZE;

		/* read the pseudo-header */
		if (!wtap_read_bytes(fh, radio_info, RADIO_INFO_SIZE, err, err_info))
			return -1;

		phdr->pseudo_header.ieee_802_11.has_data_rate = TRUE;
		phdr->pseudo_header.ieee_802_11.data_rate = radio_info[0];

		phdr->pseudo_header.ieee_802_11.has_channel = TRUE;
		phdr->pseudo_header.ieee_802_11.channel = radio_info[1];

		phdr->pseudo_header.ieee_802_11.has_signal_percent = TRUE;
		phdr->pseudo_header.ieee_802_11.signal_percent = radio_info[2];

		/*
		 * The last 4 bytes appear to be random data - the length
		 * might include the FCS - so we reduce the length by 4.
		 *
		 * Or maybe this is just the same kind of random 4 bytes
		 * of junk at the end you get in Wireless Sniffer
		 * captures.
		 */
		if (phdr->len < 4 || phdr->caplen < 4) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("peekclassic: 802.11 packet has length < 8");
			return -1;
		}
		phdr->len -= 4;
		phdr->caplen -= 4;
		break;

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

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

	return sliceLength;
}
Exemplo n.º 17
0
static gboolean
nettl_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf,
                int *err, gchar **err_info)
{
    union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
    nettl_t *nettl = (nettl_t *)wth->priv;
    gboolean fddihack = FALSE;
    struct nettlrec_hdr rec_hdr;
    guint16 hdr_len;
    struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr;
    guint32 length, caplen;
    int subsys;
    guint padlen;
    int datalen;
    guint8 dummyc[16];
    int bytes_to_read;
    guint8 *pd;

    if (!wtap_read_bytes_or_eof(fh, &rec_hdr.hdr_len, sizeof rec_hdr.hdr_len,
                                err, err_info))
        return FALSE;
    hdr_len = g_ntohs(rec_hdr.hdr_len);
    if (hdr_len < NETTL_REC_HDR_LEN) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("nettl: record header length %u too short",
            hdr_len);
        return FALSE;
    }
    if (!wtap_read_bytes(fh, &rec_hdr.subsys, NETTL_REC_HDR_LEN - 2,
                         err, err_info))
        return FALSE;
    subsys = g_ntohs(rec_hdr.subsys);
    hdr_len -= NETTL_REC_HDR_LEN;
    /* Skip the rest of the header. */
    if (!wtap_read_bytes(fh, NULL, hdr_len, err, err_info))
        return FALSE;

    if ( (pntoh32(&rec_hdr.kind) & NETTL_HDR_PDU_MASK) == 0 ) {
        /* not actually a data packet (PDU) trace record */
        rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_IP;
        length = pntoh32(&rec_hdr.length);
        caplen = pntoh32(&rec_hdr.caplen);
        padlen = 0;
    } else switch (subsys) {
        case NETTL_SUBSYS_LAN100 :
        case NETTL_SUBSYS_EISA100BT :
        case NETTL_SUBSYS_BASE100 :
        case NETTL_SUBSYS_GSC100BT :
        case NETTL_SUBSYS_PCI100BT :
        case NETTL_SUBSYS_SPP100BT :
        case NETTL_SUBSYS_100VG :
        case NETTL_SUBSYS_GELAN :
        case NETTL_SUBSYS_BTLAN :
        case NETTL_SUBSYS_INTL100 :
        case NETTL_SUBSYS_IGELAN :
        case NETTL_SUBSYS_IETHER :
        case NETTL_SUBSYS_IXGBE :
        case NETTL_SUBSYS_HSSN :
        case NETTL_SUBSYS_IGSSN :
        case NETTL_SUBSYS_ICXGBE :
        case NETTL_SUBSYS_IEXGBE :
        case NETTL_SUBSYS_IOCXGBE :
        case NETTL_SUBSYS_IQXGBE :
        case NETTL_SUBSYS_HPPB_FDDI :
        case NETTL_SUBSYS_EISA_FDDI :
        case NETTL_SUBSYS_PCI_FDDI :
        case NETTL_SUBSYS_HSC_FDDI :
        case NETTL_SUBSYS_TOKEN :
        case NETTL_SUBSYS_PCI_TR :
        case NETTL_SUBSYS_NS_LS_IP :
        case NETTL_SUBSYS_NS_LS_LOOPBACK :
        case NETTL_SUBSYS_NS_LS_TCP :
        case NETTL_SUBSYS_NS_LS_UDP :
        case NETTL_SUBSYS_HP_APAPORT :
        case NETTL_SUBSYS_HP_APALACP :
        case NETTL_SUBSYS_NS_LS_IPV6 :
        case NETTL_SUBSYS_NS_LS_ICMPV6 :
        case NETTL_SUBSYS_NS_LS_ICMP :
        case NETTL_SUBSYS_NS_LS_TELNET :
        case NETTL_SUBSYS_NS_LS_SCTP :
            if( (subsys == NETTL_SUBSYS_NS_LS_IP)
             || (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK)
             || (subsys == NETTL_SUBSYS_NS_LS_UDP)
             || (subsys == NETTL_SUBSYS_NS_LS_TCP)
             || (subsys == NETTL_SUBSYS_NS_LS_SCTP)
             || (subsys == NETTL_SUBSYS_NS_LS_IPV6)) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_IP;
            } else if (subsys == NETTL_SUBSYS_NS_LS_ICMP) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMP;
            } else if (subsys == NETTL_SUBSYS_NS_LS_ICMPV6) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6;
            } else if (subsys == NETTL_SUBSYS_NS_LS_TELNET) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_TELNET;
            } else if( (subsys == NETTL_SUBSYS_HPPB_FDDI)
                    || (subsys == NETTL_SUBSYS_EISA_FDDI)
                    || (subsys == NETTL_SUBSYS_PCI_FDDI)
                    || (subsys == NETTL_SUBSYS_HSC_FDDI) ) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_FDDI;
            } else if( (subsys == NETTL_SUBSYS_PCI_TR)
                    || (subsys == NETTL_SUBSYS_TOKEN) ) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_TOKEN_RING;
            } else {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
            }

            length = pntoh32(&rec_hdr.length);
            caplen = pntoh32(&rec_hdr.caplen);

            /* HPPB FDDI has different inbound vs outbound trace records */
            if (subsys == NETTL_SUBSYS_HPPB_FDDI) {
                if (pntoh32(&rec_hdr.kind) == NETTL_HDR_PDUIN) {
                    /* inbound is very strange...
                       there are an extra 3 bytes after the DSAP and SSAP
                       for SNAP frames ???
                    */
                    fddihack=TRUE;
                    padlen = 0;
                } else {
                    /* outbound appears to have variable padding */
                    if (!wtap_read_bytes(fh, dummyc, 9, err, err_info))
                        return FALSE;
                    /* padding is usually either a total 11 or 16 bytes??? */
                    padlen = (int)dummyc[8];
                    if (!wtap_read_bytes(fh, NULL, padlen, err, err_info))
                        return FALSE;
                    padlen += 9;
                }
            } else if ( (subsys == NETTL_SUBSYS_PCI_FDDI)
                     || (subsys == NETTL_SUBSYS_EISA_FDDI)
                     || (subsys == NETTL_SUBSYS_HSC_FDDI) ) {
                /* other flavor FDDI cards have an extra 3 bytes of padding */
                if (!wtap_read_bytes(fh, NULL, 3, err, err_info))
                    return FALSE;
                padlen = 3;
            } else if (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) {
                /* LOOPBACK has an extra 26 bytes of padding */
                if (!wtap_read_bytes(fh, NULL, 26, err, err_info))
                    return FALSE;
                padlen = 26;
            } else if (subsys == NETTL_SUBSYS_NS_LS_SCTP) {
                /*
                 * SCTP 8 byte header that we will ignore...
                 * 32 bit integer defines format
                 *   1 = Log
                 *   2 = ASCII
                 *   3 = Binary (PDUs should be Binary format)
                 * 32 bit integer defines type
                 *   1 = Inbound
                 *   2 = Outbound
                 */
                if (!wtap_read_bytes(fh, NULL, 8, err, err_info))
                    return FALSE;
                padlen = 8;
            } else {
                padlen = 0;
            }
            break;

        case NETTL_SUBSYS_NS_LS_DRIVER :
            /* XXX we don't know how to identify this as ethernet frames, so
               we assume everything is. We will crash and burn for anything else */
            /* for encapsulated 100baseT we do this */
            rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
            if (!wtap_read_bytes(fh, &drv_eth_hdr, NS_LS_DRV_ETH_HDR_LEN,
                                      err, err_info))
                return FALSE;

            length = pntoh16(&drv_eth_hdr.length);
            caplen = pntoh16(&drv_eth_hdr.caplen);
            /*
             * XXX - is there a length field that would give the length
             * of this header, so that we don't have to check for
             * nettl files from HP-UX 11?
             *
             * And what are the extra two bytes?
             */
            if (nettl->is_hpux_11) {
                if (!wtap_read_bytes(fh, NULL, 2, err, err_info))
                    return FALSE;
            }
            padlen = 0;
            break;

        case NETTL_SUBSYS_SX25L2:
        case NETTL_SUBSYS_SX25L3:
            /*
             * XXX - is the 24-byte padding actually a header with
             * packet lengths, time stamps, etc., just as is the case
             * for NETTL_SUBSYS_NS_LS_DRIVER?  It might be
             *
             *    guint8        caplen[2];
             *    guint8        length[2];
             *    guint8        xxc[4];
             *    guint8        sec[4];
             *    guint8        usec[4];
             *    guint8        xxd[4];
             *
             * or something such as that - if it has 4 bytes before that
             * (making it 24 bytes), it'd be like struct
             * nettlrec_ns_ls_drv_eth_hdr but with 2 more bytes at the end.
             *
             * And is "from_dce" at xxa[0] in the nettlrec_hdr structure?
             */
            rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_X25;
            length = pntoh32(&rec_hdr.length);
            caplen = pntoh32(&rec_hdr.caplen);
            padlen = 24;        /* sizeof (struct nettlrec_sx25l2_hdr) - NETTL_REC_HDR_LEN + 4 */
            if (!wtap_read_bytes(fh, NULL, padlen, err, err_info))
                return FALSE;
            break;

        default:
            /* We're going to assume it's ethernet if we don't recognize the
               subsystem -- We'll probably spew junks and core if it isn't... */
            wth->file_encap = WTAP_ENCAP_PER_PACKET;
            rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
            length = pntoh32(&rec_hdr.length);
            caplen = pntoh32(&rec_hdr.caplen);
            padlen = 0;
            break;
    }

    if (length < padlen) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("nettl: packet length %u in record header too short, less than %u",
            length, padlen);
        return FALSE;
    }
    rec->rec_type = REC_TYPE_PACKET;
    rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    rec->rec_header.packet_header.len = length - padlen;
    if (caplen < padlen) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("nettl: captured length %u in record header too short, less than %u",
            caplen, padlen);
        return FALSE;
    }
    datalen = caplen - padlen;
    rec->rec_header.packet_header.caplen = datalen;
    rec->ts.secs = pntoh32(&rec_hdr.sec);
    rec->ts.nsecs = pntoh32(&rec_hdr.usec) * 1000;

    pseudo_header->nettl.subsys   = subsys;
    pseudo_header->nettl.devid    = pntoh32(&rec_hdr.devid);
    pseudo_header->nettl.kind     = pntoh32(&rec_hdr.kind);
    pseudo_header->nettl.pid      = pntoh32(&rec_hdr.pid);
    pseudo_header->nettl.uid      = pntoh16(&rec_hdr.uid);

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

    /*
     * Read the packet data.
     */
    ws_buffer_assure_space(buf, datalen);
    pd = ws_buffer_start_ptr(buf);
    if (fddihack) {
        /* read in FC, dest, src, DSAP and SSAP */
        bytes_to_read = 15;
        if (bytes_to_read > datalen)
            bytes_to_read = datalen;
        if (!wtap_read_bytes(fh, pd, bytes_to_read, err, err_info))
            return FALSE;
        datalen -= bytes_to_read;
        if (datalen == 0) {
            /* There's nothing past the FC, dest, src, DSAP and SSAP */
            return TRUE;
        }
        if (pd[13] == 0xAA) {
            /* it's SNAP, have to eat 3 bytes??? */
            bytes_to_read = 3;
            if (bytes_to_read > datalen)
                bytes_to_read = datalen;
            if (!wtap_read_bytes(fh, NULL, bytes_to_read, err, err_info))
                return FALSE;
            datalen -= bytes_to_read;
            if (datalen == 0) {
                /* There's nothing past the FC, dest, src, DSAP, SSAP, and 3 bytes to eat */
                return TRUE;
            }
        }
        if (!wtap_read_bytes(fh, pd + 15, datalen, err, err_info))
            return FALSE;
    } else {
        if (!wtap_read_bytes(fh, pd, datalen, err, err_info))
            return FALSE;
    }

    return TRUE;
}
Exemplo n.º 18
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);
}
Exemplo n.º 19
0
wtap_open_return_val network_instruments_open(wtap *wth, int *err, gchar **err_info)
{
    guint offset;
    capture_file_header file_header;
    guint header_offset;
    guint i;
    tlv_header tlvh;
    guint seek_increment;
    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 += (guint)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;
    }

    /* 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 + ((guint)(file_header.offset_to_first_packet_high_byte)<<16);

    if (offset > header_offset) {
        /*
         * The packet data begins before the file header ends.
         */
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("Observer: The first packet begins in the middle of the file header");
        return WTAP_OPEN_ERROR;
    }

    /* 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;

    /* process extra information */
    for (i = 0; i < file_header.number_of_information_elements; i++) {
        guint tlv_data_length;

        /*
         * Make sure reading the TLV header won't put us in the middle
         * of the packet data.
         */
        if (offset + (guint)sizeof tlvh > header_offset) {
            /*
             * We're at or past the point where the packet data begins,
             * but we have the IE header to read.
             */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("Observer: TLVs run into the first packet data");
            return WTAP_OPEN_ERROR;
        }

        /* read the TLV header */
        if (!wtap_read_bytes(wth->fh, &tlvh, sizeof tlvh, err, err_info))
            return WTAP_OPEN_ERROR;
        offset += (guint)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;
        }

        tlv_data_length = tlvh.length - (guint)sizeof tlvh;
        /*
         * Make sure reading the TLV data won't put us in the middle
         * of the packet data.
         */
        if (offset + tlv_data_length > header_offset) {
            /*
             * We're at or past the point where the packet data begins,
             * but we have the IE data to read.
             */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("Observer: TLVs run into the first packet data");
            return WTAP_OPEN_ERROR;
        }


        /* process (or skip over) the current TLV */
        switch (tlvh.type) {
        case INFORMATION_TYPE_TIME_INFO:
            if (tlvh.length != sizeof tlvh + sizeof private_state->time_format) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup_printf("Observer: bad record (time information TLV length %u != %lu)",
                    tlvh.length,
                    (unsigned long)(sizeof tlvh + sizeof private_state->time_format));
                return WTAP_OPEN_ERROR;
            }
            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 += (guint)sizeof private_state->time_format;
            break;
        default:
            tlv_data_length = tlvh.length - (guint)sizeof tlvh;
            if (tlv_data_length > 0) {
                if (!wtap_read_bytes(wth->fh, NULL, tlv_data_length, err, err_info))
                    return WTAP_OPEN_ERROR;
            }
            offset += tlv_data_length;
        }
    }

    /* get to the first packet */
    seek_increment = header_offset - offset;
    if (seek_increment != 0) {
        if (!wtap_read_bytes(wth->fh, NULL, seek_increment, err, err_info))
            return WTAP_OPEN_ERROR;
    }

    /*
     * We assume that all packets in a file have the same network type,
     * whether they're data or expert information packets, and thus
     * we can attempt to determine the network type by reading the
     * first packet.
     *
     * If that's *not* the case, we need to use WTAP_ENCAP_PER_PACKET.
     *
     * Read the packet header.  Don't assume there *is* a packet;
     * if there isn't, report that as a bad file.  (If we use
     * WTAP_ENCAP_PER_PACKET, we don't need to handle that case, as
     * we don't need to read the first packet.
     */
    if (!wtap_read_bytes_or_eof(wth->fh, &packet_header, sizeof packet_header,
                                err, err_info)) {
        if (*err == 0) {
            /*
             * EOF, so there *are* no records.
             */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("Observer: No records in the file, so we can't determine the link-layer type");
        }
        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;

    if (init_gmt_to_localtime_offset() != NULL) {
        *err = WTAP_ERR_INTERNAL;
        /*
         * XXX - we should return the error string, so the caller
         * can report the details of the internal error, but that
         * would require plugin file readers to do so for internal
         * errors as well, which could break binary compatibility;
         * we'll do that in the next release.
         */
        return WTAP_OPEN_ERROR;
    }

    return WTAP_OPEN_MINE;
}
Exemplo n.º 20
0
static gboolean
i4b_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    int *err, gchar **err_info)
{
	i4btrace_t *i4btrace = (i4btrace_t *)wth->priv;
	i4b_trace_hdr_t hdr;
	guint32 length;

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

	if (i4btrace->byte_swapped) {
		/*
		 * Byte-swap the header.
		 */
		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);
		hdr.count = GUINT32_SWAP_LE_BE(hdr.count);
		hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr.ts_sec);
		hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr.ts_usec);
	}

	if (hdr.length < sizeof(hdr)) {
		*err = WTAP_ERR_BAD_FILE;	/* record length < header! */
		*err_info = g_strdup_printf("i4btrace: record length %u < header length %lu",
		    hdr.length, (unsigned long)sizeof(hdr));
		return FALSE;
	}
	length = hdr.length - (guint32)sizeof(hdr);
	if (length > 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("i4btrace: File has %u-byte packet, bigger than maximum of %u",
		    length, WTAP_MAX_PACKET_SIZE_STANDARD);
		return FALSE;
	}

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

	phdr->len = length;
	phdr->caplen = length;

	phdr->ts.secs = hdr.ts_sec;
	phdr->ts.nsecs = hdr.ts_usec * 1000;

	switch (hdr.type) {

	case TRC_CH_I:
		/*
		 * XXX - what is it?  It's probably not WTAP_ENCAP_NULL,
		 * as that means it has a 4-byte AF_ type as the
		 * encapsulation header.
		 */
		phdr->pkt_encap = WTAP_ENCAP_NULL;
		break;

	case TRC_CH_D:
		/*
		 * D channel, so it's LAPD; set "p2p.sent".
		 */
		phdr->pkt_encap = WTAP_ENCAP_ISDN;
		phdr->pseudo_header.isdn.channel = 0;
		break;

	case TRC_CH_B1:
		/*
		 * B channel 1.
		 */
		phdr->pkt_encap = WTAP_ENCAP_ISDN;
		phdr->pseudo_header.isdn.channel = 1;
		break;

	case TRC_CH_B2:
		/*
		 * B channel 2.
		 */
		phdr->pkt_encap = WTAP_ENCAP_ISDN;
		phdr->pseudo_header.isdn.channel = 2;
		break;
	}

	phdr->pseudo_header.isdn.uton = (hdr.dir == FROM_TE);

	/*
	 * Read the packet data.
	 */
	return wtap_read_packet_bytes(fh, buf, length, err, err_info);
}
Exemplo n.º 21
0
static int peekclassic_read_packet_v7(wtap *wth, FILE_T fh,
                                      struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
    guint8 ep_pkt[PEEKCLASSIC_V7_PKT_SIZE];
#if 0
    guint16 protoNum;
#endif
    guint16 length;
    guint16 sliceLength;
#if 0
    guint8  flags;
#endif
    guint8  status;
    guint64 timestamp;
    time_t tsecs;
    guint32 tusecs;

    if (!wtap_read_bytes_or_eof(fh, ep_pkt, sizeof(ep_pkt), err, err_info))
        return -1;

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

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

    /* fill in packet header values */
    phdr->rec_type = REC_TYPE_PACKET;
    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    tsecs = (time_t) (timestamp/1000000);
    tusecs = (guint32) (timestamp - tsecs*1000000);
    phdr->ts.secs  = tsecs - mac2unix;
    phdr->ts.nsecs = tusecs * 1000;
    phdr->len    = length;
    phdr->caplen = sliceLength;

    switch (wth->file_encap) {

    case WTAP_ENCAP_IEEE_802_11_AIROPEEK:
        phdr->pseudo_header.ieee_802_11.fcs_len = 0;		/* no FCS */
        phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
        phdr->pseudo_header.ieee_802_11.datapad = FALSE;
        phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;
        phdr->pseudo_header.ieee_802_11.presence_flags = 0;	/* not present */

        /*
         * The last 4 bytes appear to be random data - the length
         * might include the FCS - so we reduce the length by 4.
         *
         * Or maybe this is just the same kind of random 4 bytes
         * of junk at the end you get in Wireless Sniffer
         * captures.
         */
        if (phdr->len < 4 || phdr->caplen < 4) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("peekclassic: 802.11 packet has length < 4");
            return -1;
        }
        phdr->len -= 4;
        phdr->caplen -= 4;
        break;

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

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

    return sliceLength;
}
Exemplo n.º 22
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;
            }
      }
}
Exemplo n.º 23
0
static gboolean peekclassic_read_packet_v56(wtap *wth, FILE_T fh,
        struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
    peekclassic_t *peekclassic = (peekclassic_t *)wth->priv;
    guint8 ep_pkt[PEEKCLASSIC_V56_PKT_SIZE];
    guint16 length;
    guint16 sliceLength;
#if 0
    guint8  flags;
    guint8  status;
#endif
    guint32 timestamp;
#if 0
    guint16 destNum;
    guint16 srcNum;
#endif
    guint16 protoNum;
#if 0
    char    protoStr[8];
#endif
    unsigned int i;

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

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

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

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

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

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

    switch (phdr->pkt_encap) {

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

    /* read the packet data */
    return wtap_read_packet_bytes(fh, buf, sliceLength, err, err_info);
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
static int
capsa_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	capsa_t *capsa = (capsa_t *)wth->priv;
	struct capsarec_hdr capsarec_hdr;
	struct pbrec_hdr pbrec_hdr;
	guint32 rec_size;
	guint32	packet_size;
	guint32 orig_size;
	guint32 header_size;
#if 0
	guint64 timestamp;
#endif

	/* Read record header. */
	switch (capsa->format_indicator) {

	case 1:
		if (!wtap_read_bytes_or_eof(fh, &capsarec_hdr,
		    sizeof capsarec_hdr, err, err_info))
			return -1;
		rec_size = GUINT16_FROM_LE(capsarec_hdr.rec_len);
		orig_size = GUINT16_FROM_LE(capsarec_hdr.orig_len);
		packet_size = GUINT16_FROM_LE(capsarec_hdr.incl_len);
		header_size = sizeof capsarec_hdr;
#if 0
		timestamp = (((guint64)GUINT32_FROM_LE(capsarec_hdr.timestamphi))<<32) + GUINT32_FROM_LE(capsarec_hdr.timestamplo);
		/*
		 * XXX - this is not the correct time origin.
		 */
		timestamp -= G_GUINT64_CONSTANT(11644473600);
#endif

		/*
		 * OK, the rest of this is variable-length.
		 * We skip: (count1+count2)*4 bytes.
		 * XXX - what is that?  Measured statistics?
		 * Calculated statistics?
		 */
		if (!file_skip(fh, (capsarec_hdr.count1 + capsarec_hdr.count2)*4,
		    err))
			return -1;
		header_size += (capsarec_hdr.count1 + capsarec_hdr.count2)*4;
		break;

	case 2:
		if (!wtap_read_bytes_or_eof(fh, &pbrec_hdr,
		    sizeof pbrec_hdr, err, err_info))
			return -1;
		rec_size = GUINT16_FROM_LE(pbrec_hdr.rec_len);
		orig_size = GUINT16_FROM_LE(pbrec_hdr.orig_len);
		packet_size = GUINT16_FROM_LE(pbrec_hdr.incl_len);
		header_size = sizeof pbrec_hdr;
#if 0
		timestamp = (((guint64)GUINT32_FROM_LE(pbrec_hdr.timestamphi))<<32) + GUINT32_FROM_LE(pbrec_hdr.timestamplo);
		/*
		 * XXX - from the results of some conversions between
		 * Capsa format and pcap by Colasoft Packet Builder,
		 * I do not trust its conversion of time stamps (at
		 * least one of Colasoft's sample files, when
		 * converted to pcap format, has, as its time stamps,
		 * time stamps on the day after the conversion was
		 * done, which seems like more than just coincidence).
		 */
		timestamp -= G_GUINT64_CONSTANT(485946753291483);
#endif
		break;

	default:
		g_assert_not_reached();
		*err = WTAP_ERR_INTERNAL;
		return -1;
	}
	if (orig_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("capsa: File has %u-byte original length, bigger than maximum of %u",
		    orig_size, WTAP_MAX_PACKET_SIZE);
		return -1;
	}
	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("capsa: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return -1;
	}
	if (header_size + packet_size > rec_size) {
		/*
		 * Probably a corrupt capture file.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("capsa: File has %u-byte packet with %u-byte record header, bigger than record size %u",
		    packet_size, header_size, rec_size);
		return -1;
	}

	/*
	 * The "on the wire" record size always includes the CRC.
	 * If it's greater than the "captured" size by 4, then
	 * we subtract 4 from it, to reflect the way the "on the wire"
	 * record size works for other file formats.
	 */
	if (orig_size == packet_size + 4)
		orig_size = packet_size;

	/*
	 * We assume there's no FCS in this frame.
	 * XXX - is there ever one?
	 */
	phdr->pseudo_header.eth.fcs_len = 0;

	phdr->rec_type = REC_TYPE_PACKET;
	phdr->caplen = packet_size;
	phdr->len = orig_size;
#if 0
	phdr->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_TS;
	phdr->ts.secs = (time_t)(timestamp / 1000000);
	phdr->ts.nsecs = ((int)(timestamp % 1000000))*1000;
#else
	phdr->presence_flags = WTAP_HAS_CAP_LEN;
#endif

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

	return rec_size - (header_size + packet_size);
}