summaryrefslogtreecommitdiff
path: root/wiretap/pcapng.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-10-15 16:45:51 -0700
committerGuy Harris <guy@alum.mit.edu>2014-10-15 23:46:41 +0000
commitf518089709feba05fe8acfab76be5afc8bd97021 (patch)
treec9a284723a3a575f507b326c67b2cd3b74921668 /wiretap/pcapng.c
parent371e4ae1c787bfbfd292fbf2474624241ea942f9 (diff)
downloadwireshark-f518089709feba05fe8acfab76be5afc8bd97021.tar.gz
Clean up the read routines.
The block read routines don't need to return a "bytes read" amount any more. Have pcapng_read_block() just return an indication: PCAPNG_BLOCK_OK - the read succeeded; PCAPNG_BLOCK_NOT_SHB - the read failed in a fashion that indicates that we might just not be reading a pcap-ng file; PCAPNG_BLOCK_ERROR - the read failed in some other fashion (i.e., we already have concluded that the file is a pcap-ng file, or we got an I/O error). In the cases where it needs to know whether it's reading the first block for an open, have it check the shb_read flag, rather than being passed a separate Boolean argument. This means that pcapng_read_section_header_block() should return such an indication as well. Make the other block-reading routines return a Boolean success/failure indication. Change-Id: Id371457018a008ece9058d6042da44d631e51889 Reviewed-on: https://code.wireshark.org/review/4710 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'wiretap/pcapng.c')
-rw-r--r--wiretap/pcapng.c392
1 files changed, 201 insertions, 191 deletions
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index 1931616d0c..f997133feb 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -490,11 +490,16 @@ pcapng_free_wtapng_block_data(wtapng_block_t *wblock)
}
}
-static int
-pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
- pcapng_block_header_t *bh, pcapng_t *pn,
- wtapng_block_t *wblock, int *err,
- gchar **err_info)
+typedef enum {
+ PCAPNG_BLOCK_OK,
+ PCAPNG_BLOCK_NOT_SHB,
+ PCAPNG_BLOCK_ERROR
+} block_return_val;
+
+static block_return_val
+pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
+ pcapng_t *pn, wtapng_block_t *wblock,
+ int *err, gchar **err_info)
{
int bytes_read;
guint block_read;
@@ -506,17 +511,19 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
/* read fixed-length part of the block */
if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
if (*err == WTAP_ERR_SHORT_READ) {
- if (first_block) {
- /*
- * We're reading this as part of an open,
- * and this block is too short to be
- * an SHB, so the file is too short
- * to be a pcap-ng file.
- */
- return -2;
- }
+ /*
+ * This block is too short to be an SHB.
+ *
+ * If we're reading this as part of an open,
+ * the file is too short to be a pcap-ng file.
+ *
+ * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
+ * PCAPNG_BLOCK_ERROR the same, so we can just return
+ * PCAPNG_BLOCK_NOT_SHB in both cases.
+ */
+ return PCAPNG_BLOCK_NOT_SHB;
}
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
block_read = (guint)sizeof shb;
@@ -545,15 +552,13 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
break;
default:
/* Not a "pcapng" magic number we know about. */
- if (first_block) {
- /* Not a pcap-ng file. */
- return -2;
- }
-
- /* A bad block */
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_section_header_block: unknown byte-order magic number 0x%08x", shb.magic);
- return -1;
+
+ /*
+ * See above comment about PCAPNG_BLOCK_NOT_SHB.
+ */
+ return PCAPNG_BLOCK_NOT_SHB;
}
/*
@@ -563,12 +568,10 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
/*
* No.
*/
- if (first_block)
- return -2; /* probably not a pcap-ng file */
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u of an SHB is less than the minimum SHB size %u",
bh->block_total_length, MIN_SHB_SIZE);
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
/* OK, at this point we assume it's a pcap-ng file.
@@ -585,14 +588,14 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
bh->block_total_length, MAX_BLOCK_SIZE);
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
/* We currently only suport one SHB */
if (pn->shb_read == TRUE) {
*err = WTAP_ERR_UNSUPPORTED;
*err_info = g_strdup_printf("pcapng: multiple section header blocks not supported");
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
/* we currently only understand SHB V1.0 */
@@ -600,7 +603,7 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
*err = WTAP_ERR_UNSUPPORTED;
*err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
pn->version_major, pn->version_minor);
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
@@ -619,7 +622,7 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
option_content = (char *)g_try_malloc(opt_cont_buf_len);
if (opt_cont_buf_len != 0 && option_content == NULL) {
*err = ENOMEM; /* we assume we're out of memory */
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
pcapng_debug1("pcapng_read_section_header_block: Options %u bytes", to_read);
while (to_read != 0) {
@@ -628,7 +631,7 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
if (bytes_read <= 0) {
pcapng_debug0("pcapng_read_section_header_block: failed to read option");
- return bytes_read;
+ return PCAPNG_BLOCK_ERROR;
}
block_read += bytes_read;
to_read -= bytes_read;
@@ -685,12 +688,12 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
}
g_free(option_content);
- return block_read;
+ return PCAPNG_BLOCK_OK;
}
/* "Interface Description Block" */
-static int
+static gboolean
pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
pcapng_t *pn, wtapng_block_t *wblock, int *err,
gchar **err_info)
@@ -714,7 +717,7 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_if_descr_block: total block length %u of an IDB is less than the minimum IDB size %u",
bh->block_total_length, MIN_IDB_SIZE);
- return -1;
+ return FALSE;
}
/* Don't try to allocate memory for a huge number of options, as
@@ -729,13 +732,13 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
bh->block_total_length, MAX_BLOCK_SIZE);
- return -1;
+ return FALSE;
}
/* read block content */
if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
pcapng_debug0("pcapng_read_if_descr_block: failed to read IDB");
- return -1;
+ return FALSE;
}
block_read = (guint)sizeof idb;
@@ -793,7 +796,7 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
option_content = (char *)g_try_malloc(opt_cont_buf_len);
if (opt_cont_buf_len != 0 && option_content == NULL) {
*err = ENOMEM; /* we assume we're out of memory */
- return -1;
+ return FALSE;
}
while (to_read != 0) {
@@ -801,7 +804,7 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
if (bytes_read <= 0) {
pcapng_debug0("pcapng_read_if_descr_block: failed to read option");
- return bytes_read;
+ return FALSE;
}
block_read += bytes_read;
to_read -= bytes_read;
@@ -989,11 +992,11 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
}
}
- return block_read;
+ return TRUE;
}
-static int
+static gboolean
pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info, gboolean enhanced)
{
int bytes_read;
@@ -1023,7 +1026,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
bh->block_total_length, MAX_BLOCK_SIZE);
- return -1;
+ return FALSE;
}
/* "(Enhanced) Packet Block" read fixed part */
@@ -1038,11 +1041,11 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
bh->block_total_length, MIN_EPB_SIZE);
- return -1;
+ return FALSE;
}
if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
- return -1;
+ return FALSE;
}
block_read = (guint)sizeof epb;
@@ -1074,11 +1077,11 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
bh->block_total_length, MIN_PB_SIZE);
- return -1;
+ return FALSE;
}
if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
- return -1;
+ return FALSE;
}
block_read = (guint)sizeof pb;
@@ -1130,7 +1133,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
block_total_length, packet.cap_len);
- return -1;
+ return FALSE;
}
} else {
if (block_total_length <
@@ -1141,7 +1144,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
block_total_length, packet.cap_len);
- return -1;
+ return FALSE;
}
}
@@ -1149,7 +1152,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u",
packet.cap_len, WTAP_MAX_PACKET_SIZE);
- return -1;
+ return FALSE;
}
pcapng_debug3("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
packet.packet_len,
@@ -1160,7 +1163,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: interface index %u is not less than interface count %u",
packet.interface_id, pn->interfaces->len);
- return -1;
+ return FALSE;
}
iface_info = g_array_index(pn->interfaces, interface_info_t,
packet.interface_id);
@@ -1186,7 +1189,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
err,
err_info);
if (pseudo_header_len < 0) {
- return pseudo_header_len;
+ return FALSE;
}
block_read += pseudo_header_len;
if (pseudo_header_len != pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header)) {
@@ -1204,13 +1207,13 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
/* "(Enhanced) Packet Block" read capture data */
if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
packet.cap_len - pseudo_header_len, err, err_info))
- return -1;
+ return FALSE;
block_read += packet.cap_len - pseudo_header_len;
/* jump over potential padding bytes at end of the packet data */
if (padding != 0) {
if (!file_skip(fh, padding, err))
- return -1;
+ return FALSE;
block_read += padding;
}
@@ -1238,7 +1241,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
option_content = (char *)g_try_malloc(opt_cont_buf_len);
if (opt_cont_buf_len != 0 && option_content == NULL) {
*err = ENOMEM; /* we assume we're out of memory */
- return -1;
+ return FALSE;
}
while (to_read != 0) {
@@ -1246,7 +1249,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
if (bytes_read <= 0) {
pcapng_debug0("pcapng_read_packet_block: failed to read option");
- return bytes_read;
+ return FALSE;
}
block_read += bytes_read;
to_read -= bytes_read;
@@ -1317,11 +1320,11 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
pn->byte_swapped, fcslen);
- return block_read;
+ return TRUE;
}
-static int
+static gboolean
pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
{
guint block_read;
@@ -1342,7 +1345,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u of an SPB is less than the minimum SPB size %u",
bh->block_total_length, MIN_SPB_SIZE);
- return -1;
+ return FALSE;
}
/* Don't try to allocate memory for a huge number of options, as
@@ -1357,20 +1360,20 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
bh->block_total_length, MAX_BLOCK_SIZE);
- return -1;
+ return FALSE;
}
/* "Simple Packet Block" read fixed part */
if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
pcapng_debug0("pcapng_read_simple_packet_block: failed to read packet data");
- return -1;
+ return FALSE;
}
block_read = (guint)sizeof spb;
if (0 >= pn->interfaces->len) {
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: SPB appeared before any IDBs");
- return -1;
+ return FALSE;
}
iface_info = g_array_index(pn->interfaces, interface_info_t, 0);
@@ -1419,14 +1422,14 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u of PB is too small for %u bytes of packet data",
block_total_length, simple_packet.packet_len);
- return -1;
+ return FALSE;
}
if (simple_packet.cap_len > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u",
simple_packet.cap_len, WTAP_MAX_PACKET_SIZE);
- return -1;
+ return FALSE;
}
pcapng_debug1("pcapng_read_simple_packet_block: packet data: packet_len %u",
simple_packet.packet_len);
@@ -1457,7 +1460,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
err,
err_info);
if (pseudo_header_len < 0) {
- return pseudo_header_len;
+ return FALSE;
}
wblock->packet_header->caplen = simple_packet.cap_len - pseudo_header_len;
wblock->packet_header->len = simple_packet.packet_len - pseudo_header_len;
@@ -1472,20 +1475,20 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
/* "Simple Packet Block" read capture data */
if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
simple_packet.cap_len, err, err_info))
- return -1;
+ return FALSE;
block_read += simple_packet.cap_len;
/* jump over potential padding bytes at end of the packet data */
if ((simple_packet.cap_len % 4) != 0) {
if (!file_skip(fh, 4 - (simple_packet.cap_len % 4), err))
- return -1;
+ return FALSE;
block_read += 4 - (simple_packet.cap_len % 4);
}
pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
pn->byte_swapped, pn->if_fcslen);
- return block_read;
+ return TRUE;
}
#define NRES_ENDOFRECORD 0
@@ -1532,10 +1535,10 @@ name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
return namelen + 1;
}
-static int
+static gboolean
pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock _U_,int *err, gchar **err_info)
{
- int block_read = 0;
+ int block_read;
int to_read;
pcapng_name_resolution_block_t nrb;
Buffer nrb_rec;
@@ -1554,7 +1557,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u of an NRB is less than the minimum NRB size %u",
bh->block_total_length, MIN_NRB_SIZE);
- return -1;
+ return FALSE;
}
/* Don't try to allocate memory for a huge number of options, as
@@ -1569,7 +1572,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
bh->block_total_length, MAX_BLOCK_SIZE);
- return -1;
+ return FALSE;
}
to_read = bh->block_total_length - 8 - 4; /* We have read the header adn should not read the final block_total_length */
@@ -1581,6 +1584,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
* 64-byte name; we'll make the buffer bigger if necessary.
*/
ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
+ block_read = 0;
while (block_read < to_read) {
/*
* There must be at least one record's worth of data
@@ -1592,12 +1596,12 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
to_read - block_read,
(guint)sizeof nrb);
- return -1;
+ return FALSE;
}
if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
ws_buffer_free(&nrb_rec);
pcapng_debug0("pcapng_read_name_resolution_block: failed to read record header");
- return -1;
+ return FALSE;
}
block_read += (int)sizeof nrb;
@@ -1612,7 +1616,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
to_read - block_read,
nrb.record_len + PADDING4(nrb.record_len));
- return -1;
+ return FALSE;
}
switch (nrb.record_type) {
case NRES_ENDOFRECORD:
@@ -1639,14 +1643,14 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
nrb.record_len);
- return -1;
+ return FALSE;
}
ws_buffer_assure_space(&nrb_rec, nrb.record_len);
if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
nrb.record_len, err, err_info)) {
ws_buffer_free(&nrb_rec);
pcapng_debug0("pcapng_read_name_resolution_block: failed to read IPv4 record data");
- return -1;
+ return FALSE;
}
block_read += nrb.record_len;
@@ -1669,7 +1673,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
if (namelen == -1) {
ws_buffer_free(&nrb_rec);
- return -1; /* fail */
+ return FALSE; /* fail */
}
pn->add_new_ipv4(v4_addr, namep);
}
@@ -1677,7 +1681,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
ws_buffer_free(&nrb_rec);
- return -1;
+ return FALSE;
}
block_read += PADDING4(nrb.record_len);
break;
@@ -1701,20 +1705,20 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
nrb.record_len);
- return -1;
+ return FALSE;
}
if (to_read < nrb.record_len) {
ws_buffer_free(&nrb_rec);
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u > remaining data in NRB",
nrb.record_len);
- return -1;
+ return FALSE;
}
ws_buffer_assure_space(&nrb_rec, nrb.record_len);
if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
nrb.record_len, err, err_info)) {
ws_buffer_free(&nrb_rec);
- return -1;
+ return FALSE;
}
block_read += nrb.record_len;
@@ -1729,7 +1733,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
if (namelen == -1) {
ws_buffer_free(&nrb_rec);
- return -1; /* fail */
+ return FALSE; /* fail */
}
pn->add_new_ipv6(ws_buffer_start_ptr(&nrb_rec),
namep);
@@ -1738,7 +1742,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
ws_buffer_free(&nrb_rec);
- return -1;
+ return FALSE;
}
block_read += PADDING4(nrb.record_len);
break;
@@ -1746,7 +1750,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
pcapng_debug1("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
if (!file_skip(fh, nrb.record_len + PADDING4(nrb.record_len), err)) {
ws_buffer_free(&nrb_rec);
- return -1;
+ return FALSE;
}
block_read += nrb.record_len + PADDING4(nrb.record_len);
break;
@@ -1754,14 +1758,13 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
}
ws_buffer_free(&nrb_rec);
- return block_read;
+ return TRUE;
}
-static int
+static gboolean
pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock,int *err, gchar **err_info)
{
int bytes_read;
- guint block_read;
guint to_read, opt_cont_buf_len;
pcapng_interface_statistics_block_t isb;
pcapng_option_header_t oh;
@@ -1777,7 +1780,7 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too small (< %u)",
bh->block_total_length, MIN_ISB_SIZE);
- return -1;
+ return FALSE;
}
/* Don't try to allocate memory for a huge number of options, as
@@ -1792,15 +1795,14 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
bh->block_total_length, MAX_BLOCK_SIZE);
- return -1;
+ return FALSE;
}
/* "Interface Statistics Block" read fixed part */
if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
pcapng_debug0("pcapng_read_interface_statistics_block: failed to read packet data");
- return -1;
+ return FALSE;
}
- block_read = (guint)sizeof isb;
if (pn->byte_swapped) {
wblock->data.if_stats.interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
@@ -1823,14 +1825,14 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
/* Options */
to_read = bh->block_total_length -
- (MIN_BLOCK_SIZE + block_read); /* fixed and variable part, including padding */
+ (MIN_BLOCK_SIZE + (guint)sizeof isb); /* fixed and variable part, including padding */
/* Allocate enough memory to hold all options */
opt_cont_buf_len = to_read;
option_content = (char *)g_try_malloc(opt_cont_buf_len);
if (opt_cont_buf_len != 0 && option_content == NULL) {
*err = ENOMEM; /* we assume we're out of memory */
- return -1;
+ return FALSE;
}
while (to_read != 0) {
@@ -1838,9 +1840,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
if (bytes_read <= 0) {
pcapng_debug0("pcapng_read_interface_statistics_block: failed to read option");
- return bytes_read;
+ return FALSE;
}
- block_read += bytes_read;
to_read -= bytes_read;
/* handle option content */
@@ -1975,11 +1976,11 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
g_free(option_content);
- return block_read;
+ return TRUE;
}
-static int
+static gboolean
pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock _U_, int *err, gchar **err_info)
{
int block_read;
@@ -1992,7 +1993,7 @@ pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("pcapng_read_unknown_block: total block length %u of an unknown block type is less than the minimum block size %u",
bh->block_total_length, MIN_BLOCK_SIZE);
- return -1;
+ return FALSE;
}
/* add padding bytes to "block total length" */
@@ -2016,25 +2017,25 @@ pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_
if (!handler->read(fh, block_read, pn->byte_swapped,
wblock->packet_header, wblock->frame_buffer,
err, err_info))
- return -1;
+ return FALSE;
} else
#endif
{
/* No. Skip over this unknown block. */
if (!file_skip(fh, block_read, err)) {
- return -1;
+ return FALSE;
}
}
- return block_read;
+ return TRUE;
}
-static int
-pcapng_read_block(wtap *wth, FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
+static block_return_val
+pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
{
+ block_return_val ret;
int block_read;
- int bytes_read;
pcapng_block_header_t bh;
guint32 block_total_length;
@@ -2044,15 +2045,19 @@ pcapng_read_block(wtap *wth, FILE_T fh, gboolean first_block, pcapng_t *pn, wtap
if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
pcapng_debug1("pcapng_read_block: wtap_read_bytes_or_eof() failed, err = %d.", *err);
if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
- if (first_block) {
- /* short read or EOF, probably not a pcap-ng file */
- return -2;
- }
- if (*err == 0) {
- return 0; /* EOF */
- }
+ /*
+ * Short read or EOF.
+ *
+ * If we're reading this as part of an open,
+ * the file is too short to be a pcap-ng file.
+ *
+ * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
+ * PCAPNG_BLOCK_ERROR the same, so we can just return
+ * PCAPNG_BLOCK_NOT_SHB in both cases.
+ */
+ return PCAPNG_BLOCK_NOT_SHB;
}
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
block_read = sizeof bh;
@@ -2065,72 +2070,75 @@ pcapng_read_block(wtap *wth, FILE_T fh, gboolean first_block, pcapng_t *pn, wtap
pcapng_debug1("pcapng_read_block: block_type 0x%x", bh.block_type);
- if (first_block) {
- /*
- * This is being read in by pcapng_open(), so this block
- * must be an SHB. If it's not, this is not a pcap-ng
- * file.
- *
- * XXX - check for various forms of Windows <-> UN*X
- * mangling, and suggest that the file might be a
- * pcap-ng file that was damaged in transit?
- */
- if (bh.block_type != BLOCK_TYPE_SHB)
- return -2; /* not a pcap-ng file */
- }
-
- switch (bh.block_type) {
- case(BLOCK_TYPE_SHB):
- bytes_read = pcapng_read_section_header_block(fh, first_block, &bh, pn, wblock, err, err_info);
- break;
- case(BLOCK_TYPE_IDB):
- bytes_read = pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info);
- break;
- case(BLOCK_TYPE_PB):
- bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE);
- break;
- case(BLOCK_TYPE_SPB):
- bytes_read = pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info);
- break;
- case(BLOCK_TYPE_EPB):
- bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE);
- break;
- case(BLOCK_TYPE_NRB):
- bytes_read = pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info);
- break;
- case(BLOCK_TYPE_ISB):
- bytes_read = pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info);
- break;
- default:
- pcapng_debug2("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
- bytes_read = pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info);
- break;
- }
-
- if (bytes_read <= 0) {
- return bytes_read;
+ /*
+ * SHBs have to be treated differently from other blocks, as we
+ * might be doing an open and attempting to read a block at the
+ * beginning of the file to see if it's a pcap-ng file or not.
+ */
+ if (bh.block_type == BLOCK_TYPE_SHB) {
+ ret = pcapng_read_section_header_block(fh, &bh, pn, wblock, err, err_info);
+ if (ret != PCAPNG_BLOCK_OK) {
+ return ret;
+ }
+ } else {
+ if (!pn->shb_read) {
+ /*
+ * No SHB seen yet, so we're trying to read the first block
+ * during an open; if what we read isn't an SHB, this isn't
+ * a pcap-ng file.
+ */
+ return PCAPNG_BLOCK_NOT_SHB;
+ }
+ switch (bh.block_type) {
+ case(BLOCK_TYPE_IDB):
+ if (!pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info))
+ return PCAPNG_BLOCK_ERROR;
+ break;
+ case(BLOCK_TYPE_PB):
+ if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE))
+ return PCAPNG_BLOCK_ERROR;
+ break;
+ case(BLOCK_TYPE_SPB):
+ if (!pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info))
+ return PCAPNG_BLOCK_ERROR;
+ break;
+ case(BLOCK_TYPE_EPB):
+ if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE))
+ return PCAPNG_BLOCK_ERROR;
+ break;
+ case(BLOCK_TYPE_NRB):
+ if (!pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info))
+ return PCAPNG_BLOCK_ERROR;
+ break;
+ case(BLOCK_TYPE_ISB):
+ if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
+ return PCAPNG_BLOCK_ERROR;
+ break;
+ default:
+ pcapng_debug2("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
+ if (!pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info))
+ return PCAPNG_BLOCK_ERROR;
+ break;
+ }
}
- block_read += bytes_read;
/* sanity check: first and second block lengths must match */
if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
err, err_info)) {
- pcapng_debug0("pcapng_read_block: couldn't read second block length");
- return -1;
+ pcapng_debug0("pcapng_check_block_trailer: couldn't read second block length");
+ return PCAPNG_BLOCK_ERROR;
}
- block_read += bytes_read;
if (pn->byte_swapped)
block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
- if (!(block_total_length == bh.block_total_length)) {
+ if (block_total_length != bh.block_total_length) {
*err = WTAP_ERR_BAD_FILE;
- *err_info = g_strdup_printf("pcapng_read_block: total block lengths (first %u and second %u) don't match",
+ *err_info = g_strdup_printf("pcapng_check_block_trailer: total block lengths (first %u and second %u) don't match",
bh.block_total_length, block_total_length);
- return -1;
+ return PCAPNG_BLOCK_ERROR;
}
-
- return block_read;
+ return PCAPNG_BLOCK_OK;
}
/* Process an IDB that we've just read. */
@@ -2179,7 +2187,6 @@ pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
wtap_open_return_val
pcapng_open(wtap *wth, int *err, gchar **err_info)
{
- int bytes_read;
pcapng_t pn;
wtapng_block_t wblock;
pcapng_t *pcapng;
@@ -2201,17 +2208,24 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
pcapng_debug0("pcapng_open: opening file");
/* read first block */
- bytes_read = pcapng_read_block(wth, wth->fh, TRUE, &pn, &wblock, err, err_info);
- if (bytes_read <= 0) {
+ switch (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info)) {
+
+ case PCAPNG_BLOCK_OK:
+ /* No problem */
+ break;
+
+ case PCAPNG_BLOCK_NOT_SHB:
+ /* An error indicating that this isn't a pcap-ng file. */
pcapng_free_wtapng_block_data(&wblock);
- if (bytes_read == -2) {
- pcapng_debug0("pcapng_open: doesn't begin with SHB, probably not a pcap-ng file");
- return WTAP_OPEN_NOT_MINE;
- }
- pcapng_debug0("pcapng_open: couldn't read first SHB");
- if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
- return WTAP_OPEN_ERROR;
+ g_free(*err_info); /* We don't care why */
+ *err = 0;
+ *err_info = NULL;
return WTAP_OPEN_NOT_MINE;
+
+ case PCAPNG_BLOCK_ERROR:
+ /* An I/O error, or this probably *is* a pcap-ng file but not a valid one. */
+ pcapng_free_wtapng_block_data(&wblock);
+ return WTAP_OPEN_ERROR;
}
/* first block must be a "Section Header Block" */
@@ -2277,18 +2291,16 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
if (bh.block_type != BLOCK_TYPE_IDB) {
break; /* No more IDB:s */
}
- bytes_read = pcapng_read_block(wth, wth->fh, FALSE, &pn, &wblock, err, err_info);
- if (bytes_read == 0) {
- pcapng_debug0("No more IDBs available...");
- pcapng_free_wtapng_block_data(&wblock);
- break;
- }
- if (bytes_read <= 0) {
- pcapng_debug0("pcapng_open: couldn't read IDB");
- pcapng_free_wtapng_block_data(&wblock);
- if (*err == 0)
- *err = WTAP_ERR_SHORT_READ;
- return WTAP_OPEN_ERROR;
+ if (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
+ if (*err == 0) {
+ pcapng_debug0("No more IDBs available...");
+ pcapng_free_wtapng_block_data(&wblock);
+ break;
+ } else {
+ pcapng_debug0("pcapng_open: couldn't read IDB");
+ pcapng_free_wtapng_block_data(&wblock);
+ return WTAP_OPEN_ERROR;
+ }
}
pcapng_process_idb(wth, pcapng, &wblock);
pcapng_debug2("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i",
@@ -2303,7 +2315,6 @@ static gboolean
pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{
pcapng_t *pcapng = (pcapng_t *)wth->priv;
- int bytes_read;
wtapng_block_t wblock;
wtapng_if_descr_t *wtapng_if_descr;
wtapng_if_stats_t if_stats;
@@ -2318,8 +2329,7 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
while (1) {
*data_offset = file_tell(wth->fh);
pcapng_debug1("pcapng_read: data_offset is %" G_GINT64_MODIFIER "d", *data_offset);
- bytes_read = pcapng_read_block(wth, wth->fh, FALSE, pcapng, &wblock, err, err_info);
- if (bytes_read <= 0) {
+ if (pcapng_read_block(wth, wth->fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
pcapng_debug1("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
pcapng_debug0("pcapng_read: couldn't read packet block");
return FALSE;
@@ -2407,7 +2417,7 @@ pcapng_seek_read(wtap *wth, gint64 seek_off,
int *err, gchar **err_info)
{
pcapng_t *pcapng = (pcapng_t *)wth->priv;
- int bytes_read;
+ block_return_val ret;
wtapng_block_t wblock;
@@ -2421,9 +2431,9 @@ pcapng_seek_read(wtap *wth, gint64 seek_off,
wblock.packet_header = phdr;
/* read the block */
- bytes_read = pcapng_read_block(wth, wth->random_fh, FALSE, pcapng, &wblock, err, err_info);
+ ret = pcapng_read_block(wth, wth->random_fh, pcapng, &wblock, err, err_info);
pcapng_free_wtapng_block_data(&wblock);
- if (bytes_read <= 0) {
+ if (ret != PCAPNG_BLOCK_OK) {
pcapng_debug3("pcapng_seek_read: couldn't read packet block (err=%d, errno=%d, bytes_read=%d).",
*err, errno, bytes_read);
return FALSE;