forked from osmocom/wireshark
decode IDB options (if_tsaccur and if_fcslen)
svn path=/trunk/; revision=24133
This commit is contained in:
parent
042dc7258e
commit
31be5fa705
157
wiretap/pcapng.c
157
wiretap/pcapng.c
|
@ -102,6 +102,13 @@ typedef struct pcapng_enhanced_packet_block_s {
|
||||||
/* ... Options ... */
|
/* ... Options ... */
|
||||||
} pcapng_enhanced_packet_block_t;
|
} pcapng_enhanced_packet_block_t;
|
||||||
|
|
||||||
|
/* pcapng: common option header for every option type */
|
||||||
|
typedef struct pcapng_option_header_s {
|
||||||
|
guint16 option_code;
|
||||||
|
guint16 option_length;
|
||||||
|
/* x bytes option_body */
|
||||||
|
/* alignment to 32 bits */
|
||||||
|
} pcapng_option_header_t;
|
||||||
|
|
||||||
/* Block types */
|
/* Block types */
|
||||||
#define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */
|
#define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */
|
||||||
|
@ -113,6 +120,7 @@ typedef struct pcapng_enhanced_packet_block_s {
|
||||||
#define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */
|
#define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Capture section */
|
/* Capture section */
|
||||||
typedef struct wtapng_section_s {
|
typedef struct wtapng_section_s {
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
|
@ -288,9 +296,12 @@ static int
|
||||||
pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info _U_)
|
pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info _U_)
|
||||||
{
|
{
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
|
int block_read;
|
||||||
int to_read;
|
int to_read;
|
||||||
guint64 file_offset64;
|
guint64 file_offset64;
|
||||||
pcapng_interface_description_block_t idb;
|
pcapng_interface_description_block_t idb;
|
||||||
|
pcapng_option_header_t oh;
|
||||||
|
char option_content[100];
|
||||||
|
|
||||||
|
|
||||||
/* read block content */
|
/* read block content */
|
||||||
|
@ -303,8 +314,9 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, w
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
block_read = bytes_read;
|
||||||
|
|
||||||
/* mandatory */
|
/* mandatory value */
|
||||||
if(pn->byte_swapped) {
|
if(pn->byte_swapped) {
|
||||||
wblock->data.if_descr.link_type = BSWAP16(idb.linktype);
|
wblock->data.if_descr.link_type = BSWAP16(idb.linktype);
|
||||||
wblock->data.if_descr.snap_len = BSWAP32(idb.snaplen);
|
wblock->data.if_descr.snap_len = BSWAP32(idb.snaplen);
|
||||||
|
@ -326,18 +338,7 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, w
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX - we ignore IDB options for now */
|
/* default values for IDB options */
|
||||||
/* jump over the Options (and the repeated block length at the end) */
|
|
||||||
errno = WTAP_ERR_CANT_READ;
|
|
||||||
to_read = bh->block_total_length - sizeof(pcapng_block_header_t) - sizeof (pcapng_interface_description_block_t);
|
|
||||||
file_offset64 = file_seek(fh, to_read, SEEK_CUR, err);
|
|
||||||
if (file_offset64 <= 0) {
|
|
||||||
if (*err != 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* options */
|
|
||||||
wblock->data.if_descr.opt_comment = NULL;
|
wblock->data.if_descr.opt_comment = NULL;
|
||||||
wblock->data.if_descr.if_name = NULL;
|
wblock->data.if_descr.if_name = NULL;
|
||||||
wblock->data.if_descr.if_description = NULL;
|
wblock->data.if_descr.if_description = NULL;
|
||||||
|
@ -352,7 +353,105 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, w
|
||||||
wblock->data.if_descr.if_fcslen = (gchar) -1; /* unknown or changes between packets */
|
wblock->data.if_descr.if_fcslen = (gchar) -1; /* unknown or changes between packets */
|
||||||
/* XXX: guint64 if_tsoffset; */
|
/* XXX: guint64 if_tsoffset; */
|
||||||
|
|
||||||
return bytes_read + to_read;
|
|
||||||
|
/* IDB options */
|
||||||
|
errno = WTAP_ERR_CANT_READ;
|
||||||
|
to_read = bh->block_total_length - sizeof(pcapng_block_header_t) - sizeof (pcapng_interface_description_block_t);
|
||||||
|
while(to_read > 0) {
|
||||||
|
/* read option header */
|
||||||
|
errno = WTAP_ERR_CANT_READ;
|
||||||
|
bytes_read = file_read(&oh, 1, sizeof oh, fh);
|
||||||
|
if (bytes_read != sizeof oh) {
|
||||||
|
g_warning("pcapng_read_if_descr_block: failed to read option");
|
||||||
|
*err = file_error(fh);
|
||||||
|
if (*err != 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
block_read += sizeof oh;
|
||||||
|
to_read -= sizeof oh;
|
||||||
|
if(pn->byte_swapped) {
|
||||||
|
oh.option_code = BSWAP16(oh.option_code);
|
||||||
|
oh.option_length = BSWAP32(oh.option_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity check: option length */
|
||||||
|
/* XXX - might need to be increased, if we see longer options */
|
||||||
|
if (oh.option_length > sizeof option_content) {
|
||||||
|
g_warning("pcapng_read_if_descr_block: option_length %u seems pretty large", oh.option_length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read option content */
|
||||||
|
errno = WTAP_ERR_CANT_READ;
|
||||||
|
bytes_read = file_read(option_content, 1, oh.option_length, fh);
|
||||||
|
if (bytes_read != oh.option_length) {
|
||||||
|
g_warning("pcapng_read_if_descr_block: failed to read content of option %u", oh.option_code);
|
||||||
|
*err = file_error(fh);
|
||||||
|
if (*err != 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
block_read += oh.option_length;
|
||||||
|
to_read -= oh.option_length;
|
||||||
|
|
||||||
|
/* handle option content */
|
||||||
|
switch(oh.option_code) {
|
||||||
|
case(0): /* opt_endofopt */
|
||||||
|
if(to_read != 4) {
|
||||||
|
g_warning("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read - 4);
|
||||||
|
}
|
||||||
|
/* padding should be ok here, just get out of this */
|
||||||
|
to_read = 0;
|
||||||
|
break;
|
||||||
|
case(9): /* if_tsaccur */
|
||||||
|
if(oh.option_length == 1) {
|
||||||
|
wblock->data.if_descr.if_tsaccur = option_content[0];
|
||||||
|
g_warning("pcapng_read_if_descr_block: if_tsaccur %u", wblock->data.if_descr.if_tsaccur);
|
||||||
|
} else {
|
||||||
|
g_warning("pcapng_read_if_descr_block: if_tsaccur length %u not 1 as expected", oh.option_length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case(13): /* if_fcslen */
|
||||||
|
if(oh.option_length == 1) {
|
||||||
|
wblock->data.if_descr.if_fcslen = option_content[0];
|
||||||
|
pn->if_fcslen = wblock->data.if_descr.if_fcslen;
|
||||||
|
g_warning("pcapng_read_if_descr_block: if_fcslen %u", wblock->data.if_descr.if_fcslen);
|
||||||
|
/* XXX - add sanity check */
|
||||||
|
} else {
|
||||||
|
g_warning("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warning("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
|
||||||
|
oh.option_code, oh.option_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* jump over potential padding bytes at end of option */
|
||||||
|
if( (oh.option_length % 4) != 0) {
|
||||||
|
file_offset64 = file_seek(fh, 4 - (oh.option_length % 4), SEEK_CUR, err);
|
||||||
|
if (file_offset64 <= 0) {
|
||||||
|
if (*err != 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
block_read += 4 - (oh.option_length % 4);
|
||||||
|
to_read -= 4 - (oh.option_length % 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* jump over the repeated block length at the end of the block */
|
||||||
|
/* XXX - add a sanity check here? */
|
||||||
|
file_offset64 = file_seek(fh, 4, SEEK_CUR, err);
|
||||||
|
if (file_offset64 <= 0) {
|
||||||
|
if (*err != 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
block_read += 4;
|
||||||
|
|
||||||
|
return block_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,15 +493,13 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
||||||
/*g_warning("pcapng_read_packet_block: packet data: packet_len %u captured_len %u",
|
/*g_warning("pcapng_read_packet_block: packet data: packet_len %u captured_len %u",
|
||||||
wblock->data.packet.packet_len, wblock->data.packet.cap_len);*/
|
wblock->data.packet.packet_len, wblock->data.packet.cap_len);*/
|
||||||
|
|
||||||
/* XXX - convert timestamps into nsecs */
|
/* xxx - convert timestamps if we have an odd if_tsaccur */
|
||||||
|
|
||||||
/* XXX - implement other linktypes then Ethernet */
|
/* XXX - implement other linktypes then Ethernet */
|
||||||
/* (or even better share the code with libpcap.c) */
|
/* (or even better share the code with libpcap.c) */
|
||||||
|
|
||||||
/*
|
/* Ethernet FCS length, might be overwritten by "per packet" options */
|
||||||
* We don't know whether there's an FCS in this frame or not.
|
((union wtap_pseudo_header *) wblock->pseudo_header)->eth.fcs_len = pn->if_fcslen;
|
||||||
*/
|
|
||||||
((union wtap_pseudo_header *) wblock->pseudo_header)->eth.fcs_len = -1;
|
|
||||||
|
|
||||||
errno = WTAP_ERR_CANT_READ;
|
errno = WTAP_ERR_CANT_READ;
|
||||||
bytes_read = file_read((guchar *) (wblock->frame_buffer), 1, wblock->data.packet.cap_len, fh);
|
bytes_read = file_read((guchar *) (wblock->frame_buffer), 1, wblock->data.packet.cap_len, fh);
|
||||||
|
@ -452,7 +549,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We read the packet successfully. */
|
/* We read the packet successfully. */
|
||||||
return read_len + to_read;
|
return read_len + to_read + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -519,7 +616,9 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
|
||||||
|
|
||||||
/* we don't know the byte swapping of the file yet */
|
/* we don't know the byte swapping of the file yet */
|
||||||
pn.byte_swapped = FALSE;
|
pn.byte_swapped = FALSE;
|
||||||
|
pn.if_fcslen = -1;
|
||||||
|
pn.version_major = -1;
|
||||||
|
pn.version_minor = -1;
|
||||||
|
|
||||||
/* we don't expect any packet blocks yet */
|
/* we don't expect any packet blocks yet */
|
||||||
wblock.frame_buffer = NULL;
|
wblock.frame_buffer = NULL;
|
||||||
|
@ -576,7 +675,17 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
|
||||||
wth->subtype_close = pcapng_close;
|
wth->subtype_close = pcapng_close;
|
||||||
|
|
||||||
wth->file_type = WTAP_FILE_PCAPNG;
|
wth->file_type = WTAP_FILE_PCAPNG;
|
||||||
wth->tsprecision = WTAP_FILE_TSPREC_USEC; /* default is usec, might be overwritten with if_tsaccur option */
|
switch(wblock.data.if_descr.if_tsaccur) {
|
||||||
|
case(6):
|
||||||
|
wth->tsprecision = WTAP_FILE_TSPREC_USEC; /* usec is the default (without the if_tsaccur option) */
|
||||||
|
break;
|
||||||
|
case(9):
|
||||||
|
wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warning("pcapng_open: if_tsaccur %u not implemented, timestamp conversion omitted",
|
||||||
|
wblock.data.if_descr.if_tsaccur);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -619,10 +728,10 @@ pcapng_read(wtap *wth, int *err, gchar **err_info,
|
||||||
wth->phdr.caplen = wblock.data.packet.cap_len;
|
wth->phdr.caplen = wblock.data.packet.cap_len;
|
||||||
wth->phdr.len = wblock.data.packet.packet_len;
|
wth->phdr.len = wblock.data.packet.packet_len;
|
||||||
wth->phdr.ts.secs = wblock.data.packet.ts_high;
|
wth->phdr.ts.secs = wblock.data.packet.ts_high;
|
||||||
wth->phdr.ts.nsecs = wblock.data.packet.ts_low; /* convert here? */
|
wth->phdr.ts.nsecs = wblock.data.packet.ts_low;
|
||||||
|
|
||||||
/*g_warning("Read length: %u Packet length: %u", bytes_read, wth->phdr.caplen);*/
|
/*g_warning("Read length: %u Packet length: %u", bytes_read, wth->phdr.caplen);*/
|
||||||
wth->data_offset += bytes_read + 4;
|
wth->data_offset += bytes_read;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
} else {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -100,6 +100,7 @@ typedef struct {
|
||||||
gboolean byte_swapped;
|
gboolean byte_swapped;
|
||||||
guint16 version_major;
|
guint16 version_major;
|
||||||
guint16 version_minor;
|
guint16 version_minor;
|
||||||
|
guint8 if_fcslen;
|
||||||
} pcapng_t;
|
} pcapng_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in New Issue