Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
static gboolean
csids_read_packet(FILE_T fh, csids_t *csids, struct wtap_pkthdr *phdr,
                  Buffer *buf, int *err, gchar **err_info)
{
  struct csids_header hdr;
  int bytesRead = 0;
  guint8 *pd;

  bytesRead = file_read( &hdr, sizeof( struct csids_header), fh );
  if( bytesRead != sizeof( struct csids_header) ) {
    *err = file_error( fh, err_info );
    if (*err == 0 && bytesRead != 0)
      *err = WTAP_ERR_SHORT_READ;
    return FALSE;
  }
  hdr.seconds = pntohl(&hdr.seconds);
  hdr.caplen = pntohs(&hdr.caplen);

  phdr->presence_flags = WTAP_HAS_TS;
  phdr->len = hdr.caplen;
  phdr->caplen = hdr.caplen;
  phdr->ts.secs = hdr.seconds;
  phdr->ts.nsecs = 0;

  if( !wtap_read_packet_bytes( fh, buf, phdr->caplen, err, err_info ) )
    return FALSE;

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

  return TRUE;
}
Ejemplo n.º 3
0
/* Read IPFIX message header from file and fill in the struct wtap_pkthdr
 * for the packet, and, if that succeeds, read the packet data.
 * 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(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
    ipfix_message_header_t msg_hdr;

    if (!ipfix_read_message_header(&msg_hdr, fh, err, err_info))
        return FALSE;
    /*
     * The maximum value of msg_hdr.message_length is 65535, which is
     * less than WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need
     * to check it.
     */

    phdr->rec_type = REC_TYPE_PACKET;
    phdr->presence_flags = WTAP_HAS_TS;
    phdr->len = msg_hdr.message_length;
    phdr->caplen = msg_hdr.message_length;
    phdr->ts.secs = msg_hdr.export_time_secs;
    phdr->ts.nsecs = 0;

    return wtap_read_packet_bytes(fh, buf, msg_hdr.message_length, err, err_info);
}
Ejemplo n.º 4
0
static gboolean
_5views_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
    Buffer *buf, int length, int *err, gchar **err_info)
{
	t_5VW_TimeStamped_Header TimeStamped_Header;

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

	/*
	 * Read the header.
	 */
	if (!_5views_read_header(wth, wth->random_fh, &TimeStamped_Header,
	    phdr, err, err_info))
		return FALSE;

	/*
	 * Read the packet data.
	 */
	return wtap_read_packet_bytes(wth->random_fh, buf, length,
	    err, err_info);
}
Ejemplo n.º 5
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 bytes_read, packet_size;

	bytes_read = file_read(&dh, DUMP_HDR_SIZE, fh);
	if (bytes_read != DUMP_HDR_SIZE) {
		*err = file_error(fh, err_info);
		if (*err == 0 && bytes_read != 0)
			*err = WTAP_ERR_SHORT_READ;
		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);
}
Ejemplo n.º 6
0
static gboolean
aethra_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct aethrarec_hdr hdr;

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

	if (!aethra_read_rec_header(wth, wth->random_fh, &hdr, phdr, err,
	    err_info)) {
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		return FALSE;
	}

	/*
	 * Read the packet data.
	 */
	if (!wtap_read_packet_bytes(wth->random_fh, buf, phdr->caplen, err, err_info))
		return FALSE;	/* failed */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                switch (ext_flags & EXT_FLAGS_GI) {

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

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

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

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

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

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

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

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

                switch (ext_flags & EXT_FLAGS_GI) {

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

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

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

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

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

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

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

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

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

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

    switch (wth->file_encap) {

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

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

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

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

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

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

    return skip_len;
}
Ejemplo n.º 9
0
static gboolean
libpcap_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct pcaprec_ss990915_hdr hdr;
	guint packet_size;
	guint orig_size;
	int phdr_len;
	libpcap_t *libpcap;

	if (!libpcap_read_header(wth, fh, err, err_info, &hdr))
		return FALSE;

	if (hdr.hdr.incl_len > 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;
		if (err_info != NULL) {
			*err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
			    hdr.hdr.incl_len, WTAP_MAX_PACKET_SIZE);
		}
		return FALSE;
	}

	packet_size = hdr.hdr.incl_len;
	orig_size = hdr.hdr.orig_len;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX &&
	    (wth->file_encap == WTAP_ENCAP_FDDI ||
	     wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		packet_size -= 3;
		orig_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}

	phdr_len = pcap_process_pseudo_header(fh, wth->file_type_subtype,
	    wth->file_encap, packet_size, TRUE, phdr, err, err_info);
	if (phdr_len < 0)
		return FALSE;	/* error */

	/*
	 * Don't count any pseudo-header as part of the packet.
	 */
	orig_size -= phdr_len;
	packet_size -= phdr_len;

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

	/* Update the timestamp, if not already done */
	if (wth->file_encap != WTAP_ENCAP_ERF) {
		phdr->ts.secs = hdr.hdr.ts_sec;
		if (wth->file_tsprec == WTAP_TSPREC_NSEC)
			phdr->ts.nsecs = hdr.hdr.ts_usec;
		else
			phdr->ts.nsecs = hdr.hdr.ts_usec * 1000;
	} else {
		/* Set interface ID for ERF format */
		phdr->presence_flags |= WTAP_HAS_INTERFACE_ID;
		phdr->interface_id = phdr->pseudo_header.erf.phdr.flags & 0x03;
	}
	phdr->caplen = packet_size;
	phdr->len = orig_size;

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

	libpcap = (libpcap_t *)wth->priv;
	pcap_read_post_process(wth->file_type_subtype, wth->file_encap,
	    phdr, ws_buffer_start_ptr(buf), libpcap->byte_swapped, -1);
	return TRUE;
}
Ejemplo n.º 10
0
static gboolean peekclassic_read_packet_v56(wtap *wth, FILE_T fh,
    struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
	peekclassic_t *peekclassic = (peekclassic_t *)wth->priv;
	guint8 ep_pkt[PEEKCLASSIC_V56_PKT_SIZE];
	guint16 length;
	guint16 sliceLength;
#if 0
	guint8  flags;
	guint8  status;
#endif
	guint32 timestamp;
#if 0
	guint16 destNum;
	guint16 srcNum;
#endif
	guint16 protoNum;
#if 0
	char    protoStr[8];
#endif
	unsigned int i;

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

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

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

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

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

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

	switch (phdr->pkt_encap) {

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

	/* read the packet data */
	return wtap_read_packet_bytes(fh, buf, sliceLength, err, err_info);
}
Ejemplo n.º 11
0
static gboolean
visual_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
        Buffer *buf, int *err, gchar **err_info)
{
    struct visual_read_info *visual = (struct visual_read_info *)wth->priv;
    struct visual_pkt_hdr vpkt_hdr;
    int bytes_read;
    guint32 packet_size;
    struct visual_atm_hdr vatm_hdr;
    double  t;
    time_t  secs;
    guint32 usecs;
    guint32 packet_status;
    guint8 *pd;

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

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

    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;

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

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

    packet_status = pletohl(&vpkt_hdr.status);

    /* Do encapsulation-specific processing.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    phdr->caplen = packet_size;

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

    /* Sanity check */
    if (phdr->len < phdr->caplen)
    {
        phdr->len = phdr->caplen;
    }

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

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

           The encapsulation hint values we've seen are:

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

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

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

    return TRUE;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
static int
commview_read_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    int *err, gchar **err_info)
{
	commview_header_t cv_hdr;
	struct tm tm;
	guint frequency;

	if(!commview_read_header(&cv_hdr, fh, err, err_info))
		return FALSE;

	switch(cv_hdr.flags & FLAGS_MEDIUM) {

	case MEDIUM_ETHERNET :
		phdr->pkt_encap = WTAP_ENCAP_ETHERNET;
		phdr->pseudo_header.eth.fcs_len = -1; /* Unknown */
		break;

	case MEDIUM_WIFI :
		phdr->pkt_encap = WTAP_ENCAP_IEEE_802_11_WITH_RADIO;
		phdr->pseudo_header.ieee_802_11.fcs_len = -1; /* Unknown */
		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 =
		    PHDR_802_11_HAS_CHANNEL |
		    PHDR_802_11_HAS_DATA_RATE |
		    PHDR_802_11_HAS_SIGNAL_PERCENT;
		switch (cv_hdr.band) {

		case BAND_11A:
			phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_11A;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11a.presence_flags =
			    PHDR_802_11A_HAS_TURBO_TYPE;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11a.turbo_type =
			    PHDR_802_11A_TURBO_TYPE_NORMAL;
			frequency = ieee80211_chan_to_mhz(cv_hdr.channel, FALSE);
			break;

		case BAND_11B:
			phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_11B;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11b.presence_flags = 0;
			frequency = ieee80211_chan_to_mhz(cv_hdr.channel, TRUE);
			break;

		case BAND_11G:
			phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_11G;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11g.presence_flags =
			    PHDR_802_11G_HAS_MODE;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11g.mode =
			    PHDR_802_11G_MODE_NORMAL;
			frequency = ieee80211_chan_to_mhz(cv_hdr.channel, TRUE);
			break;

		case BAND_11A_TURBO:
			phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_11A;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11a.presence_flags =
			    PHDR_802_11A_HAS_TURBO_TYPE;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11a.turbo_type =
			    PHDR_802_11A_TURBO_TYPE_TURBO;
			frequency = ieee80211_chan_to_mhz(cv_hdr.channel, FALSE);
			break;

		case BAND_SUPERG:
			phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_11G;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11g.presence_flags =
			    PHDR_802_11G_HAS_MODE;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11g.mode =
			    PHDR_802_11G_MODE_SUPER_G;
			frequency = ieee80211_chan_to_mhz(cv_hdr.channel, TRUE);
			break;

		case BAND_11N_5GHZ:
			phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_11N;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11n.presence_flags =
			    0;
			frequency = ieee80211_chan_to_mhz(cv_hdr.channel, FALSE);
			break;

		case BAND_11N_2_4GHZ:
			phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_11N;
			phdr->pseudo_header.ieee_802_11.phy_info.info_11n.presence_flags =
			    0;
			frequency = ieee80211_chan_to_mhz(cv_hdr.channel, TRUE);
			break;

		case BAND_PUBLIC_SAFETY:
			/*
			 * XXX - what do we do here?  What are the channel
			 * numbers?  How do we distinguish the several
			 * different flavors of 4.9 GHz frequencies?
			 */
			frequency = 0;
			break;

		default:
			frequency = 0;
			break;
		}
		if (frequency != 0) {
			phdr->pseudo_header.ieee_802_11.presence_flags |=
			    PHDR_802_11_HAS_FREQUENCY;
			phdr->pseudo_header.ieee_802_11.frequency = frequency;
		}
		phdr->pseudo_header.ieee_802_11.channel = cv_hdr.channel;
		phdr->pseudo_header.ieee_802_11.data_rate =
		    cv_hdr.rate | (cv_hdr.direction << 8);
		phdr->pseudo_header.ieee_802_11.signal_percent = cv_hdr.signal_level_percent;

		/*
		 * XXX - these are positive in captures I've seen; does
		 * that mean that they are the negative of the actual
		 * dBm value?  (80 dBm is a bit more power than most
		 * countries' regulatory agencies are likely to allow
		 * any individual to have in their home. :-))
		 *
		 * XXX - sometimes these are 0; assume that means that no
		 * value is provided.
		 */
		if (cv_hdr.signal_level_dbm != 0) {
			phdr->pseudo_header.ieee_802_11.signal_dbm = -cv_hdr.signal_level_dbm;
			phdr->pseudo_header.ieee_802_11.presence_flags |=
			    PHDR_802_11_HAS_SIGNAL_DBM;
		}
		if (cv_hdr.noise_level != 0) {
			phdr->pseudo_header.ieee_802_11.noise_dbm = -cv_hdr.noise_level;
			phdr->pseudo_header.ieee_802_11.presence_flags |=
			    PHDR_802_11_HAS_NOISE_DBM;
		}
		break;

	case MEDIUM_TOKEN_RING :
		phdr->pkt_encap = WTAP_ENCAP_TOKEN_RING;
		break;

	default :
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("commview: unsupported encap: %u",
					    cv_hdr.flags & FLAGS_MEDIUM);
		return FALSE;
	}

	tm.tm_year = cv_hdr.year - 1900;
	tm.tm_mon = cv_hdr.month - 1;
	tm.tm_mday = cv_hdr.day;
	tm.tm_hour = cv_hdr.hours;
	tm.tm_min = cv_hdr.minutes;
	tm.tm_sec = cv_hdr.seconds;
	tm.tm_isdst = -1;

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

	phdr->len = cv_hdr.data_len;
	phdr->caplen = cv_hdr.data_len;

	phdr->ts.secs = mktime(&tm);
	phdr->ts.nsecs = cv_hdr.usecs * 1000;

	return wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info);
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
static process_record_retval
netmon_process_record(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	netmon_t *netmon = (netmon_t *)wth->priv;
	int	hdr_size = 0;
	union {
		struct netmonrec_1_x_hdr hdr_1_x;
		struct netmonrec_2_x_hdr hdr_2_x;
	}	hdr;
	int	bytes_read;
	gint64	delta = 0;	/* signed - frame times can be before the nominal start */
	gint64	t;
	time_t	secs;
	int	nsecs;
	guint32	packet_size = 0;
	guint32 orig_size = 0;
	int	trlr_size;
	union {
		struct netmonrec_2_1_trlr trlr_2_1;
		struct netmonrec_2_2_trlr trlr_2_2;
		struct netmonrec_2_3_trlr trlr_2_3;
	}	trlr;
	guint16 network;
	int	pkt_encap;

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

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

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

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

	switch (netmon->version_major) {

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

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

	phdr->rec_type = REC_TYPE_PACKET;

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

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

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

	default:
		break;
	}

	switch (netmon->version_major) {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			d = pletoh64(trlr.trlr_2_3.utc_timestamp);

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

	netmon_set_pseudo_header_info(phdr, buf);
	return SUCCESS;
}
Ejemplo n.º 16
0
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
                               Buffer *buf, int *err, gchar **err_info)
{
  stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv;
  guint32 millisecs, secs, nsecs;
  gint64 offset = 0;
  guint8 stanag_pkt_hdr[PKT_HDR_SIZE+SEG_HDR_SIZE];
  guint32 packet_size;

  *err = 0;

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

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

  rec->rec_type = REC_TYPE_PACKET;

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

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

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

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

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

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

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

  return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
/* Read the next packet */
static gboolean netmon_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	netmon_t *netmon = (netmon_t *)wth->priv;
	gint64	rec_offset;

again:
	/* Have we reached the end of the packet data? */
	if (netmon->current_frame >= netmon->frame_table_size) {
		/* Yes.  We won't need the frame table any more;
		   free it. */
		g_free(netmon->frame_table);
		netmon->frame_table = NULL;
		*err = 0;	/* it's just an EOF, not an error */
		return FALSE;
	}

	/* Seek to the beginning of the current record, if we're
	   not there already (seeking to the current position
	   may still cause a seek and a read of the underlying file,
	   so we don't want to do it unconditionally).

	   Yes, the current record could be before the previous
	   record.  At least some captures put the trailer record
	   with statistics as the first physical record in the
	   file, but set the frame table up so it's the last
	   record in sequence. */
	rec_offset = netmon->frame_table[netmon->current_frame];
	if (file_tell(wth->fh) != rec_offset) {
		if (file_seek(wth->fh, rec_offset, SEEK_SET, err) == -1)
			return FALSE;
	}
	netmon->current_frame++;

	*data_offset = file_tell(wth->fh);

	if (!netmon_process_rec_header(wth, wth->fh, &wth->phdr,
	    err, err_info))
		return FALSE;

	if (!wtap_read_packet_bytes(wth->fh, wth->frame_buffer,
	    wth->phdr.caplen, err, err_info))
		return FALSE;	/* Read error */

	/*
	 * For version 2.1 and later, there's additional information
	 * after the frame data.
	 */
	switch (netmon_process_rec_trailer(netmon, wth->fh, &wth->phdr,
	    err, err_info)) {

	case RETRY:
		goto again;

	case SUCCESS:
		break;

	case FAILURE:
		return FALSE;
	}

	netmon_set_pseudo_header_info(wth->phdr.pkt_encap,
	    &wth->phdr.pseudo_header, wth->frame_buffer, wth->phdr.caplen);
	return TRUE;
}
Ejemplo n.º 19
0
static gboolean
radcom_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
		int *err, gchar **err_info)
{
	struct radcomrec_hdr hdr;
	int	bytes_read;
	guint16 data_length, real_length, length;
	guint32 sec;
	struct tm tm;
	guint8	atmhdr[8];

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

	data_length = pletohs(&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 = pletohs(&hdr.length);
	real_length = pletohs(&hdr.real_length);

	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;

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

	switch (wth->file_encap) {

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

	case WTAP_ENCAP_LAPB:
		phdr->pseudo_header.x25.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 (!radcom_read_rec_data(wth->fh, atmhdr, sizeof atmhdr, err,
		    err_info))
			return FALSE;	/* Read error */
		length -= 8;
		real_length -= 8;
		break;
	}

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

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

	return TRUE;
}
Ejemplo n.º 20
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];
	int bytes_read;
#if 0
	guint16 protoNum;
#endif
	guint16 length;
	guint16 sliceLength;
#if 0
	guint8  flags;
#endif
	guint8  status;
	guint64 timestamp;
	time_t tsecs;
	guint32 tusecs;

	bytes_read = file_read(ep_pkt, sizeof(ep_pkt), fh);
	if (bytes_read != (int) sizeof(ep_pkt)) {
		*err = file_error(fh, err_info);
		if (*err == 0 && bytes_read > 0)
			*err = WTAP_ERR_SHORT_READ;
		return -1;
	}

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

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

	/* fill in packet header values */
	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;

		/*
		 * 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;
}
Ejemplo n.º 21
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;
	int	bytes_read;
	guint32 rec_size;
	guint32	packet_size;
	guint32 orig_size;
	int header_size;

	/* Read record header. */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&hdr, sizeof hdr, fh);
	if (bytes_read != sizeof hdr) {
		*err = file_error(fh, err_info);
		if (*err == 0 && bytes_read != 0)
			*err = WTAP_ERR_SHORT_READ;
		return -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 == WTAP_FILE_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->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(buffer_start_ptr(buf), packet_size,
		    &phdr->pseudo_header);
	}

	return rec_size - ((guint)sizeof hdr + packet_size);
}
Ejemplo n.º 22
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);
}
Ejemplo n.º 23
0
static gboolean peekclassic_read_packet_v56(wtap *wth, FILE_T fh,
    wtap_rec *rec, 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;
	}
	/*
	 * 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 */
	rec->rec_type = REC_TYPE_PACKET;
	rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	/* timestamp is in milliseconds since reference_time */
	rec->ts.secs  = peekclassic->reference_time + (timestamp / 1000);
	rec->ts.nsecs = 1000 * (timestamp % 1000) * 1000;
	rec->rec_header.packet_header.len      = length;
	rec->rec_header.packet_header.caplen   = sliceLength;

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

	switch (rec->rec_header.packet_header.pkt_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;
	}

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

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

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

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

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

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

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

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

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

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

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

      switch (wth->file_encap) {

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

      /* Read the packet data */
      return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
}
Ejemplo n.º 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);
}
Ejemplo n.º 26
0
/* Read the next packet */
static gboolean aethra_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	struct aethrarec_hdr hdr;

	/*
	 * Keep reading until we see an AETHRA_ISDN_LINK with a subtype
	 * of AETHRA_ISDN_LINK_LAPD record or get an end-of-file.
	 */
	for (;;) {
		*data_offset = file_tell(wth->fh);

		/* Read record header. */
		if (!aethra_read_rec_header(wth, wth->fh, &hdr, &wth->phdr, err, err_info))
			return FALSE;

		/*
		 * XXX - if this is big, we might waste memory by
		 * growing the buffer to handle it.
		 */
		if (wth->phdr.caplen != 0) {
			if (!wtap_read_packet_bytes(wth->fh, wth->frame_buffer,
			    wth->phdr.caplen, err, err_info))
				return FALSE;	/* Read error */
		}
#if 0
packet++;
#endif
		switch (hdr.rec_type) {

		case AETHRA_ISDN_LINK:
#if 0
fprintf(stderr, "Packet %u: type 0x%02x (AETHRA_ISDN_LINK)\n",
packet, hdr.rec_type);
#endif
			switch (hdr.flags & AETHRA_ISDN_LINK_SUBTYPE) {

			case AETHRA_ISDN_LINK_LAPD:
				/*
				 * The data is a LAPD frame.
				 */
#if 0
fprintf(stderr, "    subtype 0x%02x (AETHRA_ISDN_LINK_LAPD)\n", hdr.flags & AETHRA_ISDN_LINK_SUBTYPE);
#endif
				goto found;

			case AETHRA_ISDN_LINK_SA_BITS:
				/*
				 * These records have one data byte, which
				 * has the Sa bits in the lower 5 bits.
				 *
				 * XXX - what about stuff other than 2048K
				 * PRI lines?
				 */
#if 0
fprintf(stderr, "    subtype 0x%02x (AETHRA_ISDN_LINK_SA_BITS)\n", hdr.flags & AETHRA_ISDN_LINK_SUBTYPE);
#endif
				break;

			case AETHRA_ISDN_LINK_ALL_ALARMS_CLEARED:
				/*
				 * No data, just an "all alarms cleared"
				 * indication.
				 */
#if 0
fprintf(stderr, "    subtype 0x%02x (AETHRA_ISDN_LINK_ALL_ALARMS_CLEARED)\n", hdr.flags & AETHRA_ISDN_LINK_SUBTYPE);
#endif
				break;

			default:
#if 0
fprintf(stderr, "    subtype 0x%02x, packet_size %u, direction 0x%02x\n",
hdr.flags & AETHRA_ISDN_LINK_SUBTYPE, wth->phdr.caplen, hdr.flags & AETHRA_U_TO_N);
#endif
				break;
			}
			break;

		default:
#if 0
fprintf(stderr, "Packet %u: type 0x%02x, packet_size %u, flags 0x%02x\n",
packet, hdr.rec_type, wth->phdr.caplen, hdr.flags);
#endif
			break;
		}
	}

found:
	return TRUE;
}
Ejemplo n.º 27
0
static gboolean
libpcap_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct pcaprec_ss990915_hdr hdr;
	guint packet_size;
	guint orig_size;
	int bytes_read;
	int phdr_len;
	libpcap_t *libpcap;

	bytes_read = libpcap_read_header(wth, fh, err, err_info, &hdr);
	if (bytes_read == -1) {
		/*
		 * We failed to read the header.
		 */
		return FALSE;
	}

	packet_size = hdr.hdr.incl_len;
	orig_size = hdr.hdr.orig_len;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX &&
	    (wth->file_encap == WTAP_ENCAP_FDDI ||
	     wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		packet_size -= 3;
		orig_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}

	phdr_len = pcap_process_pseudo_header(fh, wth->file_type_subtype,
	    wth->file_encap, packet_size, TRUE, phdr, err, err_info);
	if (phdr_len < 0)
		return FALSE;	/* error */

	/*
	 * Don't count any pseudo-header as part of the packet.
	 */
	orig_size -= phdr_len;
	packet_size -= phdr_len;

	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;

	/* Update the timestamp, if not already done */
	if (wth->file_encap != WTAP_ENCAP_ERF) {
		phdr->ts.secs = hdr.hdr.ts_sec;
		if (wth->tsprecision == WTAP_FILE_TSPREC_NSEC)
			phdr->ts.nsecs = hdr.hdr.ts_usec;
		else
			phdr->ts.nsecs = hdr.hdr.ts_usec * 1000;
	} else {
		/* Set interface ID for ERF format */
		phdr->presence_flags |= WTAP_HAS_INTERFACE_ID;
		phdr->interface_id = phdr->pseudo_header.erf.phdr.flags & 0x03;
	}
	phdr->caplen = packet_size;
	phdr->len = orig_size;

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

	libpcap = (libpcap_t *)wth->priv;
	pcap_read_post_process(wth->file_type_subtype, wth->file_encap,
	    &phdr->pseudo_header, buffer_start_ptr(buf), packet_size,
	    libpcap->byte_swapped, -1);
	return TRUE;
}