Strengthen the I4B heuristics.
Check some more field values, and fix some tests to check against the maximum possible value given in the i4b_trace.h file rather than against that value + 1. (> max, or >= max+1, are both reasonable, but > max+1 isn't.) Check the first few packets, not just the first packet. Make some header fields unsigned, as that's how we treat them in most cases; that way we treat them that way by default. Change-Id: I8c2d28af048c676a3dbae367bbb49c886e0dc566 Ping-Bug: 16031 Reviewed-on: https://code.wireshark.org/review/34432 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
fc2260c0b0
commit
cdb942944a
|
@ -15,8 +15,8 @@
|
|||
*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
guint32 length; /* length of the following mbuf */
|
||||
gint32 unit; /* controller unit number */
|
||||
gint32 type; /* type of channel */
|
||||
guint32 unit; /* controller unit number */
|
||||
guint32 type; /* type of channel */
|
||||
#define TRC_CH_I 0 /* Layer 1 INFO's */
|
||||
#define TRC_CH_D 1 /* D channel */
|
||||
#define TRC_CH_B1 2 /* B1 channel */
|
||||
|
@ -24,7 +24,7 @@ typedef struct {
|
|||
gint32 dir; /* direction */
|
||||
#define FROM_TE 0 /* user -> network */
|
||||
#define FROM_NT 1 /* network -> user */
|
||||
gint32 trunc; /* # of truncated bytes (frame > MCLBYTES) */
|
||||
guint32 trunc; /* # of truncated bytes (frame > MCLBYTES) */
|
||||
guint32 count; /* frame count for this unit/type */
|
||||
guint32 ts_sec; /* timestamp seconds */
|
||||
guint32 ts_usec; /* timestamp microseconds */
|
||||
|
|
|
@ -27,13 +27,37 @@ static gboolean i4btrace_seek_read(wtap *wth, gint64 seek_off,
|
|||
static int i4b_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info);
|
||||
|
||||
/*
|
||||
* Byte-swap the header.
|
||||
*/
|
||||
#define I4B_BYTESWAP_HEADER(hdr) \
|
||||
{ \
|
||||
hdr.length = GUINT32_SWAP_LE_BE(hdr.length); \
|
||||
hdr.unit = GUINT32_SWAP_LE_BE(hdr.unit); \
|
||||
hdr.type = GUINT32_SWAP_LE_BE(hdr.type); \
|
||||
hdr.dir = GUINT32_SWAP_LE_BE(hdr.dir); \
|
||||
hdr.trunc = GUINT32_SWAP_LE_BE(hdr.trunc); \
|
||||
hdr.count = GUINT32_SWAP_LE_BE(hdr.count); \
|
||||
hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr.ts_sec); \
|
||||
hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr.ts_usec); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Test some fields in the header to see if they make sense.
|
||||
*/
|
||||
#define I4B_HDR_IS_OK(hdr) \
|
||||
(!((unsigned int)hdr.length < 3 || (unsigned int)hdr.length > 16384 || \
|
||||
(unsigned int)hdr.unit > 4 || (unsigned int)hdr.type > 4 || \
|
||||
(unsigned int)hdr.dir > 2 || (unsigned int)hdr.trunc > 2048))
|
||||
(!(hdr.length < sizeof(hdr) || \
|
||||
hdr.length > 16384 || \
|
||||
hdr.unit > 4 || \
|
||||
hdr.type > TRC_CH_B2 || \
|
||||
hdr.dir > FROM_NT || \
|
||||
hdr.trunc > 2048 || \
|
||||
hdr.ts_usec >= 1000000))
|
||||
|
||||
/*
|
||||
* Number of packets to try reading.
|
||||
*/
|
||||
#define PACKETS_TO_CHECK 5
|
||||
|
||||
wtap_open_return_val i4btrace_open(wtap *wth, int *err, gchar **err_info)
|
||||
{
|
||||
|
@ -53,11 +77,7 @@ wtap_open_return_val i4btrace_open(wtap *wth, int *err, gchar **err_info)
|
|||
/*
|
||||
* OK, try byte-swapping the header fields.
|
||||
*/
|
||||
hdr.length = GUINT32_SWAP_LE_BE(hdr.length);
|
||||
hdr.unit = GUINT32_SWAP_LE_BE(hdr.unit);
|
||||
hdr.type = GUINT32_SWAP_LE_BE(hdr.type);
|
||||
hdr.dir = GUINT32_SWAP_LE_BE(hdr.dir);
|
||||
hdr.trunc = GUINT32_SWAP_LE_BE(hdr.trunc);
|
||||
I4B_BYTESWAP_HEADER(hdr);
|
||||
if (!I4B_HDR_IS_OK(hdr)) {
|
||||
/*
|
||||
* It doesn't look valid in either byte order.
|
||||
|
@ -72,6 +92,63 @@ wtap_open_return_val i4btrace_open(wtap *wth, int *err, gchar **err_info)
|
|||
byte_swapped = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now try to read past the packet bytes; if that fails with
|
||||
* a short read, we don't fail, so that we can report
|
||||
* the file as a truncated I4B file.
|
||||
*/
|
||||
if (!wtap_read_bytes(wth->fh, NULL, hdr.length - (guint32)sizeof(hdr),
|
||||
err, err_info)) {
|
||||
if (*err != WTAP_ERR_SHORT_READ)
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now try reading a few more packets.
|
||||
*/
|
||||
for (int i = 1; i < PACKETS_TO_CHECK; i++) {
|
||||
/*
|
||||
* Read and check the file header; we've already
|
||||
* decided whether this would be a byte-swapped file
|
||||
* or not, so we swap iff we decided it was.
|
||||
*/
|
||||
if (!wtap_read_bytes_or_eof(wth->fh, &hdr, sizeof(hdr), err,
|
||||
err_info)) {
|
||||
if (*err == 0) {
|
||||
/* EOF; no more packets to try. */
|
||||
break;
|
||||
}
|
||||
if (*err != WTAP_ERR_SHORT_READ)
|
||||
return WTAP_OPEN_ERROR;
|
||||
return WTAP_OPEN_NOT_MINE;
|
||||
}
|
||||
|
||||
if (byte_swapped)
|
||||
I4B_BYTESWAP_HEADER(hdr);
|
||||
if (!I4B_HDR_IS_OK(hdr)) {
|
||||
/*
|
||||
* It doesn't look valid in either byte order.
|
||||
*/
|
||||
return WTAP_OPEN_NOT_MINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now try to read past the packet bytes; if that fails with
|
||||
* a short read, we don't fail, so that we can report
|
||||
* the file as a truncated I4B file.
|
||||
*/
|
||||
if (!wtap_read_bytes(wth->fh, NULL, hdr.length - (guint32)sizeof(hdr),
|
||||
err, err_info)) {
|
||||
if (*err != WTAP_ERR_SHORT_READ)
|
||||
return WTAP_OPEN_ERROR;
|
||||
|
||||
/*
|
||||
* Probably a truncated file, so just quit.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
|
||||
return WTAP_OPEN_ERROR;
|
||||
|
||||
|
@ -134,14 +211,7 @@ i4b_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf,
|
|||
/*
|
||||
* Byte-swap the header.
|
||||
*/
|
||||
hdr.length = GUINT32_SWAP_LE_BE(hdr.length);
|
||||
hdr.unit = GUINT32_SWAP_LE_BE(hdr.unit);
|
||||
hdr.type = GUINT32_SWAP_LE_BE(hdr.type);
|
||||
hdr.dir = GUINT32_SWAP_LE_BE(hdr.dir);
|
||||
hdr.trunc = GUINT32_SWAP_LE_BE(hdr.trunc);
|
||||
hdr.count = GUINT32_SWAP_LE_BE(hdr.count);
|
||||
hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr.ts_sec);
|
||||
hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr.ts_usec);
|
||||
I4B_BYTESWAP_HEADER(hdr);
|
||||
}
|
||||
|
||||
if (hdr.length < sizeof(hdr)) {
|
||||
|
|
Loading…
Reference in New Issue