more
[metze/wireshark/wip.git] / frame_tvbuff.c
index 2e3019c7e324ffab0261eb54a0e36cae75b50e8c..705cd47459878e8f4d09f8633db788302c4a896f 100644 (file)
@@ -5,19 +5,7 @@
  * 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 "wtap-int.h" /* for ->random_fh */
+#include "wiretap/wtap-int.h" /* for ->random_fh */
 
 struct tvb_frame {
        struct tvbuff tvb;
 
        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_UNSUPPORTED_ENCAP:
                        case WTAP_ERR_BAD_FILE:
                                g_free(err_info);
                                break;
@@ -69,26 +52,33 @@ frame_read(struct tvb_frame *frame_tvb, struct wtap_pkthdr *phdr, Buffer *buf)
        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
@@ -98,8 +88,7 @@ frame_free(tvbuff_t *tvb)
 
        if (frame_tvb->buf) {
                ws_buffer_free(frame_tvb->buf);
-
-               g_free(frame_tvb->buf);
+               g_ptr_array_add(buffer_cache, frame_tvb->buf);
        }
 }
 
@@ -139,13 +128,13 @@ frame_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
 }
 
 static gint
-frame_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *needles, guchar *found_needle)
+frame_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
 {
        struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
 
        frame_cache(frame_tvb);
 
-       return tvb_pbrk_guint8(tvb, abs_offset, limit, needles, found_needle);
+       return tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle);
 }
 
 static guint
@@ -171,7 +160,8 @@ static const struct tvb_ops tvb_frame_ops = {
 
 /* 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;
@@ -200,10 +190,11 @@ frame_tvbuff_new(const frame_data *fd, const guint8 *buf)
         * 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,
@@ -214,16 +205,12 @@ frame_tvbuff_new(const frame_data *fd, const guint8 *buf)
        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;
 
@@ -231,9 +218,10 @@ frame_tvbuff_new(const frame_data *fd, const guint8 *buf)
 }
 
 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 *
@@ -245,7 +233,7 @@ frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
        struct tvb_frame *cloned_frame_tvb;
 
        /* file not seekable */
-       if (!frame_tvb->wth)
+       if (!frame_tvb->prov)
                return NULL;
 
        abs_offset += frame_tvb->offset;
@@ -253,10 +241,11 @@ frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
        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,
@@ -265,7 +254,7 @@ frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
        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;
@@ -276,7 +265,8 @@ frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
 
 /* 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;
@@ -305,10 +295,11 @@ file_tvbuff_new(const frame_data *fd, const guint8 *buf)
         * 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,
@@ -319,16 +310,12 @@ file_tvbuff_new(const frame_data *fd, const guint8 *buf)
        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;
 
@@ -336,9 +323,10 @@ file_tvbuff_new(const frame_data *fd, const guint8 *buf)
 }
 
 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));
 }
 
 /*