forked from osmocom/wireshark
Add a Buffer to wtap_pkthdr to hold file-type-specific packet metadata.
For example, this can be used for pcap-ng options not mapped to file-type-independent metadata values. Change-Id: I398b324c62c1cc1cc61eb5e9631de00481b4aadc Reviewed-on: https://code.wireshark.org/review/5549 Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
35b1bc5ec6
commit
846bb53948
19
file.c
19
file.c
|
@ -310,6 +310,9 @@ cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_temp
|
|||
and fill in the information for this file. */
|
||||
cf_close(cf);
|
||||
|
||||
/* Initialize the packet header. */
|
||||
wtap_phdr_init(&cf->phdr);
|
||||
|
||||
/* XXX - we really want to initialize this after we've read all
|
||||
the packets, so we know how much we'll ultimately need. */
|
||||
ws_buffer_init(&cf->buf, 1500);
|
||||
|
@ -436,6 +439,9 @@ cf_close(capture_file *cf)
|
|||
/* no open_routine type */
|
||||
cf->open_type = WTAP_TYPE_AUTO;
|
||||
|
||||
/* Clean up the packet header. */
|
||||
wtap_phdr_cleanup(&cf->phdr);
|
||||
|
||||
/* Free up the packet buffer. */
|
||||
ws_buffer_free(&cf->buf);
|
||||
|
||||
|
@ -2192,7 +2198,7 @@ process_specified_records(capture_file *cf, packet_range_t *range,
|
|||
range_process_e process_this;
|
||||
struct wtap_pkthdr phdr;
|
||||
|
||||
memset(&phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
wtap_phdr_init(&phdr);
|
||||
ws_buffer_init(&buf, 1500);
|
||||
|
||||
/* Update the progress bar when it gets to this value. */
|
||||
|
@ -2290,6 +2296,7 @@ process_specified_records(capture_file *cf, packet_range_t *range,
|
|||
if (progbar != NULL)
|
||||
destroy_progress_dlg(progbar);
|
||||
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
ws_buffer_free(&buf);
|
||||
|
||||
return ret;
|
||||
|
@ -3942,6 +3949,8 @@ cf_get_user_packet_comment(capture_file *cf, const frame_data *fd)
|
|||
char *
|
||||
cf_get_comment(capture_file *cf, const frame_data *fd)
|
||||
{
|
||||
char *comment;
|
||||
|
||||
/* fetch user comment */
|
||||
if (fd->flags.has_user_comment)
|
||||
return g_strdup(cf_get_user_packet_comment(cf, fd));
|
||||
|
@ -3951,14 +3960,16 @@ cf_get_comment(capture_file *cf, const frame_data *fd)
|
|||
struct wtap_pkthdr phdr; /* Packet header */
|
||||
Buffer buf; /* Packet data */
|
||||
|
||||
memset(&phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
|
||||
wtap_phdr_init(&phdr);
|
||||
ws_buffer_init(&buf, 1500);
|
||||
|
||||
if (!cf_read_record_r(cf, fd, &phdr, &buf))
|
||||
{ /* XXX, what we can do here? */ }
|
||||
|
||||
comment = phdr.opt_comment;
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
ws_buffer_free(&buf);
|
||||
return phdr.opt_comment;
|
||||
return comment;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ frame_cache(struct tvb_frame *frame_tvb)
|
|||
{
|
||||
struct wtap_pkthdr phdr; /* Packet header */
|
||||
|
||||
memset(&phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
wtap_phdr_init(&phdr);
|
||||
|
||||
if (frame_tvb->buf == NULL) {
|
||||
frame_tvb->buf = (struct Buffer *) g_malloc(sizeof(struct Buffer));
|
||||
|
@ -87,6 +87,8 @@ frame_cache(struct tvb_frame *frame_tvb)
|
|||
}
|
||||
|
||||
frame_tvb->tvb.real_data = ws_buffer_start_ptr(frame_tvb->buf) + frame_tvb->offset;
|
||||
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -990,7 +990,7 @@ load_cap_file(capture_file *cf)
|
|||
struct wtap_pkthdr phdr;
|
||||
epan_dissect_t edt;
|
||||
|
||||
memset(&phdr, 0, sizeof(phdr));
|
||||
wtap_phdr_init(&phdr);
|
||||
|
||||
epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
|
||||
|
||||
|
@ -1000,6 +1000,8 @@ load_cap_file(capture_file *cf)
|
|||
|
||||
epan_dissect_cleanup(&edt);
|
||||
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
|
||||
if (err != 0) {
|
||||
/* Print a message noting that the read failed somewhere along the line. */
|
||||
switch (err) {
|
||||
|
|
23
reordercap.c
23
reordercap.c
|
@ -104,21 +104,18 @@ typedef struct FrameRecord_t {
|
|||
|
||||
|
||||
static void
|
||||
frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh, Buffer *buf,
|
||||
const char *infile)
|
||||
frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh,
|
||||
struct wtap_pkthdr *phdr, Buffer *buf, const char *infile)
|
||||
{
|
||||
int err;
|
||||
gchar *err_info;
|
||||
struct wtap_pkthdr phdr;
|
||||
|
||||
memset(&phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
|
||||
DEBUG_PRINT("\nDumping frame (offset=%" G_GINT64_MODIFIER "u)\n",
|
||||
frame->offset);
|
||||
|
||||
|
||||
/* Re-read the first frame from the stored location */
|
||||
if (!wtap_seek_read(wth, frame->offset, &phdr, buf, &err, &err_info)) {
|
||||
/* Re-read the frame from the stored location */
|
||||
if (!wtap_seek_read(wth, frame->offset, phdr, buf, &err, &err_info)) {
|
||||
if (err != 0) {
|
||||
/* Print a message noting that the read failed somewhere along the line. */
|
||||
fprintf(stderr,
|
||||
|
@ -138,11 +135,12 @@ frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh, Buffer *buf,
|
|||
}
|
||||
|
||||
/* Copy, and set length and timestamp from item. */
|
||||
/* TODO: remove when wtap_seek_read() will read phdr */
|
||||
phdr.ts = frame->time;
|
||||
/* TODO: remove when wtap_seek_read() fills in phdr,
|
||||
including time stamps, for all file types */
|
||||
phdr->ts = frame->time;
|
||||
|
||||
/* Dump frame to outfile */
|
||||
if (!wtap_dump(pdh, &phdr, ws_buffer_start_ptr(buf), &err)) {
|
||||
if (!wtap_dump(pdh, phdr, ws_buffer_start_ptr(buf), &err)) {
|
||||
fprintf(stderr, "reordercap: Error (%s) writing frame to outfile\n",
|
||||
wtap_strerror(err));
|
||||
exit(1);
|
||||
|
@ -202,6 +200,7 @@ main(int argc, char *argv[])
|
|||
GString *runtime_info_str;
|
||||
wtap *wth = NULL;
|
||||
wtap_dumper *pdh = NULL;
|
||||
struct wtap_pkthdr dump_phdr;
|
||||
Buffer buf;
|
||||
int err;
|
||||
gchar *err_info;
|
||||
|
@ -360,16 +359,18 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* Write out each sorted frame in turn */
|
||||
wtap_phdr_init(&dump_phdr);
|
||||
ws_buffer_init(&buf, 1500);
|
||||
for (i = 0; i < frames->len; i++) {
|
||||
FrameRecord_t *frame = (FrameRecord_t *)frames->pdata[i];
|
||||
|
||||
/* Avoid writing if already sorted and configured to */
|
||||
if (write_output_regardless || (wrong_order_count > 0)) {
|
||||
frame_write(frame, wth, pdh, &buf, infile);
|
||||
frame_write(frame, wth, pdh, &dump_phdr, &buf, infile);
|
||||
}
|
||||
g_slice_free(FrameRecord_t, frame);
|
||||
}
|
||||
wtap_phdr_cleanup(&dump_phdr);
|
||||
ws_buffer_free(&buf);
|
||||
|
||||
if (!write_output_regardless && (wrong_order_count == 0)) {
|
||||
|
|
|
@ -1810,7 +1810,7 @@ load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
|
|||
/* Get the union of the flags for all tap listeners. */
|
||||
tap_flags = union_of_tap_listener_flags();
|
||||
|
||||
memset(&file_phdr, 0, sizeof(file_phdr));
|
||||
wtap_phdr_init(&file_phdr);
|
||||
|
||||
/* XXX - TEMPORARY HACK TO ELF DISSECTOR */
|
||||
file_phdr.pkt_encap = 1234;
|
||||
|
@ -1945,6 +1945,8 @@ load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
|
|||
}
|
||||
}
|
||||
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
|
||||
if (err != 0) {
|
||||
/*
|
||||
* Print a message noting that the read failed somewhere along the line.
|
||||
|
|
4
tshark.c
4
tshark.c
|
@ -3072,7 +3072,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
|
|||
Buffer buf;
|
||||
epan_dissect_t *edt = NULL;
|
||||
|
||||
memset(&phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
wtap_phdr_init(&phdr);
|
||||
|
||||
shb_hdr = wtap_file_get_shb_info(cf->wth);
|
||||
idb_inf = wtap_file_get_idb_info(cf->wth);
|
||||
|
@ -3376,6 +3376,8 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
|
|||
}
|
||||
}
|
||||
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
|
||||
if (err != 0) {
|
||||
/*
|
||||
* Print a message noting that the read failed somewhere along the line.
|
||||
|
|
|
@ -1104,7 +1104,7 @@ packet_list_dissect_and_cache_record(PacketList *packet_list, PacketListRecord *
|
|||
g_return_if_fail(packet_list);
|
||||
g_return_if_fail(PACKETLIST_IS_LIST(packet_list));
|
||||
|
||||
memset(&phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
wtap_phdr_init(&phdr);
|
||||
|
||||
fdata = record->fdata;
|
||||
|
||||
|
@ -1175,6 +1175,7 @@ packet_list_dissect_and_cache_record(PacketList *packet_list, PacketListRecord *
|
|||
record->colorized = TRUE;
|
||||
|
||||
epan_dissect_cleanup(&edt);
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
ws_buffer_free(&buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ process_record(frame_data *frame, column_info *cinfo, ph_stats_t* ps)
|
|||
Buffer buf;
|
||||
double cur_time;
|
||||
|
||||
memset(&phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
wtap_phdr_init(&phdr);
|
||||
|
||||
/* Load the record from the capture file */
|
||||
ws_buffer_init(&buf, 1500);
|
||||
|
@ -170,6 +170,7 @@ process_record(frame_data *frame, column_info *cinfo, ph_stats_t* ps)
|
|||
|
||||
/* Free our memory. */
|
||||
epan_dissect_cleanup(&edt);
|
||||
wtap_phdr_cleanup(&phdr);
|
||||
ws_buffer_free(&buf);
|
||||
|
||||
return TRUE; /* success */
|
||||
|
|
206
wiretap/pcapng.c
206
wiretap/pcapng.c
|
@ -418,6 +418,98 @@ register_pcapng_block_type_handler(guint block_type, block_reader read,
|
|||
(void)g_hash_table_insert(block_handlers, GUINT_TO_POINTER(block_type),
|
||||
handler);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tables for plugins to handle particular options for particular block
|
||||
* types.
|
||||
*
|
||||
* An option has a handler routine, which is passed an indication of
|
||||
* whether this section of the file is byte-swapped, the length of the
|
||||
* option, the data of the option, a pointer to an error code, and a
|
||||
* pointer to a pointer variable for an error string.
|
||||
*
|
||||
* It checks whether the length and option are valid, and, if they aren't,
|
||||
* returns FALSE, setting the error code to the appropriate error (normally
|
||||
* WTAP_ERR_BAD_FILE) and the error string to an appropriate string
|
||||
* indicating the problem.
|
||||
*
|
||||
* Otherwise, if this section of the file is byte-swapped, it byte-swaps
|
||||
* multi-byte numerical values, so that it's in the host byte order.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Block types indices in the table of tables of option handlers.
|
||||
*
|
||||
* Block types are not guaranteed to be sequential, so we map the
|
||||
* block types we support to a sequential set. Furthermore, all
|
||||
* packet block types have the same set of options.
|
||||
*/
|
||||
#define BT_INDEX_SHB 0
|
||||
#define BT_INDEX_IDB 1
|
||||
#define BT_INDEX_PBS 2 /* all packet blocks */
|
||||
#define BT_INDEX_NRB 3
|
||||
#define BT_INDEX_ISB 4
|
||||
|
||||
#define NUM_BT_INDICES 5
|
||||
|
||||
static GHashTable *option_handlers[NUM_BT_INDICES];
|
||||
|
||||
void
|
||||
register_pcapng_option_handler(guint block_type, guint option_code,
|
||||
option_handler handler)
|
||||
{
|
||||
guint bt_index;
|
||||
|
||||
switch (block_type) {
|
||||
|
||||
case BLOCK_TYPE_SHB:
|
||||
bt_index = BT_INDEX_SHB;
|
||||
break;
|
||||
|
||||
case BLOCK_TYPE_IDB:
|
||||
bt_index = BT_INDEX_IDB;
|
||||
break;
|
||||
|
||||
case BLOCK_TYPE_PB:
|
||||
case BLOCK_TYPE_EPB:
|
||||
case BLOCK_TYPE_SPB:
|
||||
bt_index = BT_INDEX_PBS;
|
||||
break;
|
||||
|
||||
case BLOCK_TYPE_NRB:
|
||||
bt_index = BT_INDEX_NRB;
|
||||
break;
|
||||
|
||||
case BLOCK_TYPE_ISB:
|
||||
bt_index = BT_INDEX_ISB;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* This is a block type we don't process; either we ignore it,
|
||||
* in which case the options don't get processed, or there's
|
||||
* a plugin routine to handle it, in which case that routine
|
||||
* will do the option processing itself.
|
||||
*
|
||||
* XXX - report an error?
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (option_handlers[bt_index] == NULL) {
|
||||
/*
|
||||
* Create the table of option handlers for this block type.
|
||||
*
|
||||
* XXX - there's no "g_uint_hash()" or "g_uint_equal()",
|
||||
* so we use "g_direct_hash()" and "g_direct_equal()".
|
||||
*/
|
||||
option_handlers[bt_index] = g_hash_table_new_full(g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL, g_free);
|
||||
}
|
||||
(void)g_hash_table_insert(option_handlers[bt_index],
|
||||
GUINT_TO_POINTER(option_code), handler);
|
||||
}
|
||||
#endif /* HAVE_PLUGINS */
|
||||
|
||||
static int
|
||||
|
@ -1003,10 +1095,14 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
guint32 padding;
|
||||
interface_info_t iface_info;
|
||||
guint64 ts;
|
||||
pcapng_option_header_t oh;
|
||||
guint8 *opt_ptr;
|
||||
pcapng_option_header_t *oh;
|
||||
guint8 *option_content;
|
||||
int pseudo_header_len;
|
||||
char *option_content = NULL; /* Allocate as large as the options block */
|
||||
int fcslen;
|
||||
#ifdef HAVE_PLUGINS
|
||||
option_handler handler;
|
||||
#endif
|
||||
|
||||
/* Don't try to allocate memory for a huge number of options, as
|
||||
that might fail and, even if it succeeds, it might not leave
|
||||
|
@ -1232,24 +1328,24 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
|
||||
/* 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 FALSE;
|
||||
}
|
||||
ws_buffer_assure_space(&wblock->packet_header->ft_specific_data, opt_cont_buf_len);
|
||||
opt_ptr = ws_buffer_start_ptr(&wblock->packet_header->ft_specific_data);
|
||||
|
||||
while (to_read != 0) {
|
||||
/* read option */
|
||||
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
|
||||
oh = (pcapng_option_header_t *)(void *)opt_ptr;
|
||||
option_content = opt_ptr + sizeof (pcapng_option_header_t);
|
||||
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");
|
||||
/* XXX - free anything? */
|
||||
return FALSE;
|
||||
}
|
||||
block_read += bytes_read;
|
||||
to_read -= bytes_read;
|
||||
|
||||
/* handle option content */
|
||||
switch (oh.option_code) {
|
||||
switch (oh->option_code) {
|
||||
case(OPT_EOFOPT):
|
||||
if (to_read != 0) {
|
||||
pcapng_debug1("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
|
||||
|
@ -1258,59 +1354,81 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
to_read = 0;
|
||||
break;
|
||||
case(OPT_COMMENT):
|
||||
if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
|
||||
if (oh->option_length > 0 && oh->option_length < opt_cont_buf_len) {
|
||||
wblock->packet_header->presence_flags |= WTAP_HAS_COMMENTS;
|
||||
wblock->packet_header->opt_comment = g_strndup(option_content, oh.option_length);
|
||||
pcapng_debug2("pcapng_read_packet_block: length %u opt_comment '%s'", oh.option_length, wblock->packet_header->opt_comment);
|
||||
wblock->packet_header->opt_comment = g_strndup(option_content, oh->option_length);
|
||||
pcapng_debug2("pcapng_read_packet_block: length %u opt_comment '%s'", oh->option_length, wblock->packet_header->opt_comment);
|
||||
} else {
|
||||
pcapng_debug1("pcapng_read_packet_block: opt_comment length %u seems strange", oh.option_length);
|
||||
pcapng_debug1("pcapng_read_packet_block: opt_comment length %u seems strange", oh->option_length);
|
||||
}
|
||||
break;
|
||||
case(OPT_EPB_FLAGS):
|
||||
if (oh.option_length == 4) {
|
||||
/* Don't cast a char[] into a guint32--the
|
||||
* char[] may not be aligned correctly.
|
||||
*/
|
||||
wblock->packet_header->presence_flags |= WTAP_HAS_PACK_FLAGS;
|
||||
memcpy(&wblock->packet_header->pack_flags, option_content, sizeof(guint32));
|
||||
if (pn->byte_swapped)
|
||||
wblock->packet_header->pack_flags = GUINT32_SWAP_LE_BE(wblock->packet_header->pack_flags);
|
||||
if (wblock->packet_header->pack_flags & 0x000001E0) {
|
||||
/* The FCS length is present */
|
||||
fcslen = (wblock->packet_header->pack_flags & 0x000001E0) >> 5;
|
||||
}
|
||||
pcapng_debug1("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->packet_header->pack_flags);
|
||||
} else {
|
||||
pcapng_debug1("pcapng_read_packet_block: pack_flags length %u not 4 as expected", oh.option_length);
|
||||
if (oh->option_length != 4) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng: packet block flags option length %u is not 4",
|
||||
oh->option_length);
|
||||
/* XXX - free anything? */
|
||||
return FALSE;
|
||||
}
|
||||
/* Don't cast a char[] into a guint32--the
|
||||
* char[] may not be aligned correctly.
|
||||
*/
|
||||
wblock->packet_header->presence_flags |= WTAP_HAS_PACK_FLAGS;
|
||||
memcpy(&wblock->packet_header->pack_flags, option_content, sizeof(guint32));
|
||||
if (pn->byte_swapped) {
|
||||
wblock->packet_header->pack_flags = GUINT32_SWAP_LE_BE(wblock->packet_header->pack_flags);
|
||||
memcpy(option_content, &wblock->packet_header->pack_flags, sizeof(guint32));
|
||||
}
|
||||
if (wblock->packet_header->pack_flags & 0x000001E0) {
|
||||
/* The FCS length is present */
|
||||
fcslen = (wblock->packet_header->pack_flags & 0x000001E0) >> 5;
|
||||
}
|
||||
pcapng_debug1("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->packet_header->pack_flags);
|
||||
break;
|
||||
case(OPT_EPB_HASH):
|
||||
pcapng_debug2("pcapng_read_packet_block: epb_hash %u currently not handled - ignoring %u bytes",
|
||||
oh.option_code, oh.option_length);
|
||||
oh->option_code, oh->option_length);
|
||||
break;
|
||||
case(OPT_EPB_DROPCOUNT):
|
||||
if (oh.option_length == 8) {
|
||||
/* Don't cast a char[] into a guint32--the
|
||||
* char[] may not be aligned correctly.
|
||||
*/
|
||||
wblock->packet_header->presence_flags |= WTAP_HAS_DROP_COUNT;
|
||||
memcpy(&wblock->packet_header->drop_count, option_content, sizeof(guint64));
|
||||
if (pn->byte_swapped)
|
||||
wblock->packet_header->drop_count = GUINT64_SWAP_LE_BE(wblock->packet_header->drop_count);
|
||||
|
||||
pcapng_debug1("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->packet_header->drop_count);
|
||||
} else {
|
||||
pcapng_debug1("pcapng_read_packet_block: drop_count length %u not 8 as expected", oh.option_length);
|
||||
if (oh->option_length != 8) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng: packet block drop count option length %u is not 8",
|
||||
oh->option_length);
|
||||
/* XXX - free anything? */
|
||||
return FALSE;
|
||||
}
|
||||
/* Don't cast a char[] into a guint64--the
|
||||
* char[] may not be aligned correctly.
|
||||
*/
|
||||
wblock->packet_header->presence_flags |= WTAP_HAS_DROP_COUNT;
|
||||
memcpy(&wblock->packet_header->drop_count, option_content, sizeof(guint64));
|
||||
if (pn->byte_swapped) {
|
||||
wblock->packet_header->drop_count = GUINT64_SWAP_LE_BE(wblock->packet_header->drop_count);
|
||||
memcpy(option_content, &wblock->packet_header->drop_count, sizeof(guint64));
|
||||
}
|
||||
|
||||
pcapng_debug1("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->packet_header->drop_count);
|
||||
break;
|
||||
default:
|
||||
#ifdef HAVE_PLUGINS
|
||||
/*
|
||||
* Do we have a handler for this packet block option code?
|
||||
*/
|
||||
handler = (option_handler)g_hash_table_lookup(option_handlers[BT_INDEX_PBS],
|
||||
GUINT_TO_POINTER(oh->option_code));
|
||||
if (handler != NULL) {
|
||||
/* Yes - call the handler. */
|
||||
if (!handler(pn->byte_swapped, oh->option_length,
|
||||
option_content, err, err_info))
|
||||
/* XXX - free anything? */
|
||||
return FALSE;
|
||||
} else
|
||||
#endif
|
||||
pcapng_debug2("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
|
||||
oh.option_code, oh.option_length);
|
||||
oh->option_code, oh->option_length);
|
||||
}
|
||||
}
|
||||
|
||||
g_free(option_content);
|
||||
|
||||
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);
|
||||
|
|
|
@ -36,5 +36,18 @@ WS_DLL_PUBLIC
|
|||
void register_pcapng_block_type_handler(guint block_type, block_reader read,
|
||||
block_writer write);
|
||||
|
||||
/*
|
||||
* Handler routine for pcap-ng option type.
|
||||
*/
|
||||
typedef gboolean (*option_handler)(gboolean, guint, guint8 *, int *, gchar **);
|
||||
|
||||
/*
|
||||
* Register a handler for a pcap-ng option code for a particular block
|
||||
* type.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void register_pcapng_option_handler(guint block_type, guint option_code,
|
||||
option_handler handle);
|
||||
|
||||
#endif /* __PCAP_MODULE_H__ */
|
||||
|
||||
|
|
|
@ -1179,6 +1179,19 @@ wtap_buf_ptr(wtap *wth)
|
|||
return ws_buffer_start_ptr(wth->frame_buffer);
|
||||
}
|
||||
|
||||
void
|
||||
wtap_phdr_init(struct wtap_pkthdr *phdr)
|
||||
{
|
||||
memset(phdr, 0, sizeof(struct wtap_pkthdr));
|
||||
ws_buffer_init(&phdr->ft_specific_data, 0);
|
||||
}
|
||||
|
||||
void
|
||||
wtap_phdr_cleanup(struct wtap_pkthdr *phdr)
|
||||
{
|
||||
ws_buffer_free(&phdr->ft_specific_data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
wtap_seek_read(wtap *wth, gint64 seek_off,
|
||||
struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
|
||||
|
|
|
@ -1007,20 +1007,21 @@ union wtap_pseudo_header {
|
|||
#define REC_TYPE_FT_SPECIFIC_REPORT 2 /**< file-type-specific report */
|
||||
|
||||
struct wtap_pkthdr {
|
||||
guint rec_type; /* what type of record is this? */
|
||||
guint32 presence_flags; /* what stuff do we have? */
|
||||
nstime_t ts;
|
||||
guint32 caplen; /* data length in the file */
|
||||
guint32 len; /* data length on the wire */
|
||||
int pkt_encap; /* WTAP_ENCAP_ value for this packet */
|
||||
int pkt_tsprec; /* WTAP_TSPREC_ value for this packet */
|
||||
/* pcapng variables */
|
||||
guint32 interface_id; /* identifier of the interface. */
|
||||
/* options */
|
||||
gchar *opt_comment; /* NULL if not available */
|
||||
guint64 drop_count; /* number of packets lost (by the interface and the
|
||||
operating system) between this packet and the preceding one. */
|
||||
guint32 pack_flags; /* XXX - 0 for now (any value for "we don't have it"?) */
|
||||
guint rec_type; /* what type of record is this? */
|
||||
guint32 presence_flags; /* what stuff do we have? */
|
||||
nstime_t ts; /* time stamp */
|
||||
guint32 caplen; /* data length in the file */
|
||||
guint32 len; /* data length on the wire */
|
||||
int pkt_encap; /* WTAP_ENCAP_ value for this packet */
|
||||
int pkt_tsprec; /* WTAP_TSPREC_ value for this packet */
|
||||
/* pcapng variables */
|
||||
guint32 interface_id; /* identifier of the interface. */
|
||||
/* options */
|
||||
gchar *opt_comment; /* NULL if not available */
|
||||
guint64 drop_count; /* number of packets lost (by the interface and the
|
||||
operating system) between this packet and the preceding one. */
|
||||
guint32 pack_flags; /* XXX - 0 for now (any value for "we don't have it"?) */
|
||||
Buffer ft_specific_data; /* file-type specific data */
|
||||
|
||||
union wtap_pseudo_header pseudo_header;
|
||||
};
|
||||
|
@ -1464,6 +1465,14 @@ struct wtap_pkthdr *wtap_phdr(wtap *wth);
|
|||
WS_DLL_PUBLIC
|
||||
guint8 *wtap_buf_ptr(wtap *wth);
|
||||
|
||||
/*** initialize a wtap_pkthdr structure ***/
|
||||
WS_DLL_PUBLIC
|
||||
void wtap_phdr_init(struct wtap_pkthdr *phdr);
|
||||
|
||||
/*** clean up a wtap_pkthdr structure, freeing what wtap_phdr_init() allocated */
|
||||
WS_DLL_PUBLIC
|
||||
void wtap_phdr_cleanup(struct wtap_pkthdr *phdr);
|
||||
|
||||
/*** get various information snippets about the current file ***/
|
||||
|
||||
/** Return an approximation of the amount of data we've read sequentially
|
||||
|
|
Loading…
Reference in New Issue