2 * Implements a tvbuff for frame
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.
29 #include <epan/packet.h>
30 #include <epan/tvbuff-int.h>
31 #include <epan/tvbuff.h>
33 #include "frame_tvbuff.h"
36 #include "wtap-int.h" /* for ->random_fh */
41 Buffer
*buf
; /* Packet data */
43 wtap
*wth
; /**< Wiretap session */
44 gint64 file_off
; /**< File offset */
50 frame_read(struct tvb_frame
*frame_tvb
, struct wtap_pkthdr
*phdr
, Buffer
*buf
)
55 /* sanity check, capture file was closed? */
56 if (cfile
.wth
!= frame_tvb
->wth
)
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
)) {
64 case WTAP_ERR_UNSUPPORTED_ENCAP
:
65 case WTAP_ERR_BAD_FILE
:
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
;
93 frame_free(tvbuff_t
*tvb
)
95 struct tvb_frame
*frame_tvb
= (struct tvb_frame
*) tvb
;
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
;
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
);
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
);
134 return (gint
) (result
- tvb
->real_data
);
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
);
150 frame_offset(const tvbuff_t
*tvb _U_
, const guint counter
)
152 /* XXX: frame_tvb->offset */
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() */
172 frame_tvbuff_new(const frame_data
*fd
, const guint8
*buf
)
174 struct tvb_frame
*frame_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
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.
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 */
220 frame_tvb
->wth
= cfile
.wth
;
221 frame_tvb
->file_off
= fd
->file_off
;
222 frame_tvb
->offset
= 0;
224 frame_tvb
->wth
= NULL
;
226 frame_tvb
->buf
= NULL
;
232 frame_tvbuff_new_buffer(const frame_data
*fd
, Buffer
*buf
)
234 return frame_tvbuff_new(fd
, buffer_start_ptr(buf
));
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 */
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
;