In the pcapng seek-read routine, *don't* fill in wth->phdr; seek-read

routines are passed a separate struct wtap_pkthdr to be filled in.

Get rid of the pseudo_header member of the wblock structure - the
pseudo-header is part of the struct wtap_pkthdr.

Get rid of the union wtap_pseudo_header * argument to
pcap_process_pseudo_header() - it's passed a pointer to a struct
pcap_pkthdr, and that structure contains the union in question.

Have libpcap_read_header() take a FILE_T argument, rather than using
only the "sequential" handle of the wtap it's handed.  Have the libpcap
read routine return the offset of the beginning of the pcap record, and
have the seek-read routine read the header and fill in the struct
wtap_pkthdr handed to it.

svn path=/trunk/; revision=49401
This commit is contained in:
Guy Harris 2013-05-18 02:36:00 +00:00
parent ba8ead5e61
commit 33e1232f23
4 changed files with 103 additions and 102 deletions

View File

@ -70,9 +70,11 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
static gboolean libpcap_seek_read(wtap *wth, gint64 seek_off,
struct wtap_pkthdr *phdr, guint8 *pd, int length,
int *err, gchar **err_info);
static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
struct pcaprec_ss990915_hdr *hdr);
static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
static gboolean libpcap_process_header(wtap *wth, FILE_T fh,
struct wtap_pkthdr *phdr, int *err, gchar **err_info);
static gboolean libpcap_read_rec_data(FILE_T fh, guint8 *pd, int length,
int *err, gchar **err_info);
static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
@ -516,7 +518,7 @@ static libpcap_try_t libpcap_try(wtap *wth, int *err)
/*
* Attempt to read the first record's header.
*/
if (libpcap_read_header(wth, err, NULL, &first_rec_hdr) == -1) {
if (libpcap_read_header(wth, wth->fh, err, NULL, &first_rec_hdr) == -1) {
if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
/*
* EOF or short read - assume the file is in this
@ -555,7 +557,7 @@ static libpcap_try_t libpcap_try(wtap *wth, int *err)
/*
* Now attempt to read the second record's header.
*/
if (libpcap_read_header(wth, err, NULL, &second_rec_hdr) == -1) {
if (libpcap_read_header(wth, wth->fh, err, NULL, &second_rec_hdr) == -1) {
if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
/*
* EOF or short read - assume the file is in this
@ -595,6 +597,53 @@ static libpcap_try_t libpcap_try(wtap *wth, int *err)
/* Read the next packet */
static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
gint64 *data_offset)
{
libpcap_t *libpcap;
*data_offset = file_tell(wth->fh);
if (!libpcap_process_header(wth, wth->fh, &wth->phdr, err, err_info))
return FALSE;
buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
wth->phdr.caplen, err, err_info))
return FALSE; /* Read error */
libpcap = (libpcap_t *)wth->priv;
pcap_read_post_process(wth->file_type, wth->file_encap,
&wth->phdr.pseudo_header, buffer_start_ptr(wth->frame_buffer),
wth->phdr.caplen, libpcap->byte_swapped, -1);
return TRUE;
}
static gboolean
libpcap_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
guint8 *pd, int length, int *err, gchar **err_info)
{
libpcap_t *libpcap;
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
return FALSE;
if (!libpcap_process_header(wth, wth->random_fh, phdr, err, err_info))
return FALSE;
/*
* Read the packet data.
*/
if (!libpcap_read_rec_data(wth->random_fh, pd, length, err, err_info))
return FALSE; /* failed */
libpcap = (libpcap_t *)wth->priv;
pcap_read_post_process(wth->file_type, wth->file_encap,
&phdr->pseudo_header, pd, length, libpcap->byte_swapped, -1);
return TRUE;
}
static gboolean
libpcap_process_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
int *err, gchar **err_info)
{
struct pcaprec_ss990915_hdr hdr;
guint packet_size;
@ -604,7 +653,7 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
int phdr_len;
libpcap_t *libpcap;
bytes_read = libpcap_read_header(wth, err, err_info, &hdr);
bytes_read = libpcap_read_header(wth, fh, err, err_info, &hdr);
if (bytes_read == -1) {
/*
* We failed to read the header.
@ -632,17 +681,14 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
/*
* Read the padding.
*/
if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err,
if (!libpcap_read_rec_data(fh, fddi_padding, 3, err,
err_info))
return FALSE; /* Read error */
}
*data_offset = file_tell(wth->fh);
libpcap = (libpcap_t *)wth->priv;
phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type,
wth->file_encap, packet_size, TRUE, &wth->phdr,
&wth->phdr.pseudo_header, err, err_info);
phdr_len = pcap_process_pseudo_header(fh, wth->file_type,
wth->file_encap, packet_size, TRUE, phdr, err, err_info);
if (phdr_len < 0)
return FALSE; /* error */
@ -652,68 +698,30 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
orig_size -= phdr_len;
packet_size -= phdr_len;
buffer_assure_space(wth->frame_buffer, packet_size);
if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
packet_size, err, err_info))
return FALSE; /* Read error */
phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
/* Update the Timestamp, if not already done */
/* Update the timestamp, if not already done */
if (wth->file_encap != WTAP_ENCAP_ERF) {
wth->phdr.ts.secs = hdr.hdr.ts_sec;
if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
wth->phdr.ts.nsecs = hdr.hdr.ts_usec;
} else {
wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000;
}
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 */
wth->phdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
wth->phdr.interface_id = wth->phdr.pseudo_header.erf.phdr.flags & 0x03;
}
wth->phdr.caplen = packet_size;
wth->phdr.len = orig_size;
phdr->caplen = packet_size;
phdr->len = orig_size;
pcap_read_post_process(wth->file_type, wth->file_encap,
&wth->phdr.pseudo_header, buffer_start_ptr(wth->frame_buffer),
wth->phdr.caplen, libpcap->byte_swapped, -1);
return TRUE;
}
static gboolean
libpcap_seek_read(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;
int phdr_len;
libpcap_t *libpcap;
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
return FALSE;
libpcap = (libpcap_t *)wth->priv;
phdr_len = pcap_process_pseudo_header(wth->random_fh, wth->file_type,
wth->file_encap, length, FALSE, NULL, pseudo_header, err, err_info);
if (phdr_len < 0)
return FALSE; /* error */
/*
* Read the packet data.
*/
if (!libpcap_read_rec_data(wth->random_fh, pd, length, err, err_info))
return FALSE; /* failed */
pcap_read_post_process(wth->file_type, wth->file_encap,
pseudo_header, pd, length, libpcap->byte_swapped, -1);
return TRUE;
}
/* Read the header of the next packet.
Return -1 on an error, or the number of bytes of header read on success. */
static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
struct pcaprec_ss990915_hdr *hdr)
{
int bytes_to_read, bytes_read;
@ -745,9 +753,9 @@ static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
g_assert_not_reached();
bytes_to_read = 0;
}
bytes_read = file_read(hdr, bytes_to_read, wth->fh);
bytes_read = file_read(hdr, bytes_to_read, fh);
if (bytes_read != bytes_to_read) {
*err = file_error(wth->fh, err_info);
*err = file_error(fh, err_info);
if (*err == 0 && bytes_read != 0) {
*err = WTAP_ERR_SHORT_READ;
}

View File

@ -1484,8 +1484,8 @@ pcap_read_i2c_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, i
int
pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
guint packet_size, gboolean check_packet_size, struct wtap_pkthdr *phdr,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
guint packet_size, gboolean check_packet_size,
struct wtap_pkthdr *phdr, int *err, gchar **err_info)
{
int phdr_len = 0;
guint size;
@ -1508,7 +1508,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
return -1;
}
if (!pcap_read_nokiaatm_pseudoheader(fh,
pseudo_header, err, err_info))
&phdr->pseudo_header, err, err_info))
return -1; /* Read error */
phdr_len = NOKIAATM_LEN;
@ -1527,7 +1527,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
return -1;
}
if (!pcap_read_sunatm_pseudoheader(fh,
pseudo_header, err, err_info))
&phdr->pseudo_header, err, err_info))
return -1; /* Read error */
phdr_len = SUNATM_LEN;
@ -1540,14 +1540,14 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
* Nokia IPSO. Psuedo header has already been read, but it's not considered
* part of the packet size, so reread it to store the data for later (when saving)
*/
if (!pcap_read_nokia_pseudoheader(fh, pseudo_header, err, err_info))
if (!pcap_read_nokia_pseudoheader(fh, &phdr->pseudo_header, err, err_info))
return -1; /* Read error */
}
/*
* We don't know whether there's an FCS in this frame or not.
*/
pseudo_header->eth.fcs_len = -1;
phdr->pseudo_header.eth.fcs_len = -1;
break;
case WTAP_ENCAP_IEEE_802_11:
@ -1559,11 +1559,11 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
* XXX - are there any OSes where the capture mechanism
* supplies an FCS?
*/
pseudo_header->ieee_802_11.fcs_len = -1;
pseudo_header->ieee_802_11.decrypted = FALSE;
pseudo_header->ieee_802_11.channel = 0;
pseudo_header->ieee_802_11.data_rate = 0;
pseudo_header->ieee_802_11.signal_level = 0;
phdr->pseudo_header.ieee_802_11.fcs_len = -1;
phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
phdr->pseudo_header.ieee_802_11.channel = 0;
phdr->pseudo_header.ieee_802_11.data_rate = 0;
phdr->pseudo_header.ieee_802_11.signal_level = 0;
break;
case WTAP_ENCAP_IRDA:
@ -1577,7 +1577,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
packet_size);
return -1;
}
if (!pcap_read_irda_pseudoheader(fh, pseudo_header,
if (!pcap_read_irda_pseudoheader(fh, &phdr->pseudo_header,
err, err_info))
return -1; /* Read error */
@ -1595,7 +1595,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
packet_size);
return -1;
}
if (!pcap_read_mtp2_pseudoheader(fh, pseudo_header,
if (!pcap_read_mtp2_pseudoheader(fh, &phdr->pseudo_header,
err, err_info))
return -1; /* Read error */
@ -1613,7 +1613,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
packet_size);
return -1;
}
if (!pcap_read_lapd_pseudoheader(fh, pseudo_header,
if (!pcap_read_lapd_pseudoheader(fh, &phdr->pseudo_header,
err, err_info))
return -1; /* Read error */
@ -1631,7 +1631,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
packet_size);
return -1;
}
if (!pcap_read_sita_pseudoheader(fh, pseudo_header,
if (!pcap_read_sita_pseudoheader(fh, &phdr->pseudo_header,
err, err_info))
return -1; /* Read error */
@ -1640,7 +1640,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
case WTAP_ENCAP_BLUETOOTH_H4:
/* We don't have pseudoheader, so just pretend we received everything. */
pseudo_header->p2p.sent = FALSE;
phdr->pseudo_header.p2p.sent = FALSE;
break;
case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
@ -1656,7 +1656,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
return -1;
}
if (!pcap_read_bt_pseudoheader(fh,
pseudo_header, err, err_info))
&phdr->pseudo_header, err, err_info))
return -1; /* Read error */
phdr_len = (int)sizeof (struct libpcap_bt_phdr);
@ -1668,7 +1668,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
*err_info = g_strdup_printf("pcap: libpcap llcp file too short");
return -1;
}
if (!pcap_read_llcp_pseudoheader(fh, pseudo_header, err, err_info))
if (!pcap_read_llcp_pseudoheader(fh, &phdr->pseudo_header, err, err_info))
return -1; /* Read error */
phdr_len = LLCP_HEADER_LEN;
break;
@ -1686,7 +1686,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
return -1;
}
if (!pcap_read_ppp_pseudoheader(fh,
pseudo_header, err, err_info))
&phdr->pseudo_header, err, err_info))
return -1; /* Read error */
phdr_len = (int)sizeof (struct libpcap_ppp_phdr);
@ -1705,21 +1705,21 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
return -1;
}
if (!pcap_read_erf_pseudoheader(fh, phdr, pseudo_header,
if (!pcap_read_erf_pseudoheader(fh, phdr, &phdr->pseudo_header,
err, err_info))
return -1; /* Read error */
phdr_len = (int)sizeof(struct erf_phdr);
/* check the optional Extension header */
if (!pcap_read_erf_exheader(fh, pseudo_header, err, err_info,
if (!pcap_read_erf_exheader(fh, &phdr->pseudo_header, err, err_info,
&size))
return -1; /* Read error */
phdr_len += size;
/* check the optional Multi Channel header */
if (!pcap_read_erf_subheader(fh, pseudo_header, err, err_info,
if (!pcap_read_erf_subheader(fh, &phdr->pseudo_header, err, err_info,
&size))
return -1; /* Read error */
@ -1750,7 +1750,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
packet_size);
return -1;
}
if (!pcap_read_i2c_pseudoheader(fh, pseudo_header,
if (!pcap_read_i2c_pseudoheader(fh, &phdr->pseudo_header,
err, err_info))
return -1; /* Read error */

View File

@ -32,8 +32,8 @@
#include "ws_symbol_export.h"
extern int pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
guint packet_size, gboolean check_packet_size, struct wtap_pkthdr *phdr,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
guint packet_size, gboolean check_packet_size,
struct wtap_pkthdr *phdr, int *err, gchar **err_info);
extern void pcap_read_post_process(int file_type, int wtap_encap,
union wtap_pseudo_header *pseudo_header,

View File

@ -368,7 +368,6 @@ typedef struct wtapng_block_s {
* but, when we're writing a block, they can be const, and,
* in fact, they sometimes point to const values.
*/
const union wtap_pseudo_header *pseudo_header;
struct wtap_pkthdr *packet_header;
const guint8 *frame_buffer;
int *file_encap;
@ -1067,25 +1066,24 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
pcapng_debug3("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
int_data.wtap_encap,
wtap_encap_string(int_data.wtap_encap),
pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header));
pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header.pseudo_header));
wblock->packet_header->interface_id = wblock->data.packet.interface_id;
wblock->packet_header->pkt_encap = int_data.wtap_encap;
memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header));
memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
pseudo_header_len = pcap_process_pseudo_header(fh,
WTAP_FILE_PCAPNG,
int_data.wtap_encap,
wblock->data.packet.cap_len,
TRUE,
wblock->packet_header,
(union wtap_pseudo_header *)wblock->pseudo_header,
err,
err_info);
if (pseudo_header_len < 0) {
return FALSE;
}
block_read += pseudo_header_len;
if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header)) {
if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header)) {
pcapng_debug1("pcapng_read_packet_block: Could only read %d bytes for pseudo header.",
pseudo_header_len);
}
@ -1219,7 +1217,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
g_free(option_content);
pcap_read_post_process(WTAP_FILE_PCAPNG, int_data.wtap_encap,
(union wtap_pseudo_header *)wblock->pseudo_header,
(union wtap_pseudo_header *)&wblock->packet_header->pseudo_header,
(guint8 *) (wblock->frame_buffer),
(int) (wblock->data.packet.cap_len - pseudo_header_len),
pn->byte_swapped, fcslen);
@ -1288,7 +1286,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
int_data = g_array_index(pn->interface_data, interface_data_t, 0);
pcapng_debug1("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header));
pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header));
/* No time stamp in a simple packet block; no options, either */
wblock->packet_header->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
@ -1301,14 +1299,13 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
wblock->packet_header->drop_count = 0;
wblock->packet_header->pack_flags = 0;
memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header));
memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
pseudo_header_len = pcap_process_pseudo_header(fh,
WTAP_FILE_PCAPNG,
int_data.wtap_encap,
wblock->data.simple_packet.cap_len,
TRUE,
wblock->packet_header,
(union wtap_pseudo_header *)wblock->pseudo_header,
err,
err_info);
if (pseudo_header_len < 0) {
@ -1317,12 +1314,12 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
wblock->packet_header->caplen = wblock->data.simple_packet.cap_len - pseudo_header_len;
wblock->packet_header->len = wblock->data.packet.packet_len - pseudo_header_len;
block_read += pseudo_header_len;
if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header)) {
if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header)) {
pcapng_debug1("pcapng_read_simple_packet_block: Could only read %d bytes for pseudo header.",
pseudo_header_len);
}
memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header));
memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
/* "Simple Packet Block" read capture data */
errno = WTAP_ERR_CANT_READ;
@ -1349,7 +1346,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
}
pcap_read_post_process(WTAP_FILE_PCAPNG, int_data.wtap_encap,
(union wtap_pseudo_header *)wblock->pseudo_header,
(union wtap_pseudo_header *)&wblock->packet_header->pseudo_header,
(guint8 *) (wblock->frame_buffer),
(int) wblock->data.simple_packet.cap_len,
pn->byte_swapped, pn->if_fcslen);
@ -2043,7 +2040,6 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
/* we don't expect any packet blocks yet */
wblock.frame_buffer = NULL;
wblock.pseudo_header = NULL;
wblock.packet_header = NULL;
wblock.file_encap = &wth->file_encap;
@ -2170,7 +2166,6 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
}
wblock.frame_buffer = buffer_start_ptr(wth->frame_buffer);
wblock.pseudo_header = &wth->phdr.pseudo_header;
wblock.packet_header = &wth->phdr;
wblock.file_encap = &wth->file_encap;
@ -2281,7 +2276,6 @@ pcapng_seek_read(wtap *wth, gint64 seek_off,
struct wtap_pkthdr *phdr, guint8 *pd, int length _U_,
int *err, gchar **err_info)
{
union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
pcapng_t *pcapng = (pcapng_t *)wth->priv;
guint64 bytes_read64;
int bytes_read;
@ -2296,8 +2290,7 @@ pcapng_seek_read(wtap *wth, gint64 seek_off,
pcapng_debug1("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
wblock.frame_buffer = pd;
wblock.pseudo_header = pseudo_header;
wblock.packet_header = &wth->phdr;
wblock.packet_header = phdr;
wblock.file_encap = &wth->file_encap;
/* read the block */