nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* frame_tvbuff.c
2 * Implements a tvbuff for frame
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22  
23 #include <config.h>
24  
25 #include <glib.h>
26  
27 #include <epan/packet.h>
28 #include <epan/tvbuff-int.h>
29 #include <epan/tvbuff.h>
30  
31 #include "frame_tvbuff.h"
32 #include "globals.h"
33  
34 #include "wiretap/wtap-int.h" /* for ->random_fh */
35  
36 struct tvb_frame {
37 struct tvbuff tvb;
38  
39 Buffer *buf; /* Packet data */
40  
41 wtap *wth; /**< Wiretap session */
42 gint64 file_off; /**< File offset */
43  
44 guint offset;
45 };
46  
47 static gboolean
48 frame_read(struct tvb_frame *frame_tvb, struct wtap_pkthdr *phdr, Buffer *buf)
49 {
50 int err;
51 gchar *err_info;
52  
53 /* sanity check, capture file was closed? */
54 if (cfile.wth != frame_tvb->wth)
55 return FALSE;
56  
57 /* XXX, what if phdr->caplen isn't equal to
58 * frame_tvb->tvb.length + frame_tvb->offset?
59 */
60 if (!wtap_seek_read(frame_tvb->wth, frame_tvb->file_off, phdr, buf, &err, &err_info)) {
61 /* XXX - report error! */
62 switch (err) {
63 case WTAP_ERR_BAD_FILE:
64 g_free(err_info);
65 break;
66 }
67 return FALSE;
68 }
69 return TRUE;
70 }
71  
72 static void
73 frame_cache(struct tvb_frame *frame_tvb)
74 {
75 struct wtap_pkthdr phdr; /* Packet header */
76  
77 wtap_phdr_init(&phdr);
78  
79 if (frame_tvb->buf == NULL) {
80 frame_tvb->buf = (struct Buffer *) g_malloc(sizeof(struct Buffer));
81  
82 /* XXX, register frame_tvb to some list which frees from time to time not used buffers :] */
83 ws_buffer_init(frame_tvb->buf, frame_tvb->tvb.length + frame_tvb->offset);
84  
85 if (!frame_read(frame_tvb, &phdr, frame_tvb->buf))
86 { /* TODO: THROW(???); */ }
87 }
88  
89 frame_tvb->tvb.real_data = ws_buffer_start_ptr(frame_tvb->buf) + frame_tvb->offset;
90  
91 wtap_phdr_cleanup(&phdr);
92 }
93  
94 static void
95 frame_free(tvbuff_t *tvb)
96 {
97 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
98  
99 if (frame_tvb->buf) {
100 ws_buffer_free(frame_tvb->buf);
101  
102 g_free(frame_tvb->buf);
103 }
104 }
105  
106 static const guint8 *
107 frame_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length _U_)
108 {
109 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
110  
111 frame_cache(frame_tvb);
112  
113 return tvb->real_data + abs_offset;
114 }
115  
116 static void *
117 frame_memcpy(tvbuff_t *tvb, void *target, guint abs_offset, guint abs_length)
118 {
119 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
120  
121 frame_cache(frame_tvb);
122  
123 return memcpy(target, tvb->real_data + abs_offset, abs_length);
124 }
125  
126 static gint
127 frame_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
128 {
129 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
130 const guint8 *result;
131  
132 frame_cache(frame_tvb);
133  
134 result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
135 if (result)
136 return (gint) (result - tvb->real_data);
137 else
138 return -1;
139 }
140  
141 static gint
142 frame_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
143 {
144 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
145  
146 frame_cache(frame_tvb);
147  
148 return tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle);
149 }
150  
151 static guint
152 frame_offset(const tvbuff_t *tvb _U_, const guint counter)
153 {
154 /* XXX: frame_tvb->offset */
155 return counter;
156 }
157  
158 static tvbuff_t *frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length);
159  
160 static const struct tvb_ops tvb_frame_ops = {
161 sizeof(struct tvb_frame), /* size */
162  
163 frame_free, /* free */
164 frame_offset, /* offset */
165 frame_get_ptr, /* get_ptr */
166 frame_memcpy, /* memcpy */
167 frame_find_guint8, /* find_guint8 */
168 frame_pbrk_guint8, /* pbrk_guint8 */
169 frame_clone, /* clone */
170 };
171  
172 /* based on tvb_new_real_data() */
173 tvbuff_t *
174 frame_tvbuff_new(const frame_data *fd, const guint8 *buf)
175 {
176 struct tvb_frame *frame_tvb;
177 tvbuff_t *tvb;
178  
179 tvb = tvb_new(&tvb_frame_ops);
180  
181 /*
182 * XXX - currently, the length arguments in
183 * tvbuff structure are signed, but the captured
184 * and reported length values are unsigned; this means
185 * that length values > 2^31 - 1 will appear as
186 * negative lengths
187 *
188 * Captured length values that large will already
189 * have been filtered out by the Wiretap modules
190 * (the file will be reported as corrupted), to
191 * avoid trying to allocate large chunks of data.
192 *
193 * Reported length values will not have been
194 * filtered out, and should not be filtered out,
195 * as those lengths are not necessarily invalid.
196 *
197 * For now, we clip the reported length at G_MAXINT
198 *
199 * (XXX, is this still a problem?) There was an exception when we call
200 * tvb_new_real_data() now there's no one
201 */
202  
203 tvb->real_data = buf;
204 tvb->length = fd->cap_len;
205 tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
206 tvb->initialized = TRUE;
207  
208 /*
209 * This is the top-level real tvbuff for this data source,
210 * so its data source tvbuff is itself.
211 */
212 tvb->ds_tvb = tvb;
213  
214 frame_tvb = (struct tvb_frame *) tvb;
215  
216 /* XXX, wtap_can_seek() */
217 if (cfile.wth && cfile.wth->random_fh
218 #ifdef WANT_PACKET_EDITOR
219 && fd->file_off != -1 /* generic clone for modified packets */
220 #endif
221 ) {
222 frame_tvb->wth = cfile.wth;
223 frame_tvb->file_off = fd->file_off;
224 frame_tvb->offset = 0;
225 } else
226 frame_tvb->wth = NULL;
227  
228 frame_tvb->buf = NULL;
229  
230 return tvb;
231 }
232  
233 tvbuff_t *
234 frame_tvbuff_new_buffer(const frame_data *fd, Buffer *buf)
235 {
236 return frame_tvbuff_new(fd, ws_buffer_start_ptr(buf));
237 }
238  
239 static tvbuff_t *
240 frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
241 {
242 struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
243  
244 tvbuff_t *cloned_tvb;
245 struct tvb_frame *cloned_frame_tvb;
246  
247 /* file not seekable */
248 if (!frame_tvb->wth)
249 return NULL;
250  
251 abs_offset += frame_tvb->offset;
252  
253 cloned_tvb = tvb_new(&tvb_frame_ops);
254  
255 /* data will be read when needed */
256 cloned_tvb->real_data = NULL;
257 cloned_tvb->length = abs_length;
258 cloned_tvb->reported_length = abs_length; /* XXX? */
259 cloned_tvb->initialized = TRUE;
260  
261 /*
262 * This is the top-level real tvbuff for this data source,
263 * so its data source tvbuff is itself.
264 */
265 cloned_tvb->ds_tvb = cloned_tvb;
266  
267 cloned_frame_tvb = (struct tvb_frame *) cloned_tvb;
268 cloned_frame_tvb->wth = frame_tvb->wth;
269 cloned_frame_tvb->file_off = frame_tvb->file_off;
270 cloned_frame_tvb->offset = abs_offset;
271 cloned_frame_tvb->buf = NULL;
272  
273 return cloned_tvb;
274 }
275  
276  
277 /* based on tvb_new_real_data() */
278 tvbuff_t *
279 file_tvbuff_new(const frame_data *fd, const guint8 *buf)
280 {
281 struct tvb_frame *frame_tvb;
282 tvbuff_t *tvb;
283  
284 tvb = tvb_new(&tvb_frame_ops);
285  
286 /*
287 * XXX - currently, the length arguments in
288 * tvbuff structure are signed, but the captured
289 * and reported length values are unsigned; this means
290 * that length values > 2^31 - 1 will appear as
291 * negative lengths
292 *
293 * Captured length values that large will already
294 * have been filtered out by the Wiretap modules
295 * (the file will be reported as corrupted), to
296 * avoid trying to allocate large chunks of data.
297 *
298 * Reported length values will not have been
299 * filtered out, and should not be filtered out,
300 * as those lengths are not necessarily invalid.
301 *
302 * For now, we clip the reported length at G_MAXINT
303 *
304 * (XXX, is this still a problem?) There was an exception when we call
305 * tvb_new_real_data() now there's no one
306 */
307  
308 tvb->real_data = buf;
309 tvb->length = fd->cap_len;
310 tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
311 tvb->initialized = TRUE;
312  
313 /*
314 * This is the top-level real tvbuff for this data source,
315 * so its data source tvbuff is itself.
316 */
317 tvb->ds_tvb = tvb;
318  
319 frame_tvb = (struct tvb_frame *) tvb;
320  
321 /* XXX, wtap_can_seek() */
322 if (cfile.wth && cfile.wth->random_fh
323 #ifdef WANT_PACKET_EDITOR
324 && fd->file_off != -1 /* generic clone for modified packets */
325 #endif
326 ) {
327 frame_tvb->wth = cfile.wth;
328 frame_tvb->file_off = fd->file_off;
329 frame_tvb->offset = 0;
330 } else
331 frame_tvb->wth = NULL;
332  
333 frame_tvb->buf = NULL;
334  
335 return tvb;
336 }
337  
338 tvbuff_t *
339 file_tvbuff_new_buffer(const frame_data *fd, Buffer *buf)
340 {
341 return frame_tvbuff_new(fd, ws_buffer_start_ptr(buf));
342 }
343  
344 /*
345 * Editor modelines - http://www.wireshark.org/tools/modelines.html
346 *
347 * Local variables:
348 * c-basic-offset: 8
349 * tab-width: 8
350 * indent-tabs-mode: t
351 * End:
352 *
353 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
354 * :indentSize=8:tabSize=8:noTabs=false:
355 */