sec_vt_header: dissect call_id
[wireshark-wip.git] / frame_tvbuff.c
blob61ab0fa84f990fbd3093b2019f06c8cd9b3554b5
1 /* frame_tvbuff.c
2 * Implements a tvbuff for frame
4 * $Id$
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "config.h"
27 #include <glib.h>
29 #include <epan/packet.h>
30 #include <epan/tvbuff-int.h>
31 #include <epan/tvbuff.h>
33 #include "frame_tvbuff.h"
34 #include "globals.h"
36 #include "wtap-int.h" /* for ->random_fh */
38 struct tvb_frame {
39 struct tvbuff tvb;
41 Buffer *buf; /* Packet data */
43 wtap *wth; /**< Wiretap session */
44 gint64 file_off; /**< File offset */
46 guint offset;
49 static gboolean
50 frame_read(struct tvb_frame *frame_tvb, struct wtap_pkthdr *phdr, Buffer *buf)
52 int err;
53 gchar *err_info;
55 /* sanity check, capture file was closed? */
56 if (cfile.wth != frame_tvb->wth)
57 return FALSE;
59 /* XXX, frame_tvb->tvb.length + frame_tvb->offset might be not real captured packet length
60 * can it cause some problems for wiretap readers?
62 if (!wtap_seek_read(frame_tvb->wth, frame_tvb->file_off, phdr, buf, frame_tvb->tvb.length + frame_tvb->offset, &err, &err_info)) {
63 switch (err) {
64 case WTAP_ERR_UNSUPPORTED_ENCAP:
65 case WTAP_ERR_BAD_FILE:
66 g_free(err_info);
67 break;
69 return FALSE;
71 return TRUE;
74 static void
75 frame_cache(struct tvb_frame *frame_tvb)
77 struct wtap_pkthdr phdr; /* Packet header */
79 if (frame_tvb->buf == NULL) {
80 frame_tvb->buf = (struct Buffer *) g_malloc(sizeof(struct Buffer));
82 /* XXX, register frame_tvb to some list which frees from time to time not used buffers :] */
83 buffer_init(frame_tvb->buf, frame_tvb->tvb.length + frame_tvb->offset);
85 if (!frame_read(frame_tvb, &phdr, frame_tvb->buf))
86 { /* TODO: THROW(???); */ }
89 frame_tvb->tvb.real_data = buffer_start_ptr(frame_tvb->buf) + frame_tvb->offset;
92 static void
93 frame_free(tvbuff_t *tvb)
95 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
97 if (frame_tvb->buf) {
98 buffer_free(frame_tvb->buf);
100 g_free(frame_tvb->buf);
104 static const guint8 *
105 frame_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length _U_)
107 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
109 frame_cache(frame_tvb);
111 return tvb->real_data + abs_offset;
114 static void *
115 frame_memcpy(tvbuff_t *tvb, void *target, guint abs_offset, guint abs_length)
117 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
119 frame_cache(frame_tvb);
121 return memcpy(target, tvb->real_data + abs_offset, abs_length);
124 static gint
125 frame_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
127 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
128 const guint8 *result;
130 frame_cache(frame_tvb);
132 result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
133 if (result)
134 return (gint) (result - tvb->real_data);
135 else
136 return -1;
139 static gint
140 frame_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *needles, guchar *found_needle)
142 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
144 frame_cache(frame_tvb);
146 return tvb_pbrk_guint8(tvb, abs_offset, limit, needles, found_needle);
149 static guint
150 frame_offset(const tvbuff_t *tvb _U_, const guint counter)
152 /* XXX: frame_tvb->offset */
153 return counter;
156 static tvbuff_t *frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length);
158 static const struct tvb_ops tvb_frame_ops = {
159 sizeof(struct tvb_frame), /* size */
161 frame_free, /* free */
162 frame_offset, /* offset */
163 frame_get_ptr, /* get_ptr */
164 frame_memcpy, /* memcpy */
165 frame_find_guint8, /* find_guint8 */
166 frame_pbrk_guint8, /* pbrk_guint8 */
167 frame_clone, /* clone */
170 /* based on tvb_new_real_data() */
171 tvbuff_t *
172 frame_tvbuff_new(const frame_data *fd, const guint8 *buf)
174 struct tvb_frame *frame_tvb;
175 tvbuff_t *tvb;
177 tvb = tvb_new(&tvb_frame_ops);
180 * XXX - currently, the length arguments in
181 * tvbuff structure are signed, but the captured
182 * and reported length values are unsigned; this means
183 * that length values > 2^31 - 1 will appear as
184 * negative lengths
186 * Captured length values that large will already
187 * have been filtered out by the Wiretap modules
188 * (the file will be reported as corrupted), to
189 * avoid trying to allocate large chunks of data.
191 * Reported length values will not have been
192 * filtered out, and should not be filtered out,
193 * as those lengths are not necessarily invalid.
195 * For now, we clip the reported length at G_MAXINT
197 * (XXX, is this still a problem?) There was an exception when we call
198 * tvb_new_real_data() now there's no one
201 tvb->real_data = buf;
202 tvb->length = fd->cap_len;
203 tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
204 tvb->initialized = TRUE;
207 * This is the top-level real tvbuff for this data source,
208 * so its data source tvbuff is itself.
210 tvb->ds_tvb = tvb;
212 frame_tvb = (struct tvb_frame *) tvb;
214 /* XXX, wtap_can_seek() */
215 if (cfile.wth && cfile.wth->random_fh
216 #ifdef WANT_PACKET_EDITOR
217 && fd->file_off != -1 /* generic clone for modified packets */
218 #endif
220 frame_tvb->wth = cfile.wth;
221 frame_tvb->file_off = fd->file_off;
222 frame_tvb->offset = 0;
223 } else
224 frame_tvb->wth = NULL;
226 frame_tvb->buf = NULL;
228 return tvb;
231 tvbuff_t *
232 frame_tvbuff_new_buffer(const frame_data *fd, Buffer *buf)
234 return frame_tvbuff_new(fd, buffer_start_ptr(buf));
237 static tvbuff_t *
238 frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
240 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
242 tvbuff_t *cloned_tvb;
243 struct tvb_frame *cloned_frame_tvb;
245 /* file not seekable */
246 if (!frame_tvb->wth)
247 return NULL;
249 abs_offset += frame_tvb->offset;
251 cloned_tvb = tvb_new(&tvb_frame_ops);
253 /* data will be read when needed */
254 cloned_tvb->real_data = NULL;
255 cloned_tvb->length = abs_length;
256 cloned_tvb->reported_length = abs_length; /* XXX? */
257 cloned_tvb->initialized = TRUE;
260 * This is the top-level real tvbuff for this data source,
261 * so its data source tvbuff is itself.
263 cloned_tvb->ds_tvb = cloned_tvb;
265 cloned_frame_tvb = (struct tvb_frame *) cloned_tvb;
266 cloned_frame_tvb->wth = frame_tvb->wth;
267 cloned_frame_tvb->file_off = frame_tvb->file_off;
268 cloned_frame_tvb->offset = abs_offset;
269 cloned_frame_tvb->buf = NULL;
271 return cloned_tvb;