static int read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_header, guint8 *pd, int length, int *err, char **err_info) { int seek_increment; int bytes_consumed = 0; /* validate offsets */ if (offset_to_frame < current_offset_from_packet_header) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: bad record (offset to packet data %d < %d)", offset_to_frame, current_offset_from_packet_header); return -1; } /* skip to the packet data */ seek_increment = offset_to_frame - current_offset_from_packet_header; if (seek_increment > 0) { if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1) { return -1; } bytes_consumed += seek_increment; } /* read in the packet data */ wtap_file_read_expected_bytes(pd, length, fh, err, err_info); bytes_consumed += length; return bytes_consumed; }
/* Read IPFIX message header from file. Return true on success. Set *err to * 0 on EOF, any other value for "real" errors (EOF is ok, since return * value is still FALSE) */ static gboolean ipfix_read_message_header(ipfix_message_header_t *pfx_hdr, FILE_T fh, int *err, gchar **err_info) { wtap_file_read_expected_bytes(pfx_hdr, IPFIX_MSG_HDR_SIZE, fh, err, err_info); /* macro which does a return if read fails */ /* fix endianess, because IPFIX files are always big-endian */ pfx_hdr->version = g_ntohs(pfx_hdr->version); pfx_hdr->message_length = g_ntohs(pfx_hdr->message_length); pfx_hdr->export_time_secs = g_ntohl(pfx_hdr->export_time_secs); pfx_hdr->sequence_number = g_ntohl(pfx_hdr->sequence_number); pfx_hdr->observation_id = g_ntohl(pfx_hdr->observation_id); /* is the version number one we expect? */ if (pfx_hdr->version != IPFIX_VERSION) { /* Not an ipfix file. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("ipfix: wrong version %d", pfx_hdr->version); return FALSE; } if (pfx_hdr->message_length < 16) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("ipfix: message length %u is too short", pfx_hdr->message_length); return FALSE; } /* go back to before header */ if (file_seek(fh, 0 - IPFIX_MSG_HDR_SIZE, SEEK_CUR, err) == -1) { ipfix_debug0("ipfix_read: couldn't go back in file before header"); return FALSE; } return TRUE; }
/* classic wtap: read packet */ static gboolean ipfix_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { ipfix_message_header_t msg_hdr; *data_offset = file_tell(wth->fh); ipfix_debug1("ipfix_read: data_offset is initially %" G_GINT64_MODIFIER "d", *data_offset); if (!ipfix_read_message_header(&msg_hdr, wth->fh, err, err_info)) { ipfix_debug2("ipfix_read: couldn't read message header with code: %d\n, and error '%s'", *err, *err_info); return FALSE; } buffer_assure_space(wth->frame_buffer, msg_hdr.message_length); wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), msg_hdr.message_length, wth->fh, err, err_info); wth->phdr.presence_flags = 0; wth->phdr.len = msg_hdr.message_length; wth->phdr.caplen = msg_hdr.message_length; wth->phdr.ts.secs = 0; wth->phdr.ts.nsecs = 0; /*ipfix_debug2("Read length: %u Packet length: %u", msg_hdr.message_length, wth->phdr.caplen);*/ ipfix_debug1("ipfix_read: data_offset is finally %" G_GINT64_MODIFIER "d", file_tell(wth->fh)); return TRUE; }
/* classic wtap: seek to file position and read packet */ static gboolean ipfix_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guint8 *pd, int length _U_, int *err, gchar **err_info) { ipfix_message_header_t msg_hdr; (void) pseudo_header; /* avoids compiler warning about unused variable */ /* seek to the right file position */ if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) { ipfix_debug2("ipfix_seek_read: couldn't read message header with code: %d\n, and error '%s'", *err, *err_info); return FALSE; /* Seek error */ } ipfix_debug1("ipfix_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off); if (!ipfix_read_message_header(&msg_hdr, wth->random_fh, err, err_info)) { ipfix_debug0("ipfix_read: couldn't read message header"); return FALSE; } if(length != (int)msg_hdr.message_length) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("ipfix: record length %u doesn't match requested length %d", msg_hdr.message_length, length); ipfix_debug1("ipfix_seek_read: %s", *err_info); return FALSE; } wtap_file_read_expected_bytes(pd, length, wth->random_fh, err, err_info); return TRUE; }
static gboolean peekclassic_seek_read_v56(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, guint8 *pd, int length, int *err, gchar **err_info) { union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; guint8 ep_pkt[PEEKCLASSIC_V56_PKT_SIZE]; int pkt_encap; guint16 protoNum; unsigned int i; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->random_fh, err, err_info); protoNum = pntohs(&ep_pkt[PEEKCLASSIC_V56_PROTONUM_OFFSET]); pkt_encap = WTAP_ENCAP_UNKNOWN; for (i=0; i<NUM_PEEKCLASSIC_ENCAPS; i++) { if (peekclassic_encap[i].protoNum == protoNum) { pkt_encap = peekclassic_encap[i].encap; } } switch (pkt_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ pseudo_header->eth.fcs_len = 0; break; } /* * XXX - should "errno" be set in "wtap_file_read_expected_bytes()"? */ errno = WTAP_ERR_CANT_READ; wtap_file_read_expected_bytes(pd, length, wth->random_fh, err, err_info); return TRUE; }
static gboolean peekclassic_seek_read_v7(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, guint8 *pd, int length, int *err, gchar **err_info) { union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; guint8 ep_pkt[PEEKCLASSIC_V7_PKT_SIZE]; guint8 status; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; /* Read the packet header. */ wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->random_fh, err, err_info); status = ep_pkt[PEEKCLASSIC_V7_STATUS_OFFSET]; switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_AIROPEEK: pseudo_header->ieee_802_11.fcs_len = 0; /* no FCS */ pseudo_header->ieee_802_11.decrypted = FALSE; 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. */ pseudo_header->eth.fcs_len = (status & 0x01) ? 0 : 4; break; } /* * XXX - should "errno" be set in "wtap_file_read_expected_bytes()"? */ errno = WTAP_ERR_CANT_READ; wtap_file_read_expected_bytes(pd, length, wth->random_fh, err, err_info); return TRUE; }
static gboolean tnef_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { guint8 *buf; gint64 file_size; int packet_size; struct stat statb; *err = 0; /* there is only ever one packet */ if(wth->data_offset) return FALSE; *data_offset = wth->data_offset; if ((file_size = wtap_file_size(wth, err)) == -1) return FALSE; if (file_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_RECORD; *err_info = g_strdup_printf("tnef: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u", file_size, WTAP_MAX_PACKET_SIZE); return FALSE; } packet_size = (int)file_size; buffer_assure_space(wth->frame_buffer, packet_size); buf = buffer_start_ptr(wth->frame_buffer); wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err); wth->data_offset += packet_size; wth->phdr.caplen = packet_size; wth->phdr.len = packet_size; if (fstat(wth->fd, &statb) == -1) { *err = errno; return FALSE; } wth->phdr.ts.secs = statb.st_mtime; wth->phdr.ts.nsecs = 0; return TRUE; }
static gboolean ber_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { gint64 offset; guint8 *buf; gint64 file_size; int packet_size; *err = 0; offset = file_tell(wth->fh); /* there is only ever one packet */ if (offset != 0) return FALSE; *data_offset = offset; if ((file_size = wtap_file_size(wth, err)) == -1) return FALSE; if (file_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("ber: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u", file_size, WTAP_MAX_PACKET_SIZE); return FALSE; } packet_size = (int)file_size; buffer_assure_space(wth->frame_buffer, packet_size); buf = buffer_start_ptr(wth->frame_buffer); wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err, err_info); wth->phdr.presence_flags = 0; /* yes, we have no bananas^Wtime stamp */ wth->phdr.caplen = packet_size; wth->phdr.len = packet_size; wth->phdr.ts.secs = 0; wth->phdr.ts.nsecs = 0; return TRUE; }
static gboolean jpeg_jfif_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { guint8 *buf; gint64 file_size; int packet_size; gint64 capture_size; *err = 0; /* interpret the file as one packet only */ if (wth->data_offset) return FALSE; *data_offset = wth->data_offset; if ((file_size = wtap_file_size(wth, err)) == -1) return FALSE; /* Read maximum possible packet size */ if (file_size <= WTAP_MAX_PACKET_SIZE) { capture_size = file_size; } else { capture_size = WTAP_MAX_PACKET_SIZE; } packet_size = (int)capture_size; buffer_assure_space(wth->frame_buffer, packet_size); buf = buffer_start_ptr(wth->frame_buffer); wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err); wth->data_offset += packet_size; wth->phdr.caplen = packet_size; wth->phdr.len = (int)file_size; wth->phdr.ts.secs = 0; wth->phdr.ts.nsecs = 0; *err_info = NULL; return TRUE; }
static gboolean read_packet_data(FILE_T fh, int offset_to_frame, int offset, guint8 *pd, int length, int *err, char **err_info) { int seek_increment; /* get to the packet data */ if (offset_to_frame < offset) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("Observer: bad record (offset to packet data %d < %d)", offset_to_frame, offset); return FALSE; } seek_increment = offset_to_frame - offset; if (seek_increment > 0) { if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1) return FALSE; } /* read in the packet */ wtap_file_read_expected_bytes(pd, length, fh, err); return TRUE; }
static gboolean airopeekv9_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err, gchar **err_info) { airopeek9_t *airopeek9 = (airopeek9_t *)wth->priv; hdr_info_t hdr_info; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; /* Process the packet header. */ if (airopeekv9_process_header(wth->random_fh, &hdr_info, err, err_info) == -1) return FALSE; switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: pseudo_header->ieee_802_11 = hdr_info.ieee_802_11; if (airopeek9->has_fcs) pseudo_header->ieee_802_11.fcs_len = 4; else pseudo_header->ieee_802_11.fcs_len = 0; break; case WTAP_ENCAP_ETHERNET: pseudo_header->eth.fcs_len = 0; break; } /* * XXX - should "errno" be set in "wtap_file_read_expected_bytes()"? */ errno = WTAP_ERR_CANT_READ; wtap_file_read_expected_bytes(pd, length, wth->random_fh, err); return TRUE; }
static gboolean peekclassic_read_v56(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { 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; char protoStr[8]; unsigned int i; /* * XXX - in order to figure out whether this packet is an * Ethernet packet or not, we have to look at the packet * header, so we have to remember the address of the header, * not the address of the data, for random access. * * If we can determine that from the file header, rather than * the packet header, we can remember the offset of the data, * and not have the seek_read routine read the header. */ *data_offset = file_tell(wth->fh); wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->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]); memcpy(protoStr, &ep_pkt[PEEKCLASSIC_V56_PROTOSTR_OFFSET], sizeof protoStr); /* * 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; } /* read the frame data */ buffer_assure_space(wth->frame_buffer, sliceLength); wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), sliceLength, wth->fh, err, err_info); /* fill in packet header values */ wth->phdr.len = length; wth->phdr.caplen = sliceLength; /* timestamp is in milliseconds since reference_time */ wth->phdr.ts.secs = peekclassic->reference_time.tv_sec + (timestamp / 1000); wth->phdr.ts.nsecs = 1000 * (timestamp % 1000) * 1000; wth->phdr.pkt_encap = WTAP_ENCAP_UNKNOWN; for (i=0; i<NUM_PEEKCLASSIC_ENCAPS; i++) { if (peekclassic_encap[i].protoNum == protoNum) { wth->phdr.pkt_encap = peekclassic_encap[i].encap; } } switch (wth->phdr.pkt_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ wth->phdr.pseudo_header.eth.fcs_len = 0; break; } return TRUE; }
static gboolean commview_read_header(commview_header_t *cv_hdr, FILE_T fh, int *err, gchar **err_info) { wtap_file_read_expected_bytes(&cv_hdr->data_len, 2, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->source_data_len, 2, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->version, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->year, 2, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->month, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->day, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->hours, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->minutes, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->seconds, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->usecs, 4, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->flags, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->signal_level_percent, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->rate, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->band, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->channel, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->direction, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->signal_level_dbm, 1, fh, err, err_info); wtap_file_read_expected_bytes(&cv_hdr->noise_level, 1, fh, err, err_info); /* Convert multi-byte values from little endian to host endian format */ cv_hdr->data_len = GUINT16_FROM_LE(cv_hdr->data_len); cv_hdr->source_data_len = GUINT16_FROM_LE(cv_hdr->source_data_len); cv_hdr->year = GUINT16_FROM_LE(cv_hdr->year); cv_hdr->usecs = GUINT32_FROM_LE(cv_hdr->usecs); return TRUE; }
/* classic wtap: open capture file. Return 1 on success, 0 on normal failure * like malformed format, -1 on bad error like file system */ int ipfix_open(wtap *wth, int *err, gchar **err_info) { gint i, n, records_for_ipfix_check = RECORDS_FOR_IPFIX_CHECK; gchar *s; guint16 checked_len = 0; ipfix_message_header_t msg_hdr; ipfix_set_header_t set_hdr; ipfix_debug0("ipfix_open: opening file"); /* number of records to scan before deciding if this really is IPFIX */ if ((s = getenv("IPFIX_RECORDS_TO_CHECK")) != NULL) { if ((n = atoi(s)) > 0 && n < 101) { records_for_ipfix_check = n; } } /* * IPFIX is a little hard because there's no magic number; we look at * the first few records and see if they look enough like IPFIX * records. */ for (i = 0; i < records_for_ipfix_check; i++) { /* read first message header to check version */ if (!ipfix_read_message_header(&msg_hdr, wth->fh, err, err_info)) { ipfix_debug3("ipfix_open: couldn't read message header #%d with err code #%d (%s)", i, *err, *err_info); if (*err == WTAP_ERR_BAD_FILE) { *err = 0; /* not actually an error in this case */ g_free(*err_info); *err_info = NULL; return 0; } if (*err != 0) return -1; /* real failure */ /* else it's EOF */ if (i < 1) { /* we haven't seen enough to prove this is a ipfix file */ return 0; } /* if we got here, it's EOF and we think it's an ipfix file */ break; } if (file_seek(wth->fh, IPFIX_MSG_HDR_SIZE, SEEK_CUR, err) == -1) { ipfix_debug1("ipfix_open: failed seek to next message in file, %d bytes away", msg_hdr.message_length); return 0; } checked_len = IPFIX_MSG_HDR_SIZE; /* check each Set in IPFIX Message for sanity */ while (checked_len < msg_hdr.message_length) { wtap_file_read_expected_bytes(&set_hdr, IPFIX_SET_HDR_SIZE, wth->fh, err, err_info); set_hdr.set_length = g_ntohs(set_hdr.set_length); if ((set_hdr.set_length < IPFIX_SET_HDR_SIZE) || ((set_hdr.set_length + checked_len) > msg_hdr.message_length)) { ipfix_debug1("ipfix_open: found invalid set_length of %d", set_hdr.set_length); return 0; } if (file_seek(wth->fh, set_hdr.set_length - IPFIX_SET_HDR_SIZE, SEEK_CUR, err) == -1) { ipfix_debug1("ipfix_open: failed seek to next set in file, %d bytes away", set_hdr.set_length - IPFIX_SET_HDR_SIZE); return 0; } checked_len += set_hdr.set_length; } } /* all's good, this is a IPFIX file */ wth->file_encap = WTAP_ENCAP_RAW_IPFIX; wth->snapshot_length = 0; wth->tsprecision = WTAP_FILE_TSPREC_SEC; wth->subtype_read = ipfix_read; wth->subtype_seek_read = ipfix_seek_read; wth->subtype_close = ipfix_close; wth->file_type = WTAP_FILE_IPFIX; /* go back to beginning of file */ if (file_seek (wth->fh, 0, SEEK_SET, err) != 0) { return -1; } return 1; }
static gboolean airopeekv9_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { airopeek9_t *airopeek9 = (airopeek9_t *)wth->priv; hdr_info_t hdr_info; int hdrlen; double t; *data_offset = wth->data_offset; /* Process the packet header. */ hdrlen = airopeekv9_process_header(wth->fh, &hdr_info, err, err_info); if (hdrlen == 0) return FALSE; wth->data_offset += hdrlen; /* * If sliceLength is 0, force it to be the actual length of the packet. */ if (hdr_info.sliceLength == 0) hdr_info.sliceLength = hdr_info.length; if (hdr_info.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_RECORD; *err_info = g_strdup_printf("airopeek9: File has %u-byte packet, bigger than maximum of %u", hdr_info.sliceLength, WTAP_MAX_PACKET_SIZE); return FALSE; } /* fill in packet header length values before slicelength may be adjusted */ wth->phdr.len = hdr_info.length; wth->phdr.caplen = hdr_info.sliceLength; /* read the frame data */ buffer_assure_space(wth->frame_buffer, hdr_info.sliceLength); wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), hdr_info.sliceLength, wth->fh, err); wth->data_offset += hdr_info.sliceLength; /* recalculate and fill in packet time stamp */ t = (double) hdr_info.timestamp.lower + (double) hdr_info.timestamp.upper * 4294967296.0; t *= 1.0e-9; t -= TIME_FIXUP_CONSTANT; wth->phdr.ts.secs = (time_t) t; wth->phdr.ts.nsecs = (guint32) ((t - wth->phdr.ts.secs)*1000000000); switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: /* * The last 4 bytes sometimes contains the FCS but on a lot of * interfaces these are zero. Is there some way to determine * from the packet header whether it's an FCS or not? * * For now, we just discard those bytes; if we can determine * whether it's an FCS or not, we should use that to determine * whether to supply it as an FCS or discard it. */ wth->pseudo_header.ieee_802_11 = hdr_info.ieee_802_11; if (airopeek9->has_fcs) wth->pseudo_header.ieee_802_11.fcs_len = 4; else { wth->pseudo_header.ieee_802_11.fcs_len = 0; wth->phdr.len -= 4; wth->phdr.caplen -= 4; } 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? */ wth->pseudo_header.eth.fcs_len = 0; wth->phdr.len -= 4; wth->phdr.caplen -= 4; break; } return TRUE; }
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); }
static gboolean peekclassic_read_v7(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { 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; *data_offset = file_tell(wth->fh); wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->fh, err, err_info); /* 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; } wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* fill in packet header length values before slicelength may be adjusted */ wth->phdr.len = length; wth->phdr.caplen = sliceLength; if (sliceLength % 2) /* packets are padded to an even length */ sliceLength++; switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_AIROPEEK: wth->phdr.pseudo_header.ieee_802_11.fcs_len = 0; /* no FCS */ wth->phdr.pseudo_header.ieee_802_11.decrypted = FALSE; 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. */ wth->phdr.pseudo_header.eth.fcs_len = (status & 0x01) ? 0 : 4; break; } /* read the frame data */ buffer_assure_space(wth->frame_buffer, sliceLength); wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), sliceLength, wth->fh, err, err_info); /* fill in packet header values */ tsecs = (time_t) (timestamp/1000000); tusecs = (guint32) (timestamp - tsecs*1000000); wth->phdr.ts.secs = tsecs - mac2unix; wth->phdr.ts.nsecs = tusecs * 1000; if (wth->file_encap == WTAP_ENCAP_IEEE_802_11_AIROPEEK) { /* * 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. */ wth->phdr.len -= 4; wth->phdr.caplen -= 4; } return TRUE; }