camins: improve the heuristics

The current mechanism that reads the first 20 blocks looking for a headerd
oesn't work in all cases. I was given sample files that consist of
data blocks only and have no header.

Use a new approach to detect a .camins file by searching for pairs of
size high + size low blocks, either read or write. Go through the
entire file. If we have significantly more pairs than single, non-matching
blocks, this is a camins file.

Change-Id: Ic91e7db7149b105e26896d1a89cad4a2a73d0f13
Reviewed-on: https://code.wireshark.org/review/19603
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
Petri-Dish: Martin Kaiser <wireshark@kaiser.cx>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Roland Knall <rknall@gmail.com>
This commit is contained in:
Martin Kaiser 2017-01-08 18:04:56 +01:00 committed by Roland Knall
parent 3df81a0550
commit 259989ac1a
2 changed files with 73 additions and 22 deletions

View File

@ -104,6 +104,76 @@ typedef enum {
#define DVB_CI_PSEUDO_HDR_HOST_TO_CAM 0xFE
/* Detect a camins file by looking at the blocks that access the 16bit
size register. The matching blocks to access the upper and lower 8bit
must be no further than 5 blocks apart.
A file may have errors that affect the size blocks. Therefore, we
read the entire file and require that we have much more valid pairs
than errors. */
static gboolean detect_camins_file(FILE_T fh)
{
int err;
gchar *err_info;
guint8 block[2];
guint8 search_block = 0;
guint8 gap_count = 0;
guint32 valid_pairs = 0, invalid_pairs = 0;
while (wtap_read_bytes(fh, block, sizeof(block), &err, &err_info)) {
if (err == WTAP_ERR_SHORT_READ)
break;
if (search_block != 0) {
/* We're searching for a matching block to complete the pair. */
if (block[1] == search_block) {
/* We found it */
valid_pairs++;
search_block = 0;
}
else {
/* We didn't find it. */
gap_count++;
if (gap_count > 5) {
/* Give up the search, we have no pair. */
invalid_pairs++;
search_block = 0;
}
}
}
else {
/* We're not searching for a matching block at the moment.
If we see a size read/write block of one type, the matching
block is the the other type and we can start searching. */
if (block[1] == TRANS_READ_SIZE_LOW) {
search_block = TRANS_READ_SIZE_HIGH;
gap_count = 0;
}
else if (block[1] == TRANS_READ_SIZE_HIGH) {
search_block = TRANS_READ_SIZE_LOW;
gap_count = 0;
}
else if (block[1] == TRANS_WRITE_SIZE_LOW) {
search_block = TRANS_WRITE_SIZE_HIGH;
gap_count = 0;
}
else if (block[1] == TRANS_WRITE_SIZE_HIGH) {
search_block = TRANS_WRITE_SIZE_LOW;
gap_count = 0;
}
}
}
/* For valid_pairs == invalid_pairs == 0, this isn't a camins file.
Don't change > into >= */
if (valid_pairs > 10 * invalid_pairs)
return TRUE;
return FALSE;
}
/* find the transaction type for the data bytes of the next packet
and the number of data bytes in that packet
the fd is moved such that it can be used in a subsequent call
@ -302,28 +372,9 @@ camins_seek_read(wtap *wth, gint64 seek_off,
wtap_open_return_val camins_open(wtap *wth, int *err, gchar **err_info)
wtap_open_return_val camins_open(wtap *wth, int *err, gchar **err_info _U_)
{
guint8 found_start_blocks = 0;
guint8 count = 0;
guint8 block[2];
/* all CAM Inspector files I've looked at have at least two blocks of
0x00 0xE1 within the first 20 bytes */
do {
if (!wtap_read_bytes(wth->fh, block, sizeof(block), err, err_info)) {
if (*err == WTAP_ERR_SHORT_READ)
break;
return WTAP_OPEN_ERROR;
}
if (block[0]==0x00 && block[1] == 0xE1)
found_start_blocks++;
count++;
} while (count<20);
if (found_start_blocks < 2)
if (!detect_camins_file(wth->fh))
return WTAP_OPEN_NOT_MINE; /* no CAM Inspector file */
/* rewind the fh so we re-read from the beginning */

View File

@ -28,6 +28,6 @@
#include <glib.h>
#include <wiretap/wtap.h>
wtap_open_return_val camins_open(wtap *wth, int *err, gchar **err_info);
wtap_open_return_val camins_open(wtap *wth, int *err, gchar **err_info _U_);
#endif /* _CAMINS_H */