* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config.h>
#include <epan/tvbuff.h>
#include "frame_tvbuff.h"
-#include "globals.h"
#include "wiretap/wtap-int.h" /* for ->random_fh */
Buffer *buf; /* Packet data */
- wtap *wth; /**< Wiretap session */
+ const struct packet_provider_data *prov; /* provider of packet information */
gint64 file_off; /**< File offset */
guint offset;
};
static gboolean
-frame_read(struct tvb_frame *frame_tvb, struct wtap_pkthdr *phdr, Buffer *buf)
+frame_read(struct tvb_frame *frame_tvb, wtap_rec *rec, Buffer *buf)
{
int err;
gchar *err_info;
- /* sanity check, capture file was closed? */
- if (cfile.wth != frame_tvb->wth)
- return FALSE;
-
/* XXX, what if phdr->caplen isn't equal to
* frame_tvb->tvb.length + frame_tvb->offset?
*/
- if (!wtap_seek_read(frame_tvb->wth, frame_tvb->file_off, phdr, buf, &err, &err_info)) {
+ if (!wtap_seek_read(frame_tvb->prov->wth, frame_tvb->file_off, rec, buf, &err, &err_info)) {
/* XXX - report error! */
switch (err) {
case WTAP_ERR_BAD_FILE:
return TRUE;
}
+static GPtrArray *buffer_cache = NULL;
+
static void
frame_cache(struct tvb_frame *frame_tvb)
{
- struct wtap_pkthdr phdr; /* Packet header */
+ wtap_rec rec; /* Record metadata */
- wtap_phdr_init(&phdr);
+ wtap_rec_init(&rec);
if (frame_tvb->buf == NULL) {
- frame_tvb->buf = (struct Buffer *) g_malloc(sizeof(struct Buffer));
+ if (G_UNLIKELY(!buffer_cache)) buffer_cache = g_ptr_array_sized_new(1024);
+
+ if (buffer_cache->len > 0) {
+ frame_tvb->buf = (struct Buffer *) g_ptr_array_remove_index(buffer_cache, buffer_cache->len - 1);
+ } else {
+ frame_tvb->buf = (struct Buffer *) g_malloc(sizeof(struct Buffer));
+ }
- /* XXX, register frame_tvb to some list which frees from time to time not used buffers :] */
ws_buffer_init(frame_tvb->buf, frame_tvb->tvb.length + frame_tvb->offset);
- if (!frame_read(frame_tvb, &phdr, frame_tvb->buf))
+ if (!frame_read(frame_tvb, &rec, frame_tvb->buf))
{ /* TODO: THROW(???); */ }
}
frame_tvb->tvb.real_data = ws_buffer_start_ptr(frame_tvb->buf) + frame_tvb->offset;
- wtap_phdr_cleanup(&phdr);
+ wtap_rec_cleanup(&rec);
}
static void
if (frame_tvb->buf) {
ws_buffer_free(frame_tvb->buf);
-
- g_free(frame_tvb->buf);
+ g_ptr_array_add(buffer_cache, frame_tvb->buf);
}
}
/* based on tvb_new_real_data() */
tvbuff_t *
-frame_tvbuff_new(const frame_data *fd, const guint8 *buf)
+frame_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd,
+ const guint8 *buf)
{
struct tvb_frame *frame_tvb;
tvbuff_t *tvb;
* tvb_new_real_data() now there's no one
*/
- tvb->real_data = buf;
- tvb->length = fd->cap_len;
- tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
- tvb->initialized = TRUE;
+ tvb->real_data = buf;
+ tvb->length = fd->cap_len;
+ tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
+ tvb->contained_length = tvb->reported_length;
+ tvb->initialized = TRUE;
/*
* This is the top-level real tvbuff for this data source,
frame_tvb = (struct tvb_frame *) tvb;
/* XXX, wtap_can_seek() */
- if (cfile.wth && cfile.wth->random_fh
-#ifdef WANT_PACKET_EDITOR
- && fd->file_off != -1 /* generic clone for modified packets */
-#endif
- ) {
- frame_tvb->wth = cfile.wth;
+ if (prov->wth && prov->wth->random_fh) {
+ frame_tvb->prov = prov;
frame_tvb->file_off = fd->file_off;
frame_tvb->offset = 0;
} else
- frame_tvb->wth = NULL;
+ frame_tvb->prov = NULL;
frame_tvb->buf = NULL;
}
tvbuff_t *
-frame_tvbuff_new_buffer(const frame_data *fd, Buffer *buf)
+frame_tvbuff_new_buffer(const struct packet_provider_data *prov,
+ const frame_data *fd, Buffer *buf)
{
- return frame_tvbuff_new(fd, ws_buffer_start_ptr(buf));
+ return frame_tvbuff_new(prov, fd, ws_buffer_start_ptr(buf));
}
static tvbuff_t *
struct tvb_frame *cloned_frame_tvb;
/* file not seekable */
- if (!frame_tvb->wth)
+ if (!frame_tvb->prov)
return NULL;
abs_offset += frame_tvb->offset;
cloned_tvb = tvb_new(&tvb_frame_ops);
/* data will be read when needed */
- cloned_tvb->real_data = NULL;
- cloned_tvb->length = abs_length;
- cloned_tvb->reported_length = abs_length; /* XXX? */
- cloned_tvb->initialized = TRUE;
+ cloned_tvb->real_data = NULL;
+ cloned_tvb->length = abs_length;
+ cloned_tvb->reported_length = abs_length; /* XXX? */
+ cloned_tvb->contained_length = cloned_tvb->reported_length;
+ cloned_tvb->initialized = TRUE;
/*
* This is the top-level real tvbuff for this data source,
cloned_tvb->ds_tvb = cloned_tvb;
cloned_frame_tvb = (struct tvb_frame *) cloned_tvb;
- cloned_frame_tvb->wth = frame_tvb->wth;
+ cloned_frame_tvb->prov = frame_tvb->prov;
cloned_frame_tvb->file_off = frame_tvb->file_off;
cloned_frame_tvb->offset = abs_offset;
cloned_frame_tvb->buf = NULL;
/* based on tvb_new_real_data() */
tvbuff_t *
-file_tvbuff_new(const frame_data *fd, const guint8 *buf)
+file_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd,
+ const guint8 *buf)
{
struct tvb_frame *frame_tvb;
tvbuff_t *tvb;
* tvb_new_real_data() now there's no one
*/
- tvb->real_data = buf;
- tvb->length = fd->cap_len;
- tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
- tvb->initialized = TRUE;
+ tvb->real_data = buf;
+ tvb->length = fd->cap_len;
+ tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
+ tvb->contained_length = tvb->reported_length;
+ tvb->initialized = TRUE;
/*
* This is the top-level real tvbuff for this data source,
frame_tvb = (struct tvb_frame *) tvb;
/* XXX, wtap_can_seek() */
- if (cfile.wth && cfile.wth->random_fh
-#ifdef WANT_PACKET_EDITOR
- && fd->file_off != -1 /* generic clone for modified packets */
-#endif
- ) {
- frame_tvb->wth = cfile.wth;
+ if (prov->wth && prov->wth->random_fh) {
+ frame_tvb->prov = prov;
frame_tvb->file_off = fd->file_off;
frame_tvb->offset = 0;
} else
- frame_tvb->wth = NULL;
+ frame_tvb->prov = NULL;
frame_tvb->buf = NULL;
}
tvbuff_t *
-file_tvbuff_new_buffer(const frame_data *fd, Buffer *buf)
+file_tvbuff_new_buffer(const struct packet_provider_data *prov,
+ const frame_data *fd, Buffer *buf)
{
- return frame_tvbuff_new(fd, ws_buffer_start_ptr(buf));
+ return frame_tvbuff_new(prov, fd, ws_buffer_start_ptr(buf));
}
/*