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

	*data_offset = file_tell(wth->fh);

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

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

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

	return TRUE;
}
Exemplo n.º 2
0
static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
    int skip_len;

    *data_offset = file_tell(wth->fh);

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

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

    return TRUE;
}
Exemplo n.º 3
0
/* Read the next packet */
static gboolean snoop_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	int	padbytes;

	*data_offset = file_tell(wth->fh);

	padbytes = snoop_read_packet(wth, wth->fh, &wth->phdr,
	    wth->frame_buffer, err, err_info);
	if (padbytes == -1)
		return FALSE;

	/*
	 * Skip over the padding, if any.
	 */
	if (padbytes != 0) {
		if (!file_skip(wth->fh, padbytes, err))
			return FALSE;
	}

	return TRUE;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
/**
 * Skip a block
 */
static void skip_block(ang_file *f, struct blockheader *b)
{
	file_skip(f, b->size);
}
Exemplo n.º 6
0
static gboolean
iptrace_read_rec_2_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    int *err, gchar **err_info)
{
	guint8			header[IPTRACE_2_0_PHDR_SIZE];
	int			ret;
	iptrace_2_0_phdr	pkt_hdr;
	guint32			packet_size;

	ret = iptrace_read_rec_header(fh, header, IPTRACE_2_0_PHDR_SIZE,
	    err, err_info);
	if (ret <= 0) {
		/* Read error or EOF */
		return FALSE;
	}

	/*
	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
	 * value giving the type of the interface.  Check out the
	 * <net/if_types.h> header file.
	 */
	pkt_hdr.if_type = header[28];
	phdr->pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
#if 0
	/*
	 * We used to error out if the interface type in iptrace was
	 * unknown/unhandled, but an iptrace may contain packets
	 * from a variety of interfaces, some known, and others
	 * unknown.
	 *
	 * It is better to display the data even for unknown interface
	 * types, isntead of erroring out. In the future, it would be
	 * nice to be able to flag which frames are shown as data
	 * because their interface type is unknown, and also present
	 * the interface type number to the user so that it can be
	 * reported easily back to the Wireshark developer.
	 *
	 * XXX - what types are there that are used in files but
	 * that we don't handle?
	 */
	if (phdr->pkt_encap == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
		    pkt_hdr.if_type);
		return FALSE;
	}
#endif

	/* Read the packet metadata */
	packet_size = pntoh32(&header[0]);
	if (packet_size < IPTRACE_2_0_PDATA_SIZE) {
		/*
		 * Uh-oh, the record isn't big enough to even have a
		 * packet meta-data header.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
		    packet_size);
		return FALSE;
	}
	packet_size -= IPTRACE_2_0_PDATA_SIZE;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (phdr->pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		if (packet_size < 3) {
			/*
			 * Uh-oh, the record isn't big enough to even have
			 * the padding.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
			    packet_size + IPTRACE_2_0_PDATA_SIZE);
			return FALSE;
		}
		packet_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}
	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("iptrace: 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->len = packet_size;
	phdr->caplen = packet_size;
	phdr->ts.secs = pntoh32(&header[32]);
	phdr->ts.nsecs = pntoh32(&header[36]);

	/* Fill in the pseudo_header. */
	fill_in_pseudo_header(phdr->pkt_encap, &phdr->pseudo_header, header);

	/* Get the packet data */
	return iptrace_read_rec_data(fh, buf, phdr, err, err_info);
}
Exemplo n.º 7
0
static gboolean
iptrace_read_rec_1_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    int *err, gchar **err_info)
{
	guint8			header[IPTRACE_1_0_PHDR_SIZE];
	int			ret;
	iptrace_1_0_phdr	pkt_hdr;
	guint32			packet_size;

	ret = iptrace_read_rec_header(fh, header, IPTRACE_1_0_PHDR_SIZE,
	    err, err_info);
	if (ret <= 0) {
		/* Read error or EOF */
		return FALSE;
	}

	/*
	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
	 * value giving the type of the interface.  Check out the
	 * <net/if_types.h> header file.
	 */
	pkt_hdr.if_type = header[28];
	phdr->pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
	if (phdr->pkt_encap == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
		    pkt_hdr.if_type);
		return FALSE;
	}

	/* Read the packet metadata */
	packet_size = pntoh32(&header[0]);
	if (packet_size < IPTRACE_1_0_PDATA_SIZE) {
		/*
		 * Uh-oh, the record isn't big enough to even have a
		 * packet meta-data header.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
		    packet_size);
		return FALSE;
	}
	packet_size -= IPTRACE_1_0_PDATA_SIZE;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (phdr->pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		if (packet_size < 3) {
			/*
			 * Uh-oh, the record isn't big enough to even have
			 * the padding.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
			    packet_size + IPTRACE_1_0_PDATA_SIZE);
			return FALSE;
		}
		packet_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}
	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("iptrace: 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->len = packet_size;
	phdr->caplen = packet_size;
	phdr->ts.secs = pntoh32(&header[4]);
	phdr->ts.nsecs = 0;

	/* Fill in the pseudo-header. */
	fill_in_pseudo_header(phdr->pkt_encap, &phdr->pseudo_header, header);

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

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

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

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

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

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

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

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

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

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

    writep = buffer + 4;
    left -= 4;

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

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

            total_read += junky_offset;
            writep += junky_offset;

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

            left -= junky_offset;
            junky_offset = 8192;
        }

    } while(left);

    K12_HEX_ASCII_DUMP(5,file_offset, "GOT record", buffer, actual_len);
    return total_read;
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
0
/* Read the next packet */
static gboolean capsa_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	capsa_t *capsa = (capsa_t *)wth->priv;
	guint32 frame_within_block;
	int	padbytes;

	if (capsa->frame_count == capsa->number_of_frames) {
		/*
		 * No more frames left.  Return an EOF.
		 */
		*err = 0;
		return FALSE;
	}
	frame_within_block = capsa->frame_count % N_RECORDS_PER_GROUP;
	if (frame_within_block == 0) {
		/*
		 * Here's a record offset block.
		 * Get the offset of the block, and then skip the
		 * first byte.
		 */
		capsa->base_offset = file_tell(wth->fh);
		if (!file_skip(wth->fh, 1, err))
			return FALSE;

		/*
		 * Now read the record offsets.
		 */
		if (!wtap_read_bytes(wth->fh, &capsa->record_offsets,
		    sizeof capsa->record_offsets, err, err_info))
			return FALSE;

		/*
		 * And finish processing all 805 bytes by skipping
		 * the last 4 bytes.
		 */
		if (!file_skip(wth->fh, 4, err))
			return FALSE;
	}

	*data_offset = capsa->base_offset +
	    GUINT32_FROM_LE(capsa->record_offsets[frame_within_block]);
	if (!file_seek(wth->fh, *data_offset, SEEK_SET, err))
		return FALSE;

	padbytes = capsa_read_packet(wth, wth->fh, &wth->phdr,
	    wth->frame_buffer, err, err_info);
	if (padbytes == -1)
		return FALSE;

	/*
	 * Skip over the padding, if any.
	 */
	if (padbytes != 0) {
		if (!file_skip(wth->fh, padbytes, err))
			return FALSE;
	}

	capsa->frame_count++;

	return TRUE;
}
Exemplo n.º 11
0
wtap_open_return_val capsa_open(wtap *wth, int *err, gchar **err_info)
{
	char magic[sizeof capsa_magic];
	guint16 format_indicator;
	int file_type_subtype;
	guint32 number_of_frames;
	capsa_t *capsa;

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

	if (memcmp(magic, capsa_magic, sizeof capsa_magic) != 0) {
		return WTAP_OPEN_NOT_MINE;
	}

	/* Read the mysterious "format indicator" */
	if (!wtap_read_bytes(wth->fh, &format_indicator, sizeof format_indicator,
	    err, err_info))
		return WTAP_OPEN_ERROR;
	format_indicator = GUINT16_FROM_LE(format_indicator);

	/*
	 * Make sure it's a format we support.
	 */
	switch (format_indicator) {

	case 1:		/* Capsa */
		file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_COLASOFT_CAPSA;
		break;

	case 2:		/* Packet Builder */
		file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_COLASOFT_PACKET_BUILDER;
		break;

	default:
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("capsa: format indicator %u unsupported",
		    format_indicator);
		return WTAP_OPEN_ERROR;
	}

	/*
	 * Link speed, in megabytes/second?
	 */
	if (!file_skip(wth->fh, 2, err))
		return WTAP_OPEN_ERROR;

	/*
	 * Flags of some sort?
	 */
	if (!file_skip(wth->fh, 4, err))
		return WTAP_OPEN_ERROR;

	/*
	 * File size.
	 */
	if (!file_skip(wth->fh, 4, err))
		return WTAP_OPEN_ERROR;

	/*
	 * Zeroes?
	 */
	if (!file_skip(wth->fh, 4, err))
		return WTAP_OPEN_ERROR;

	/*
	 * Count of packets.
	 */
	if (!wtap_read_bytes(wth->fh, &number_of_frames, sizeof number_of_frames,
	    err, err_info))
		return WTAP_OPEN_ERROR;
	number_of_frames = GUINT32_FROM_LE(number_of_frames);

	/*
	 * Skip past what we think is file header.
	 */
	if (!file_seek(wth->fh, 0x44ef, SEEK_SET, err))
		return WTAP_OPEN_ERROR;

	wth->file_type_subtype = file_type_subtype;
	capsa = (capsa_t *)g_malloc(sizeof(capsa_t));
	capsa->format_indicator = format_indicator;
	capsa->number_of_frames = number_of_frames;
	capsa->frame_count = 0;
	wth->priv = (void *)capsa;
	wth->subtype_read = capsa_read;
	wth->subtype_seek_read = capsa_seek_read;
	/*
	 * XXX - we've never seen a Wi-Fi Capsa capture, so we don't
	 * yet know how to handle them.
	 */
	wth->file_encap = WTAP_ENCAP_ETHERNET;
	wth->snapshot_length = 0;	/* not available in header */
	wth->file_tsprec = WTAP_TSPREC_USEC;
	return WTAP_OPEN_MINE;
}
Exemplo n.º 12
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;
}