Use GLibs CLAMP(). The current inlined implementation seems to be wrong:
[obnox/wireshark/wip.git] / epan / tvbuff.c
1 /* tvbuff.c
2  *
3  * Testy, Virtual(-izable) Buffer of guint8*'s
4  *
5  * "Testy" -- the buffer gets mad when an attempt to access data
6  *              beyond the bounds of the buffer. An exception is thrown.
7  *
8  * "Virtual" -- the buffer can have its own data, can use a subset of
9  *              the data of a backing tvbuff, or can be a composite of
10  *              other tvbuffs.
11  *
12  * $Id$
13  *
14  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
15  *
16  * Code to convert IEEE floating point formats to native floating point
17  * derived from code Copyright (c) Ashok Narayanan, 2000
18  *
19  * Wireshark - Network traffic analyzer
20  * By Gerald Combs <gerald@wireshark.org>
21  * Copyright 1998 Gerald Combs
22  *
23  * This program is free software; you can redistribute it and/or
24  * modify it under the terms of the GNU General Public License
25  * as published by the Free Software Foundation; either version 2
26  * of the License, or (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  * GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, write to the Free Software
35  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
36  */
37
38 #ifdef HAVE_CONFIG_H
39 # include "config.h"
40 #endif
41
42 #include <string.h>
43
44 #ifdef HAVE_LIBZ
45 #include <zlib.h>
46 #endif
47
48 #include "pint.h"
49 #include "tvbuff.h"
50 #include "strutil.h"
51 #include "emem.h"
52 #include "proto.h"      /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
53
54 static const guint8*
55 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
56                 int *exception);
57
58 static const guint8*
59 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length);
60
61 #if GLIB_CHECK_VERSION(2,10,0)
62 #else
63 /* We dole out tvbuff's from this memchunk. */
64 static GMemChunk *tvbuff_mem_chunk = NULL;
65 #endif
66
67 void
68 tvbuff_init(void)
69 {
70 #if GLIB_CHECK_VERSION(2,10,0)
71 #else
72         if (!tvbuff_mem_chunk)
73                 tvbuff_mem_chunk = g_mem_chunk_create(tvbuff_t, 20, G_ALLOC_AND_FREE);
74 #endif
75 }
76
77 void
78 tvbuff_cleanup(void)
79 {
80 #if GLIB_CHECK_VERSION(2,10,0)
81 #else
82         if (tvbuff_mem_chunk)
83                 g_mem_chunk_destroy(tvbuff_mem_chunk);
84
85         tvbuff_mem_chunk = NULL;
86 #endif
87 }
88
89 static void
90 tvb_init(tvbuff_t *tvb, tvbuff_type type)
91 {
92         tvb_backing_t   *backing;
93         tvb_comp_t      *composite;
94
95         tvb->type               = type;
96         tvb->initialized        = FALSE;
97         tvb->usage_count        = 1;
98         tvb->length             = 0;
99         tvb->reported_length    = 0;
100         tvb->free_cb            = NULL;
101         tvb->real_data          = NULL;
102         tvb->raw_offset         = -1;
103         tvb->used_in            = NULL;
104         tvb->ds_tvb             = NULL;
105
106         switch(type) {
107                 case TVBUFF_REAL_DATA:
108                         /* Nothing */
109                         break;
110
111                 case TVBUFF_SUBSET:
112                         backing = &tvb->tvbuffs.subset;
113                         backing->tvb    = NULL;
114                         backing->offset = 0;
115                         backing->length = 0;
116                         break;
117
118                 case TVBUFF_COMPOSITE:
119                         composite = &tvb->tvbuffs.composite;
120                         composite->tvbs                 = NULL;
121                         composite->start_offsets        = NULL;
122                         composite->end_offsets          = NULL;
123                         break;
124
125                 default:
126                         DISSECTOR_ASSERT_NOT_REACHED();
127                         break;
128         }
129 }
130
131
132 tvbuff_t*
133 tvb_new(tvbuff_type type)
134 {
135         tvbuff_t        *tvb;
136
137 #if GLIB_CHECK_VERSION(2,10,0)
138         tvb = g_slice_new(tvbuff_t);
139 #else
140         tvb = g_chunk_new(tvbuff_t, tvbuff_mem_chunk);
141 #endif
142
143         tvb_init(tvb, type);
144
145         return tvb;
146 }
147
148 static tvbuff_t*
149 tvb_new_with_subset(guint subset_tvb_offset, guint subset_tvb_length)
150 {
151         tvbuff_t *tvb = tvb_new(TVBUFF_SUBSET);
152         tvb->tvbuffs.subset.offset = subset_tvb_offset;
153         tvb->tvbuffs.subset.length = subset_tvb_length;
154
155         return tvb;
156 }
157
158 void
159 tvb_free(tvbuff_t* tvb)
160 {
161         tvbuff_t        *member_tvb;
162         tvb_comp_t      *composite;
163         GSList          *slist;
164
165         tvb->usage_count--;
166
167         if (tvb->usage_count == 0) {
168                 switch (tvb->type) {
169                 case TVBUFF_REAL_DATA:
170                         if (tvb->free_cb) {
171                                 /*
172                                  * XXX - do this with a union?
173                                  */
174                                 tvb->free_cb((gpointer)tvb->real_data);
175                         }
176                         break;
177
178                 case TVBUFF_SUBSET:
179                         /* This will be NULL if tvb_new_subset() fails because
180                          * reported_length < -1 */
181                         if (tvb->tvbuffs.subset.tvb) {
182                                 tvb_decrement_usage_count(tvb->tvbuffs.subset.tvb, 1);
183                         }
184                         break;
185
186                 case TVBUFF_COMPOSITE:
187                         composite = &tvb->tvbuffs.composite;
188                         for (slist = composite->tvbs; slist != NULL ; slist = slist->next) {
189                                 member_tvb = slist->data;
190                                 tvb_decrement_usage_count(member_tvb, 1);
191                         }
192
193                         g_slist_free(composite->tvbs);
194
195                         g_free(composite->start_offsets);
196                         g_free(composite->end_offsets);
197                         if (tvb->real_data) {
198                                 /*
199                                  * XXX - do this with a union?
200                                  */
201                                 g_free((gpointer)tvb->real_data);
202                         }
203
204                         break;
205                 }
206
207                 if (tvb->used_in) {
208                         g_slist_free(tvb->used_in);
209                 }
210
211 #if GLIB_CHECK_VERSION(2,10,0)
212                 g_slice_free(tvbuff_t, tvb);
213 #else
214                 g_chunk_free(tvb, tvbuff_mem_chunk);
215 #endif
216         }
217 }
218
219 guint
220 tvb_increment_usage_count(tvbuff_t* tvb, guint count)
221 {
222         tvb->usage_count += count;
223
224         return tvb->usage_count;
225 }
226
227 guint
228 tvb_decrement_usage_count(tvbuff_t* tvb, guint count)
229 {
230         if (tvb->usage_count <= count) {
231                 tvb->usage_count = 1;
232                 tvb_free(tvb);
233                 return 0;
234         }
235         else {
236                 tvb->usage_count -= count;
237                 return tvb->usage_count;
238         }
239
240 }
241
242 void
243 tvb_free_chain(tvbuff_t* tvb)
244 {
245         GSList          *slist;
246
247         /* Recursively call tvb_free_chain() */
248         for (slist = tvb->used_in; slist != NULL ; slist = slist->next) {
249                 tvb_free_chain( (tvbuff_t*)slist->data );
250         }
251
252         /* Stop the recursion */
253         tvb_free(tvb);
254 }
255
256
257
258 void
259 tvb_set_free_cb(tvbuff_t* tvb, tvbuff_free_cb_t func)
260 {
261         DISSECTOR_ASSERT(tvb);
262         DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
263         tvb->free_cb = func;
264 }
265
266 static void
267 add_to_used_in_list(tvbuff_t *tvb, tvbuff_t *used_in)
268 {
269         tvb->used_in = g_slist_prepend(tvb->used_in, used_in);
270         tvb_increment_usage_count(tvb, 1);
271 }
272
273 void
274 tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child)
275 {
276         DISSECTOR_ASSERT(parent && child);
277         DISSECTOR_ASSERT(parent->initialized);
278         DISSECTOR_ASSERT(child->initialized);
279         DISSECTOR_ASSERT(child->type == TVBUFF_REAL_DATA);
280         add_to_used_in_list(parent, child);
281 }
282
283 static void
284 tvb_set_real_data_no_exceptions(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length)
285 {
286         tvb->real_data = data;
287         tvb->length = length;
288         tvb->reported_length = reported_length;
289         tvb->initialized = TRUE;
290 }
291
292 void
293 tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length)
294 {
295         DISSECTOR_ASSERT(tvb);
296         DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
297         DISSECTOR_ASSERT(!tvb->initialized);
298
299         THROW_ON(reported_length < -1, ReportedBoundsError);
300
301         tvb_set_real_data_no_exceptions(tvb, data, length, reported_length);
302 }
303
304 tvbuff_t*
305 tvb_new_real_data(const guint8* data, guint length, gint reported_length)
306 {
307         tvbuff_t        *tvb;
308
309         THROW_ON(reported_length < -1, ReportedBoundsError);
310
311         tvb = tvb_new(TVBUFF_REAL_DATA);
312
313         tvb_set_real_data_no_exceptions(tvb, data, length, reported_length);
314
315         /*
316          * This is the top-level real tvbuff for this data source,
317          * so its data source tvbuff is itself.
318          */
319         tvb->ds_tvb = tvb;
320
321         return tvb;
322 }
323
324 tvbuff_t*
325 tvb_new_child_real_data(tvbuff_t *parent, const guint8* data, guint length, gint reported_length)
326 {
327         tvbuff_t *tvb = tvb_new_real_data(data, length, reported_length);
328         if (tvb) {
329                 tvb_set_child_real_data_tvbuff (parent, tvb);
330         }
331
332         return tvb;
333 }
334
335 /* Computes the absolute offset and length based on a possibly-negative offset
336  * and a length that is possible -1 (which means "to the end of the data").
337  * Returns TRUE/FALSE indicating whether the offset is in bounds or
338  * not. The integer ptrs are modified with the new offset and length.
339  * No exception is thrown.
340  *
341  * XXX - we return TRUE, not FALSE, if the offset is positive and right
342  * after the end of the tvbuff (i.e., equal to the length).  We do this
343  * so that a dissector constructing a subset tvbuff for the next protocol
344  * will get a zero-length tvbuff, not an exception, if there's no data
345  * left for the next protocol - we want the next protocol to be the one
346  * that gets an exception, so the error is reported as an error in that
347  * protocol rather than the containing protocol.  */
348 static gboolean
349 compute_offset_length(guint tvb_length, guint tvb_reported_length, gint offset, gint length,
350                 guint *offset_ptr, guint *length_ptr, int *exception)
351 {
352         DISSECTOR_ASSERT(offset_ptr);
353         DISSECTOR_ASSERT(length_ptr);
354
355         /* Compute the offset */
356         if (offset >= 0) {
357                 /* Positive offset - relative to the beginning of the packet. */
358                 if ((guint) offset > tvb_reported_length) {
359                         if (exception) {
360                                 *exception = ReportedBoundsError;
361                         }
362                         return FALSE;
363                 }
364                 else if ((guint) offset > tvb_length) {
365                         if (exception) {
366                                 *exception = BoundsError;
367                         }
368                         return FALSE;
369                 }
370                 else {
371                         *offset_ptr = offset;
372                 }
373         }
374         else {
375                 /* Negative offset - relative to the end of the packet. */
376                 if ((guint) -offset > tvb_reported_length) {
377                         if (exception) {
378                                 *exception = ReportedBoundsError;
379                         }
380                         return FALSE;
381                 }
382                 else if ((guint) -offset > tvb_length) {
383                         if (exception) {
384                                 *exception = BoundsError;
385                         }
386                         return FALSE;
387                 }
388                 else {
389                         *offset_ptr = tvb_length + offset;
390                 }
391         }
392
393         /* Compute the length */
394         if (length < -1) {
395                 if (exception) {
396                         /* XXX - ReportedBoundsError? */
397                         *exception = BoundsError;
398                 }
399                 return FALSE;
400         }
401         else if (length == -1) {
402                 *length_ptr = tvb_length - *offset_ptr;
403         }
404         else {
405                 *length_ptr = length;
406         }
407
408         return TRUE;
409 }
410
411
412 static gboolean
413 check_offset_length_no_exception(guint tvb_length, guint tvb_reported_length, gint offset, gint length,
414                 guint *offset_ptr, guint *length_ptr, int *exception)
415 {
416         guint   end_offset;
417
418         if (!compute_offset_length(tvb_length, tvb_reported_length, offset, length, offset_ptr, length_ptr, exception)) {
419                 return FALSE;
420         }
421
422         /*
423          * Compute the offset of the first byte past the length.
424          */
425         end_offset = *offset_ptr + *length_ptr;
426
427         /*
428          * Check for an overflow, and clamp "end_offset" at the maximum
429          * if we got an overflow - that should force us to indicate that
430          * we're past the end of the tvbuff.
431          */
432         if (end_offset < *offset_ptr)
433                 end_offset = UINT_MAX;
434
435         /*
436          * Check whether that offset goes more than one byte past the
437          * end of the buffer.
438          *
439          * If not, return TRUE; otherwise, return FALSE and, if "exception"
440          * is non-null, return the appropriate exception through it.
441          */
442         if (end_offset <= tvb_length) {
443                 return TRUE;
444         }
445         else if (end_offset <= tvb_reported_length) {
446                 if (exception) {
447                         *exception = BoundsError;
448                 }
449         }
450         else {
451                 if (exception) {
452                         *exception = ReportedBoundsError;
453                 }
454         }
455
456         return FALSE;
457 }
458
459 /* Checks (+/-) offset and length and throws an exception if
460  * either is out of bounds. Sets integer ptrs to the new offset
461  * and length. */
462 static void
463 check_offset_length(guint tvb_length, guint tvb_reported_length, gint offset, gint length,
464                 guint *offset_ptr, guint *length_ptr)
465 {
466         int exception = 0;
467
468         if (!check_offset_length_no_exception(tvb_length, tvb_reported_length, offset, length, offset_ptr, length_ptr, &exception)) {
469                 DISSECTOR_ASSERT(exception > 0);
470                 THROW(exception);
471         }
472 }
473
474 static void
475 tvb_set_subset_no_exceptions(tvbuff_t *tvb, tvbuff_t *backing, gint reported_length)
476 {
477         tvb->tvbuffs.subset.tvb         = backing;
478         tvb->length                     = tvb->tvbuffs.subset.length;
479
480         if (reported_length == -1) {
481                 tvb->reported_length    = backing->reported_length - tvb->tvbuffs.subset.offset;
482         }
483         else {
484                 tvb->reported_length    = reported_length;
485         }
486         tvb->initialized                = TRUE;
487         add_to_used_in_list(backing, tvb);
488
489         /* Optimization. If the backing buffer has a pointer to contiguous, real data,
490          * then we can point directly to our starting offset in that buffer */
491         if (backing->real_data != NULL) {
492                 tvb->real_data = backing->real_data + tvb->tvbuffs.subset.offset;
493         }
494 }
495
496 void
497 tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing,
498                 gint backing_offset, gint backing_length, gint reported_length)
499 {
500         DISSECTOR_ASSERT(tvb);
501         DISSECTOR_ASSERT(tvb->type == TVBUFF_SUBSET);
502         DISSECTOR_ASSERT(!tvb->initialized);
503
504         THROW_ON(reported_length < -1, ReportedBoundsError);
505
506         check_offset_length(backing->length, backing->reported_length, backing_offset, backing_length,
507                         &tvb->tvbuffs.subset.offset,
508                         &tvb->tvbuffs.subset.length);
509
510         tvb_set_subset_no_exceptions(tvb, backing, reported_length);
511 }
512
513 tvbuff_t*
514 tvb_new_subset(tvbuff_t *backing, gint backing_offset, gint backing_length, gint reported_length)
515 {
516         tvbuff_t        *tvb;
517         guint           subset_tvb_offset;
518         guint           subset_tvb_length;
519
520         THROW_ON(reported_length < -1, ReportedBoundsError);
521
522         check_offset_length(backing->length, backing->reported_length, backing_offset, backing_length,
523                         &subset_tvb_offset,
524                         &subset_tvb_length);
525
526         tvb = tvb_new_with_subset(subset_tvb_offset, subset_tvb_length);
527
528         tvb_set_subset_no_exceptions(tvb, backing, reported_length);
529
530         /*
531          * The top-level data source of this tvbuff is the top-level
532          * data source of its parent.
533          */
534         tvb->ds_tvb = backing->ds_tvb;
535
536         return tvb;
537 }
538
539 tvbuff_t*
540 tvb_new_subset_remaining(tvbuff_t *backing, gint backing_offset)
541 {
542         tvbuff_t        *tvb;
543         guint           subset_tvb_offset;
544         guint           subset_tvb_length;
545
546         check_offset_length(backing->length, backing->reported_length, backing_offset, -1 /* backing_length */,
547                         &subset_tvb_offset,
548                         &subset_tvb_length);
549
550         tvb = tvb_new_with_subset(subset_tvb_offset, subset_tvb_length);
551
552         tvb_set_subset_no_exceptions(tvb, backing, -1 /* reported_length */);
553
554         /*
555          * The top-level data source of this tvbuff is the top-level
556          * data source of its parent.
557          */
558         tvb->ds_tvb = backing->ds_tvb;
559
560         return tvb;
561 }
562
563 void
564 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
565 {
566         tvb_comp_t      *composite;
567
568         DISSECTOR_ASSERT(tvb && !tvb->initialized);
569         DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
570         composite = &tvb->tvbuffs.composite;
571         composite->tvbs = g_slist_append( composite->tvbs, member );
572         add_to_used_in_list(tvb, member);
573 }
574
575 void
576 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
577 {
578         tvb_comp_t      *composite;
579
580         DISSECTOR_ASSERT(tvb && !tvb->initialized);
581         DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
582         composite = &tvb->tvbuffs.composite;
583         composite->tvbs = g_slist_prepend( composite->tvbs, member );
584         add_to_used_in_list(tvb, member);
585 }
586
587 tvbuff_t*
588 tvb_new_composite(void)
589 {
590         return tvb_new(TVBUFF_COMPOSITE);
591 }
592
593 void
594 tvb_composite_finalize(tvbuff_t* tvb)
595 {
596         GSList          *slist;
597         guint           num_members;
598         tvbuff_t        *member_tvb;
599         tvb_comp_t      *composite;
600         int             i = 0;
601
602         DISSECTOR_ASSERT(tvb && !tvb->initialized);
603         DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
604         DISSECTOR_ASSERT(tvb->length == 0);
605
606         composite = &tvb->tvbuffs.composite;
607         num_members = g_slist_length(composite->tvbs);
608
609         composite->start_offsets = g_new(guint, num_members);
610         composite->end_offsets = g_new(guint, num_members);
611
612         for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
613                 DISSECTOR_ASSERT((guint) i < num_members);
614                 member_tvb = slist->data;
615                 composite->start_offsets[i] = tvb->length;
616                 tvb->length += member_tvb->length;
617                 composite->end_offsets[i] = tvb->length - 1;
618                 i++;
619         }
620
621         tvb->initialized = TRUE;
622 }
623
624
625
626 guint
627 tvb_length(tvbuff_t* tvb)
628 {
629         DISSECTOR_ASSERT(tvb && tvb->initialized);
630
631         return tvb->length;
632 }
633
634 gint
635 tvb_length_remaining(tvbuff_t *tvb, gint offset)
636 {
637         guint   abs_offset, abs_length;
638
639         DISSECTOR_ASSERT(tvb && tvb->initialized);
640
641         if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
642                 return abs_length;
643         }
644         else {
645                 return -1;
646         }
647 }
648
649 guint
650 tvb_ensure_length_remaining(tvbuff_t *tvb, gint offset)
651 {
652         guint   abs_offset, abs_length;
653         int     exception;
654
655         DISSECTOR_ASSERT(tvb && tvb->initialized);
656
657         if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, &exception)) {
658                 THROW(exception);
659         }
660         if (abs_length == 0) {
661                 /*
662                  * This routine ensures there's at least one byte available.
663                  * There aren't any bytes available, so throw the appropriate
664                  * exception.
665                  */
666                 if (abs_offset >= tvb->reported_length)
667                         THROW(ReportedBoundsError);
668                 else
669                         THROW(BoundsError);
670         }
671         return abs_length;
672 }
673
674
675
676
677 /* Validates that 'length' bytes are available starting from
678  * offset (pos/neg). Does not throw an exception. */
679 gboolean
680 tvb_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
681 {
682         guint           abs_offset, abs_length;
683
684         DISSECTOR_ASSERT(tvb && tvb->initialized);
685
686         if (!compute_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length, NULL))
687                 return FALSE;
688
689         if (abs_offset + abs_length <= tvb->length) {
690                 return TRUE;
691         }
692         else {
693                 return FALSE;
694         }
695 }
696
697 /* Validates that 'length' bytes are available starting from
698  * offset (pos/neg). Throws an exception if they aren't. */
699 void
700 tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
701 {
702         guint           abs_offset, abs_length;
703
704         DISSECTOR_ASSERT(tvb && tvb->initialized);
705
706         /*
707          * -1 doesn't mean "until end of buffer", as that's pointless
708          * for this routine.  We must treat it as a Really Large Positive
709          * Number, so that we throw an exception; we throw
710          * ReportedBoundsError, as if it were past even the end of a
711          * reassembled packet, and past the end of even the data we
712          * didn't capture.
713          *
714          * We do the same with other negative lengths.
715          */
716         if (length < 0) {
717                 THROW(ReportedBoundsError);
718         }
719         check_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length);
720 }
721
722 gboolean
723 tvb_offset_exists(tvbuff_t *tvb, gint offset)
724 {
725         guint           abs_offset, abs_length;
726
727         DISSECTOR_ASSERT(tvb && tvb->initialized);
728         if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL))
729                 return FALSE;
730
731         if (abs_offset < tvb->length) {
732                 return TRUE;
733         }
734         else {
735                 return FALSE;
736         }
737 }
738
739 guint
740 tvb_reported_length(tvbuff_t* tvb)
741 {
742         DISSECTOR_ASSERT(tvb && tvb->initialized);
743
744         return tvb->reported_length;
745 }
746
747 gint
748 tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
749 {
750         guint   abs_offset, abs_length;
751
752         DISSECTOR_ASSERT(tvb && tvb->initialized);
753
754         if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
755                 if (tvb->reported_length >= abs_offset)
756                         return tvb->reported_length - abs_offset;
757                 else
758                         return -1;
759         }
760         else {
761                 return -1;
762         }
763 }
764
765 /* Set the reported length of a tvbuff to a given value; used for protocols
766    whose headers contain an explicit length and where the calling
767    dissector's payload may include padding as well as the packet for
768    this protocol.
769
770    Also adjusts the data length. */
771 void
772 tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
773 {
774         DISSECTOR_ASSERT(tvb && tvb->initialized);
775
776         if (reported_length > tvb->reported_length)
777                 THROW(ReportedBoundsError);
778
779         tvb->reported_length = reported_length;
780         if (reported_length < tvb->length)
781                 tvb->length = reported_length;
782 }
783
784
785 #if 0
786 static const guint8*
787 first_real_data_ptr(tvbuff_t *tvb)
788 {
789         tvbuff_t        *member;
790
791         switch(tvb->type) {
792                 case TVBUFF_REAL_DATA:
793                         return tvb->real_data;
794                 case TVBUFF_SUBSET:
795                         member = tvb->tvbuffs.subset.tvb;
796                         return first_real_data_ptr(member);
797                 case TVBUFF_COMPOSITE:
798                         member = tvb->tvbuffs.composite.tvbs->data;
799                         return first_real_data_ptr(member);
800         }
801
802         DISSECTOR_ASSERT_NOT_REACHED();
803         return NULL;
804 }
805 #endif
806
807 static guint
808 offset_from_real_beginning(tvbuff_t *tvb, guint counter)
809 {
810         tvbuff_t        *member;
811
812         switch(tvb->type) {
813                 case TVBUFF_REAL_DATA:
814                         return counter;
815                 case TVBUFF_SUBSET:
816                         member = tvb->tvbuffs.subset.tvb;
817                         return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
818                 case TVBUFF_COMPOSITE:
819                         member = tvb->tvbuffs.composite.tvbs->data;
820                         return offset_from_real_beginning(member, counter);
821         }
822
823         DISSECTOR_ASSERT_NOT_REACHED();
824         return 0;
825 }
826
827 guint
828 tvb_offset_from_real_beginning(tvbuff_t *tvb)
829 {
830         return offset_from_real_beginning(tvb, 0);
831 }
832
833 static const guint8*
834 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset,
835                 guint abs_length)
836 {
837         guint           i, num_members;
838         tvb_comp_t      *composite;
839         tvbuff_t        *member_tvb = NULL;
840         guint           member_offset, member_length;
841         GSList          *slist;
842
843         DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
844
845         /* Maybe the range specified by offset/length
846          * is contiguous inside one of the member tvbuffs */
847         composite = &tvb->tvbuffs.composite;
848         num_members = g_slist_length(composite->tvbs);
849
850         for (i = 0; i < num_members; i++) {
851                 if (abs_offset <= composite->end_offsets[i]) {
852                         slist = g_slist_nth(composite->tvbs, i);
853                         member_tvb = slist->data;
854                         break;
855                 }
856         }
857         DISSECTOR_ASSERT(member_tvb);
858
859         if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
860                                 abs_length, &member_offset, &member_length, NULL)) {
861
862                 /*
863                  * The range is, in fact, contiguous within member_tvb.
864                  */
865                 DISSECTOR_ASSERT(!tvb->real_data);
866                 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
867         }
868         else {
869                 tvb->real_data = tvb_memdup(tvb, 0, -1);
870                 return tvb->real_data + abs_offset;
871         }
872
873         DISSECTOR_ASSERT_NOT_REACHED();
874         return NULL;
875 }
876
877 static const guint8*
878 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
879                 int *exception)
880 {
881         guint   abs_offset, abs_length;
882
883         if (!check_offset_length_no_exception(tvb->length, tvb->reported_length, offset, length,
884                 &abs_offset, &abs_length, exception)) {
885                 return NULL;
886         }
887
888         /*
889          * We know that all the data is present in the tvbuff, so
890          * no exceptions should be thrown.
891          */
892         if (tvb->real_data) {
893                 return tvb->real_data + abs_offset;
894         }
895         else {
896                 switch(tvb->type) {
897                         case TVBUFF_REAL_DATA:
898                                 DISSECTOR_ASSERT_NOT_REACHED();
899                         case TVBUFF_SUBSET:
900                                 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
901                                                 abs_offset - tvb->tvbuffs.subset.offset,
902                                                 abs_length, NULL);
903                         case TVBUFF_COMPOSITE:
904                                 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
905                 }
906         }
907
908         DISSECTOR_ASSERT_NOT_REACHED();
909         return NULL;
910 }
911
912 static const guint8*
913 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
914 {
915         int exception;
916         const guint8 *p;
917
918         p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
919         if (p == NULL) {
920                 DISSECTOR_ASSERT(exception > 0);
921                 THROW(exception);
922         }
923         return p;
924 }
925
926 static const guint8*
927 fast_ensure_contiguous(tvbuff_t *tvb, gint offset, guint length)
928 {
929         guint   end_offset;
930         guint   u_offset;
931
932         DISSECTOR_ASSERT(tvb && tvb->initialized);
933         /* We don't check for overflow in this fast path so we only handle simple types */
934         DISSECTOR_ASSERT(length <= 8);
935
936         if (offset < 0 || !tvb->real_data) {
937                 return ensure_contiguous(tvb, offset, length);
938         }
939
940         u_offset = offset;
941         end_offset = u_offset + length;
942
943         if (end_offset <= tvb->length) {
944                 return tvb->real_data + u_offset;
945         }
946
947         if (end_offset > tvb->reported_length) {
948                 THROW(ReportedBoundsError);
949         }
950         THROW(BoundsError);
951         /* not reached */
952         return NULL;
953 }
954
955 static const guint8*
956 guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
957 {
958         const guint8    *b;
959         int             i;
960
961         for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
962                 if (*b == needle) {
963                         return b;
964                 }
965         }
966
967         return NULL;
968 }
969
970 static const guint8*
971 guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles)
972 {
973         const guint8    *b;
974         int             i;
975         guint8          item, needle;
976         const guint8    *needlep;
977
978         for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
979                 item = *b;
980                 needlep = needles;
981                 while ((needle = *needlep) != '\0') {
982                         if (item == needle)
983                                 return b;
984                         needlep++;
985                 }
986         }
987
988         return NULL;
989 }
990
991
992
993 /************** ACCESSORS **************/
994
995 static void*
996 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_length)
997 {
998         guint           i, num_members;
999         tvb_comp_t      *composite;
1000         tvbuff_t        *member_tvb = NULL;
1001         guint           member_offset, member_length;
1002         gboolean        retval;
1003         GSList          *slist;
1004
1005         DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
1006
1007         /* Maybe the range specified by offset/length
1008          * is contiguous inside one of the member tvbuffs */
1009         composite = &tvb->tvbuffs.composite;
1010         num_members = g_slist_length(composite->tvbs);
1011
1012         for (i = 0; i < num_members; i++) {
1013                 if (abs_offset <= composite->end_offsets[i]) {
1014                         slist = g_slist_nth(composite->tvbs, i);
1015                         member_tvb = slist->data;
1016                         break;
1017                 }
1018         }
1019         DISSECTOR_ASSERT(member_tvb);
1020
1021         if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
1022                                 (gint) abs_length, &member_offset, &member_length, NULL)) {
1023
1024                 DISSECTOR_ASSERT(!tvb->real_data);
1025                 return tvb_memcpy(member_tvb, target, member_offset, member_length);
1026         }
1027         else {
1028                 /* The requested data is non-contiguous inside
1029                  * the member tvb. We have to memcpy() the part that's in the member tvb,
1030                  * then iterate across the other member tvb's, copying their portions
1031                  * until we have copied all data.
1032                  */
1033                 retval = compute_offset_length(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i], -1,
1034                                 &member_offset, &member_length, NULL);
1035                 DISSECTOR_ASSERT(retval);
1036
1037                 tvb_memcpy(member_tvb, target, member_offset, member_length);
1038                 abs_offset      += member_length;
1039                 abs_length      -= member_length;
1040
1041                 /* Recurse */
1042                 if (abs_length > 0) {
1043                         composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
1044                 }
1045
1046                 return target;
1047         }
1048
1049         DISSECTOR_ASSERT_NOT_REACHED();
1050         return NULL;
1051 }
1052
1053 void*
1054 tvb_memcpy(tvbuff_t *tvb, void* target, gint offset, size_t length)
1055 {
1056         guint   abs_offset, abs_length;
1057
1058         DISSECTOR_ASSERT(tvb && tvb->initialized);
1059
1060         /*
1061          * XXX - we should eliminate the "length = -1 means 'to the end
1062          * of the tvbuff'" convention, and use other means to achieve
1063          * that; this would let us eliminate a bunch of checks for
1064          * negative lengths in cases where the protocol has a 32-bit
1065          * length field.
1066          *
1067          * Allowing -1 but throwing an assertion on other negative
1068          * lengths is a bit more work with the length being a size_t;
1069          * instead, we check for a length <= 2^31-1.
1070          */
1071         DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
1072         check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1073
1074         if (tvb->real_data) {
1075                 return memcpy(target, tvb->real_data + abs_offset, abs_length);
1076         }
1077
1078         switch(tvb->type) {
1079                 case TVBUFF_REAL_DATA:
1080                         DISSECTOR_ASSERT_NOT_REACHED();
1081
1082                 case TVBUFF_SUBSET:
1083                         return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
1084                                         abs_offset - tvb->tvbuffs.subset.offset,
1085                                         abs_length);
1086
1087                 case TVBUFF_COMPOSITE:
1088                         return composite_memcpy(tvb, target, offset, length);
1089         }
1090
1091         DISSECTOR_ASSERT_NOT_REACHED();
1092         return NULL;
1093 }
1094
1095
1096 /*
1097  * XXX - this doesn't treat a length of -1 as an error.
1098  * If it did, this could replace some code that calls
1099  * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1100  * data to it.
1101  *
1102  * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1103  * an error; does anything else depend on this routine treating -1 as
1104  * meaning "to the end of the buffer"?
1105  */
1106 void*
1107 tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1108 {
1109         guint   abs_offset, abs_length;
1110         void    *duped;
1111
1112         DISSECTOR_ASSERT(tvb && tvb->initialized);
1113
1114         check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1115
1116         duped = g_malloc(abs_length);
1117         return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1118 }
1119
1120 /*
1121  * XXX - this doesn't treat a length of -1 as an error.
1122  * If it did, this could replace some code that calls
1123  * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1124  * data to it.
1125  *
1126  * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1127  * an error; does anything else depend on this routine treating -1 as
1128  * meaning "to the end of the buffer"?
1129  *
1130  * This function allocates memory from a buffer with packet lifetime.
1131  * You do not have to free this buffer, it will be automatically freed
1132  * when wireshark starts decoding the next packet.
1133  * Do not use this function if you want the allocated memory to be persistent
1134  * after the current packet has been dissected.
1135  */
1136 void*
1137 ep_tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1138 {
1139         guint   abs_offset, abs_length;
1140         void    *duped;
1141
1142         DISSECTOR_ASSERT(tvb && tvb->initialized);
1143
1144         check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1145
1146         duped = ep_alloc(abs_length);
1147         return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1148 }
1149
1150
1151
1152 const guint8*
1153 tvb_get_ptr(tvbuff_t *tvb, gint offset, gint length)
1154 {
1155         return ensure_contiguous(tvb, offset, length);
1156 }
1157
1158 /* ---------------- */
1159 guint8
1160 tvb_get_guint8(tvbuff_t *tvb, gint offset)
1161 {
1162         const guint8* ptr;
1163
1164         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint8));
1165         return *ptr;
1166 }
1167
1168 guint16
1169 tvb_get_ntohs(tvbuff_t *tvb, gint offset)
1170 {
1171         const guint8* ptr;
1172
1173         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1174         return pntohs(ptr);
1175 }
1176
1177 guint32
1178 tvb_get_ntoh24(tvbuff_t *tvb, gint offset)
1179 {
1180         const guint8* ptr;
1181
1182         ptr = fast_ensure_contiguous(tvb, offset, 3);
1183         return pntoh24(ptr);
1184 }
1185
1186 guint32
1187 tvb_get_ntohl(tvbuff_t *tvb, gint offset)
1188 {
1189         const guint8* ptr;
1190
1191         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1192         return pntohl(ptr);
1193 }
1194
1195 guint64
1196 tvb_get_ntoh64(tvbuff_t *tvb, gint offset)
1197 {
1198         const guint8* ptr;
1199
1200         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1201         return pntoh64(ptr);
1202 }
1203
1204 /*
1205  * Stuff for IEEE float handling on platforms that don't have IEEE
1206  * format as the native floating-point format.
1207  *
1208  * For now, we treat only the VAX as such a platform.
1209  *
1210  * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1211  * and possibly other machines.
1212  *
1213  * It appears that the official Linux port to System/390 and
1214  * zArchitecture uses IEEE format floating point (not a
1215  * huge surprise).
1216  *
1217  * I don't know whether there are any other machines that
1218  * could run Wireshark and that don't use IEEE format.
1219  * As far as I know, all of the main commercial microprocessor
1220  * families on which OSes that support Wireshark can run
1221  * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1222  * IA-64, and so on).
1223  */
1224
1225 #if defined(vax)
1226
1227 #include <math.h>
1228
1229 /*
1230  * Single-precision.
1231  */
1232 #define IEEE_SP_NUMBER_WIDTH    32      /* bits in number */
1233 #define IEEE_SP_EXP_WIDTH       8       /* bits in exponent */
1234 #define IEEE_SP_MANTISSA_WIDTH  23      /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1235
1236 #define IEEE_SP_SIGN_MASK       0x80000000
1237 #define IEEE_SP_EXPONENT_MASK   0x7F800000
1238 #define IEEE_SP_MANTISSA_MASK   0x007FFFFF
1239 #define IEEE_SP_INFINITY        IEEE_SP_EXPONENT_MASK
1240
1241 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1242 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1243 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1244
1245 static int
1246 ieee_float_is_zero(guint32 w)
1247 {
1248         return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1249 }
1250
1251 static gfloat
1252 get_ieee_float(guint32 w)
1253 {
1254         long sign;
1255         long exponent;
1256         long mantissa;
1257
1258         sign = w & IEEE_SP_SIGN_MASK;
1259         exponent = w & IEEE_SP_EXPONENT_MASK;
1260         mantissa = w & IEEE_SP_MANTISSA_MASK;
1261
1262         if (ieee_float_is_zero(w)) {
1263                 /* number is zero, unnormalized, or not-a-number */
1264                 return 0.0;
1265         }
1266 #if 0
1267         /*
1268          * XXX - how to handle this?
1269          */
1270         if (IEEE_SP_INFINITY == exponent) {
1271                 /*
1272                  * number is positive or negative infinity, or a special value
1273                  */
1274                 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1275         }
1276 #endif
1277
1278         exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1279                 IEEE_SP_MANTISSA_WIDTH;
1280         mantissa |= IEEE_SP_IMPLIED_BIT;
1281
1282         if (sign)
1283                 return -mantissa * pow(2, exponent);
1284         else
1285                 return mantissa * pow(2, exponent);
1286 }
1287
1288 /*
1289  * Double-precision.
1290  * We assume that if you don't have IEEE floating-point, you have a
1291  * compiler that understands 64-bit integral quantities.
1292  */
1293 #define IEEE_DP_NUMBER_WIDTH    64      /* bits in number */
1294 #define IEEE_DP_EXP_WIDTH       11      /* bits in exponent */
1295 #define IEEE_DP_MANTISSA_WIDTH  52      /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1296
1297 #define IEEE_DP_SIGN_MASK       0x8000000000000000LL
1298 #define IEEE_DP_EXPONENT_MASK   0x7FF0000000000000LL
1299 #define IEEE_DP_MANTISSA_MASK   0x000FFFFFFFFFFFFFLL
1300 #define IEEE_DP_INFINITY        IEEE_DP_EXPONENT_MASK
1301
1302 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1303 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1304 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1305
1306 static int
1307 ieee_double_is_zero(guint64 w)
1308 {
1309         return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1310 }
1311
1312 static gdouble
1313 get_ieee_double(guint64 w)
1314 {
1315         gint64 sign;
1316         gint64 exponent;
1317         gint64 mantissa;
1318
1319         sign = w & IEEE_DP_SIGN_MASK;
1320         exponent = w & IEEE_DP_EXPONENT_MASK;
1321         mantissa = w & IEEE_DP_MANTISSA_MASK;
1322
1323         if (ieee_double_is_zero(w)) {
1324                 /* number is zero, unnormalized, or not-a-number */
1325                 return 0.0;
1326         }
1327 #if 0
1328         /*
1329          * XXX - how to handle this?
1330          */
1331         if (IEEE_DP_INFINITY == exponent) {
1332                 /*
1333                  * number is positive or negative infinity, or a special value
1334                  */
1335                 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1336         }
1337 #endif
1338
1339         exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1340                 IEEE_DP_MANTISSA_WIDTH;
1341         mantissa |= IEEE_DP_IMPLIED_BIT;
1342
1343         if (sign)
1344                 return -mantissa * pow(2, exponent);
1345         else
1346                 return mantissa * pow(2, exponent);
1347 }
1348 #endif
1349
1350 /*
1351  * Fetches an IEEE single-precision floating-point number, in
1352  * big-endian form, and returns a "float".
1353  *
1354  * XXX - should this be "double", in case there are IEEE single-
1355  * precision numbers that won't fit in some platform's native
1356  * "float" format?
1357  */
1358 gfloat
1359 tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
1360 {
1361 #if defined(vax)
1362         return get_ieee_float(tvb_get_ntohl(tvb, offset));
1363 #else
1364         union {
1365                 gfloat f;
1366                 guint32 w;
1367         } ieee_fp_union;
1368
1369         ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1370         return ieee_fp_union.f;
1371 #endif
1372 }
1373
1374 /*
1375  * Fetches an IEEE double-precision floating-point number, in
1376  * big-endian form, and returns a "double".
1377  */
1378 gdouble
1379 tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
1380 {
1381 #if defined(vax)
1382         union {
1383                 guint32 w[2];
1384                 guint64 dw;
1385         } ieee_fp_union;
1386 #else
1387         union {
1388                 gdouble d;
1389                 guint32 w[2];
1390         } ieee_fp_union;
1391 #endif
1392
1393 #ifdef WORDS_BIGENDIAN
1394         ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1395         ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1396 #else
1397         ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1398         ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1399 #endif
1400 #if defined(vax)
1401         return get_ieee_double(ieee_fp_union.dw);
1402 #else
1403         return ieee_fp_union.d;
1404 #endif
1405 }
1406
1407 guint16
1408 tvb_get_letohs(tvbuff_t *tvb, gint offset)
1409 {
1410         const guint8* ptr;
1411
1412         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1413         return pletohs(ptr);
1414 }
1415
1416 guint32
1417 tvb_get_letoh24(tvbuff_t *tvb, gint offset)
1418 {
1419         const guint8* ptr;
1420
1421         ptr = fast_ensure_contiguous(tvb, offset, 3);
1422         return pletoh24(ptr);
1423 }
1424
1425 guint32
1426 tvb_get_letohl(tvbuff_t *tvb, gint offset)
1427 {
1428         const guint8* ptr;
1429
1430         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1431         return pletohl(ptr);
1432 }
1433
1434 guint64
1435 tvb_get_letoh64(tvbuff_t *tvb, gint offset)
1436 {
1437         const guint8* ptr;
1438
1439         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1440         return pletoh64(ptr);
1441 }
1442
1443 /*
1444  * Fetches an IEEE single-precision floating-point number, in
1445  * little-endian form, and returns a "float".
1446  *
1447  * XXX - should this be "double", in case there are IEEE single-
1448  * precision numbers that won't fit in some platform's native
1449  * "float" format?
1450  */
1451 gfloat
1452 tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
1453 {
1454 #if defined(vax)
1455         return get_ieee_float(tvb_get_letohl(tvb, offset));
1456 #else
1457         union {
1458                 gfloat f;
1459                 guint32 w;
1460         } ieee_fp_union;
1461
1462         ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1463         return ieee_fp_union.f;
1464 #endif
1465 }
1466
1467 /*
1468  * Fetches an IEEE double-precision floating-point number, in
1469  * little-endian form, and returns a "double".
1470  */
1471 gdouble
1472 tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
1473 {
1474 #if defined(vax)
1475         union {
1476                 guint32 w[2];
1477                 guint64 dw;
1478         } ieee_fp_union;
1479 #else
1480         union {
1481                 gdouble d;
1482                 guint32 w[2];
1483         } ieee_fp_union;
1484 #endif
1485
1486 #ifdef WORDS_BIGENDIAN
1487         ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1488         ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1489 #else
1490         ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1491         ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1492 #endif
1493 #if defined(vax)
1494         return get_ieee_double(ieee_fp_union.dw);
1495 #else
1496         return ieee_fp_union.d;
1497 #endif
1498 }
1499
1500 /* Fetch an IPv4 address, in network byte order.
1501  * We do *not* convert them to host byte order; we leave them in
1502  * network byte order. */
1503 guint32
1504 tvb_get_ipv4(tvbuff_t *tvb, gint offset)
1505 {
1506         const guint8* ptr;
1507         guint32 addr;
1508
1509         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1510         memcpy(&addr, ptr, sizeof addr);
1511         return addr;
1512 }
1513
1514 /* Fetch an IPv6 address. */
1515 void
1516 tvb_get_ipv6(tvbuff_t *tvb, gint offset, struct e_in6_addr *addr)
1517 {
1518         const guint8* ptr;
1519
1520         ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1521         memcpy(addr, ptr, sizeof *addr);
1522 }
1523
1524 /* Fetch a GUID. */
1525 void
1526 tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1527 {
1528         ensure_contiguous(tvb, offset, sizeof(*guid));
1529         guid->data1 = tvb_get_ntohl(tvb, offset);
1530         guid->data2 = tvb_get_ntohs(tvb, offset + 4);
1531         guid->data3 = tvb_get_ntohs(tvb, offset + 6);
1532         tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1533 }
1534
1535 void
1536 tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1537 {
1538         ensure_contiguous(tvb, offset, sizeof(*guid));
1539         guid->data1 = tvb_get_letohl(tvb, offset);
1540         guid->data2 = tvb_get_letohs(tvb, offset + 4);
1541         guid->data3 = tvb_get_letohs(tvb, offset + 6);
1542         tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1543 }
1544
1545 void
1546 tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian)
1547 {
1548         if (little_endian) {
1549                 tvb_get_letohguid(tvb, offset, guid);
1550         } else {
1551                 tvb_get_ntohguid(tvb, offset, guid);
1552         }
1553 }
1554
1555 static const guint8 bit_mask8[] = {
1556         0xff,
1557         0x7f,
1558         0x3f,
1559         0x1f,
1560         0x0f,
1561         0x07,
1562         0x03,
1563         0x01
1564 };
1565
1566 /* Bit offset mask for number of bits = 8 - 16 */
1567 static const guint16 bit_mask16[] = {
1568         0xffff,
1569         0x7fff,
1570         0x3fff,
1571         0x1fff,
1572         0x0fff,
1573         0x07ff,
1574         0x03ff,
1575         0x01ff
1576 };
1577
1578 /* Get 1 - 8 bits */
1579 guint8
1580 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, gint no_of_bits)
1581 {
1582         gint    offset;
1583         guint16 value = 0;
1584         guint8  tot_no_bits;
1585
1586         if (no_of_bits>8) {
1587                 DISSECTOR_ASSERT_NOT_REACHED();
1588         }
1589         /* Byte align offset */
1590         offset = bit_offset>>3;
1591
1592         /* Find out which mask to use for the most significant octet
1593          * by convering bit_offset into the offset into the first
1594          * fetched octet.
1595          */
1596         bit_offset = bit_offset & 0x7;
1597         tot_no_bits = bit_offset+no_of_bits;
1598         if(tot_no_bits<=8){
1599                 /* Read one octet, mask off bit_offset bits and left shift out the unused bits */
1600                 value = tvb_get_guint8(tvb,offset) & bit_mask8[bit_offset];
1601                 value = value >> (8-tot_no_bits);
1602         }else{
1603                 /* Read two octets, mask off bit_offset bits and left shift out the unused bits */
1604                 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1605                 value = value >> (16 - tot_no_bits);
1606         }
1607
1608         return (guint8)value;
1609 }
1610
1611 /* Get 9 - 16 bits */
1612 /* Bit offset mask for number of bits = 16 - 32 */
1613 static const guint32 bit_mask32[] = {
1614         0xffffffff,
1615         0x7fffffff,
1616         0x3fffffff,
1617         0x1fffffff,
1618         0x0fffffff,
1619         0x07ffffff,
1620         0x03ffffff,
1621         0x01ffffff
1622 };
1623
1624 guint16
1625 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, gint no_of_bits,gboolean little_endian)
1626 {
1627         gint    offset;
1628         guint16 value = 0;
1629         guint16 tempval = 0;
1630         guint8  tot_no_bits;
1631
1632         if ((no_of_bits<=8)||(no_of_bits>16)) {
1633                 /* If bits <= 8 use tvb_get_bits8 */
1634                 DISSECTOR_ASSERT_NOT_REACHED();
1635         }
1636         if(little_endian){
1637                 DISSECTOR_ASSERT_NOT_REACHED();
1638                 /* This part is not implemented yet */
1639         }
1640
1641         /* Byte align offset */
1642         offset = bit_offset>>3;
1643
1644         /* Find out which mask to use for the most significant octet
1645          * by convering bit_offset into the offset into the first
1646          * fetched octet.
1647          */
1648         bit_offset = bit_offset & 0x7;
1649         tot_no_bits = bit_offset+no_of_bits;
1650         /* Read two octets and mask off bit_offset bits */
1651         value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1652         if(tot_no_bits < 16){
1653                 /* Left shift out the unused bits */
1654                 value = value >> (16 - tot_no_bits);
1655         }else if(tot_no_bits > 16){
1656                 /* Spans three octets, read next octet and shift as needed */
1657                 value = value << (tot_no_bits - 16);
1658                 tempval = tvb_get_guint8(tvb,offset+2);
1659                 tempval = tempval >> (24-tot_no_bits);
1660                 value = value | tempval;
1661         }
1662
1663         return value;
1664 }
1665
1666 /* Bit offset mask for number of bits = 32 - 64 */
1667 static const guint64 bit_mask64[] = {
1668         G_GINT64_CONSTANT(0xffffffffffffffffU),
1669         G_GINT64_CONSTANT(0x7fffffffffffffffU),
1670         G_GINT64_CONSTANT(0x3fffffffffffffffU),
1671         G_GINT64_CONSTANT(0x1fffffffffffffffU),
1672         G_GINT64_CONSTANT(0x0fffffffffffffffU),
1673         G_GINT64_CONSTANT(0x07ffffffffffffffU),
1674         G_GINT64_CONSTANT(0x03ffffffffffffffU),
1675         G_GINT64_CONSTANT(0x01ffffffffffffffU)
1676 };
1677
1678 guint32
1679 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1680 {
1681         gint    offset;
1682         guint32 value = 0;
1683         guint32 tempval = 0;
1684         guint8  tot_no_bits;
1685
1686         if ((no_of_bits<=16)||(no_of_bits>32)) {
1687                 /* If bits <= 16 use tvb_get_bits8 or tvb_get_bits16 */
1688                 DISSECTOR_ASSERT_NOT_REACHED();
1689         }
1690         if(little_endian){
1691                 DISSECTOR_ASSERT_NOT_REACHED();
1692                 /* This part is not implemented yet */
1693         }
1694
1695         /* Byte align offset */
1696         offset = bit_offset>>3;
1697
1698         /* Find out which mask to use for the most significant octet
1699          * by convering bit_offset into the offset into the first
1700          * fetched octet.
1701          */
1702         bit_offset = bit_offset & 0x7;
1703         tot_no_bits = bit_offset+no_of_bits;
1704         /* Read four octets and mask off bit_offset bits */
1705         value = tvb_get_ntohl(tvb,offset) & bit_mask32[bit_offset];
1706         if(tot_no_bits < 32){
1707                 /* Left shift out the unused bits */
1708                 value = value >> (32 - tot_no_bits);
1709         }else if(tot_no_bits > 32){
1710                 /* Spans five octets, read next octet and shift as needed */
1711                 value = value << (tot_no_bits - 32);
1712                 tempval = tvb_get_guint8(tvb,offset+4);
1713                 tempval = tempval >> (40-tot_no_bits);
1714                 value = value | tempval;
1715         }
1716
1717         return value;
1718 }
1719
1720 guint64
1721 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1722 {
1723         gint    offset;
1724         guint64 value = 0;
1725         guint64 tempval = 0;
1726         guint8  tot_no_bits;
1727
1728         if ((no_of_bits<=32)||(no_of_bits>64)) {
1729                 /* If bits <= 32 use tvb_get_bits8, tvb_get_bits16 or tvb_get_bits32 */
1730                 DISSECTOR_ASSERT_NOT_REACHED();
1731         }
1732         if(little_endian){
1733                 DISSECTOR_ASSERT_NOT_REACHED();
1734                 /* This part is not implemented yet */
1735         }
1736
1737         /* Byte align offset */
1738         offset = bit_offset>>3;
1739
1740         /* Find out which mask to use for the most significant octet
1741          * by convering bit_offset into the offset into the first
1742          * fetched octet.
1743          */
1744         bit_offset = bit_offset & 0x7;
1745         tot_no_bits = bit_offset+no_of_bits;
1746         /* Read eight octets and mask off bit_offset bits */
1747         value = tvb_get_ntoh64(tvb,offset) & bit_mask64[bit_offset];
1748         if (tot_no_bits < 64){
1749                 /* Left shift out the unused bits */
1750                 value = value >> (64 - tot_no_bits);
1751         }else if (tot_no_bits > 64){
1752                 /* Spans nine octets, read next octet and shift as needed */
1753                 value = value << (tot_no_bits - 64);
1754                 tempval = tvb_get_guint8(tvb,offset+8);
1755                 tempval = tempval >> (72-tot_no_bits);
1756                 value = value | tempval;
1757         }
1758
1759         return value;
1760 }
1761
1762 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1763  * at most maxlength number of bytes; if maxlength is -1, searches to
1764  * end of tvbuff.
1765  * Returns the offset of the found needle, or -1 if not found.
1766  * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1767  * in that case, -1 will be returned if the boundary is reached before
1768  * finding needle. */
1769 gint
1770 tvb_find_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 needle)
1771 {
1772         const guint8    *result;
1773         guint           abs_offset, junk_length;
1774         guint           tvbufflen;
1775         guint           limit;
1776
1777         DISSECTOR_ASSERT(tvb && tvb->initialized);
1778
1779         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1780
1781         /* Only search to end of tvbuff, w/o throwing exception. */
1782         tvbufflen = tvb_length_remaining(tvb, abs_offset);
1783         if (maxlength == -1) {
1784                 /* No maximum length specified; search to end of tvbuff. */
1785                 limit = tvbufflen;
1786         }
1787         else if (tvbufflen < (guint) maxlength) {
1788                 /* Maximum length goes past end of tvbuff; search to end
1789                    of tvbuff. */
1790                 limit = tvbufflen;
1791         }
1792         else {
1793                 /* Maximum length doesn't go past end of tvbuff; search
1794                    to that value. */
1795                 limit = maxlength;
1796         }
1797
1798         /* If we have real data, perform our search now. */
1799         if (tvb->real_data) {
1800                 result = guint8_find(tvb->real_data + abs_offset, limit, needle);
1801                 if (result == NULL) {
1802                         return -1;
1803                 }
1804                 else {
1805                         return (gint) (result - tvb->real_data);
1806                 }
1807         }
1808
1809         switch(tvb->type) {
1810                 case TVBUFF_REAL_DATA:
1811                         DISSECTOR_ASSERT_NOT_REACHED();
1812
1813                 case TVBUFF_SUBSET:
1814                         return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1815                                         abs_offset - tvb->tvbuffs.subset.offset,
1816                                         limit, needle);
1817
1818                 case TVBUFF_COMPOSITE:
1819                         DISSECTOR_ASSERT_NOT_REACHED();
1820                         /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1821         }
1822
1823         DISSECTOR_ASSERT_NOT_REACHED();
1824         return -1;
1825 }
1826
1827 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1828  * Searches at most maxlength number of bytes; if maxlength is -1, searches
1829  * to end of tvbuff.
1830  * Returns the offset of the found needle, or -1 if not found.
1831  * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1832  * in that case, -1 will be returned if the boundary is reached before
1833  * finding needle. */
1834 gint
1835 tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, gint maxlength, const guint8 *needles)
1836 {
1837         const guint8    *result;
1838         guint           abs_offset, junk_length;
1839         guint           tvbufflen;
1840         guint           limit;
1841
1842         DISSECTOR_ASSERT(tvb && tvb->initialized);
1843
1844         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1845
1846         /* Only search to end of tvbuff, w/o throwing exception. */
1847         tvbufflen = tvb_length_remaining(tvb, abs_offset);
1848         if (maxlength == -1) {
1849                 /* No maximum length specified; search to end of tvbuff. */
1850                 limit = tvbufflen;
1851         }
1852         else if (tvbufflen < (guint) maxlength) {
1853                 /* Maximum length goes past end of tvbuff; search to end
1854                    of tvbuff. */
1855                 limit = tvbufflen;
1856         }
1857         else {
1858                 /* Maximum length doesn't go past end of tvbuff; search
1859                    to that value. */
1860                 limit = maxlength;
1861         }
1862
1863         /* If we have real data, perform our search now. */
1864         if (tvb->real_data) {
1865                 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles);
1866                 if (result == NULL) {
1867                         return -1;
1868                 }
1869                 else {
1870                         return (gint) (result - tvb->real_data);
1871                 }
1872         }
1873
1874         switch(tvb->type) {
1875                 case TVBUFF_REAL_DATA:
1876                         DISSECTOR_ASSERT_NOT_REACHED();
1877
1878                 case TVBUFF_SUBSET:
1879                         return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1880                                         abs_offset - tvb->tvbuffs.subset.offset,
1881                                         limit, needles);
1882
1883                 case TVBUFF_COMPOSITE:
1884                         DISSECTOR_ASSERT_NOT_REACHED();
1885                         /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1886         }
1887
1888         DISSECTOR_ASSERT_NOT_REACHED();
1889         return -1;
1890 }
1891
1892 /* Find size of stringz (NUL-terminated string) by looking for terminating
1893  * NUL.  The size of the string includes the terminating NUL.
1894  *
1895  * If the NUL isn't found, it throws the appropriate exception.
1896  */
1897 guint
1898 tvb_strsize(tvbuff_t *tvb, gint offset)
1899 {
1900         guint   abs_offset, junk_length;
1901         gint    nul_offset;
1902
1903         DISSECTOR_ASSERT(tvb && tvb->initialized);
1904
1905         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1906         nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1907         if (nul_offset == -1) {
1908                 /*
1909                  * OK, we hit the end of the tvbuff, so we should throw
1910                  * an exception.
1911                  *
1912                  * Did we hit the end of the captured data, or the end
1913                  * of the actual data?  If there's less captured data
1914                  * than actual data, we presumably hit the end of the
1915                  * captured data, otherwise we hit the end of the actual
1916                  * data.
1917                  */
1918                 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1919                         THROW(BoundsError);
1920                 } else {
1921                         THROW(ReportedBoundsError);
1922                 }
1923         }
1924         return (nul_offset - abs_offset) + 1;
1925 }
1926
1927 /* Find length of string by looking for end of string ('\0'), up to
1928  * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1929  * of tvbuff.
1930  * Returns -1 if 'maxlength' reached before finding EOS. */
1931 gint
1932 tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
1933 {
1934         gint    result_offset;
1935         guint   abs_offset, junk_length;
1936
1937         DISSECTOR_ASSERT(tvb && tvb->initialized);
1938
1939         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1940
1941         result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1942
1943         if (result_offset == -1) {
1944                 return -1;
1945         }
1946         else {
1947                 return result_offset - abs_offset;
1948         }
1949 }
1950
1951 /*
1952  * Implement strneql etc
1953  */
1954
1955 /*
1956  * Call strncmp after checking if enough chars left, returning 0 if
1957  * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1958  */
1959 gint
1960 tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1961 {
1962         const guint8 *ptr;
1963
1964         ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1965
1966         if (ptr) {
1967                 int cmp = strncmp((const char *)ptr, str, size);
1968
1969                 /*
1970                  * Return 0 if equal, -1 otherwise.
1971                  */
1972                 return (cmp == 0 ? 0 : -1);
1973         } else {
1974                 /*
1975                  * Not enough characters in the tvbuff to match the
1976                  * string.
1977                  */
1978                 return -1;
1979         }
1980 }
1981
1982 /*
1983  * Call g_ascii_strncasecmp after checking if enough chars left, returning
1984  * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1985  */
1986 gint
1987 tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1988 {
1989         const guint8 *ptr;
1990
1991         ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1992
1993         if (ptr) {
1994                 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
1995
1996                 /*
1997                  * Return 0 if equal, -1 otherwise.
1998                  */
1999                 return (cmp == 0 ? 0 : -1);
2000         } else {
2001                 /*
2002                  * Not enough characters in the tvbuff to match the
2003                  * string.
2004                  */
2005                 return -1;
2006         }
2007 }
2008
2009 /*
2010  * Call memcmp after checking if enough chars left, returning 0 if
2011  * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2012  */
2013 gint
2014 tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str, size_t size)
2015 {
2016         const guint8 *ptr;
2017
2018         ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2019
2020         if (ptr) {
2021                 int cmp = memcmp(ptr, str, size);
2022
2023                 /*
2024                  * Return 0 if equal, -1 otherwise.
2025                  */
2026                 return (cmp == 0 ? 0 : -1);
2027         } else {
2028                 /*
2029                  * Not enough characters in the tvbuff to match the
2030                  * string.
2031                  */
2032                 return -1;
2033         }
2034 }
2035
2036 /* Convert a string from Unicode to ASCII.      At the moment we fake it by
2037  * replacing all non-ASCII characters with a '.' )-:  The caller must
2038  * free the result returned.  The len parameter is the number of guint16's
2039  * to convert from Unicode. */
2040 char *
2041 tvb_fake_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
2042 {
2043         char *buffer;
2044         int i;
2045         guint16 character;
2046
2047         /* Make sure we have enough data before allocating the buffer,
2048            so we don't blow up if the length is huge. */
2049         tvb_ensure_bytes_exist(tvb, offset, 2*len);
2050
2051         /* We know we won't throw an exception, so we don't have to worry
2052            about leaking this buffer. */
2053         buffer = g_malloc(len + 1);
2054
2055         for (i = 0; i < len; i++) {
2056                 character = little_endian ? tvb_get_letohs(tvb, offset)
2057                                           : tvb_get_ntohs(tvb, offset);
2058                 buffer[i] = character < 256 ? character : '.';
2059                 offset += 2;
2060         }
2061
2062         buffer[len] = 0;
2063
2064         return buffer;
2065 }
2066
2067 /* Convert a string from Unicode to ASCII.      At the moment we fake it by
2068  * replacing all non-ASCII characters with a '.' )-:   The len parameter is
2069  * the number of guint16's to convert from Unicode.
2070  *
2071  * This function allocates memory from a buffer with packet lifetime.
2072  * You do not have to free this buffer, it will be automatically freed
2073  * when wireshark starts decoding the next packet.
2074  */
2075 char *
2076 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
2077 {
2078         char *buffer;
2079         int i;
2080         guint16 character;
2081
2082         /* Make sure we have enough data before allocating the buffer,
2083            so we don't blow up if the length is huge. */
2084         tvb_ensure_bytes_exist(tvb, offset, 2*len);
2085
2086         /* We know we won't throw an exception, so we don't have to worry
2087            about leaking this buffer. */
2088         buffer = ep_alloc(len + 1);
2089
2090         for (i = 0; i < len; i++) {
2091                 character = little_endian ? tvb_get_letohs(tvb, offset)
2092                                           : tvb_get_ntohs(tvb, offset);
2093                 buffer[i] = character < 256 ? character : '.';
2094                 offset += 2;
2095         }
2096
2097         buffer[len] = 0;
2098
2099         return buffer;
2100 }
2101
2102 /*
2103  * Format the data in the tvb from offset for length ...
2104  */
2105
2106 gchar *
2107 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
2108 {
2109   const guint8 *ptr;
2110   gint len = size;
2111
2112   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2113
2114         len = tvb_length_remaining(tvb, offset);
2115         ptr = ensure_contiguous(tvb, offset, len);
2116
2117   }
2118
2119   return format_text(ptr, len);
2120
2121 }
2122
2123 /*
2124  * Format the data in the tvb from offset for length ...
2125  */
2126
2127 gchar *
2128 tvb_format_text_wsp(tvbuff_t *tvb, gint offset, gint size)
2129 {
2130   const guint8 *ptr;
2131   gint len = size;
2132
2133   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2134
2135         len = tvb_length_remaining(tvb, offset);
2136         ptr = ensure_contiguous(tvb, offset, len);
2137
2138   }
2139
2140   return format_text_wsp(ptr, len);
2141
2142 }
2143
2144 /*
2145  * Like "tvb_format_text()", but for null-padded strings; don't show
2146  * the null padding characters as "\000".
2147  */
2148 gchar *
2149 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
2150 {
2151   const guint8 *ptr, *p;
2152   gint len = size;
2153   gint stringlen;
2154
2155   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2156
2157         len = tvb_length_remaining(tvb, offset);
2158         ptr = ensure_contiguous(tvb, offset, len);
2159
2160   }
2161
2162   for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2163         ;
2164   return format_text(ptr, stringlen);
2165
2166 }
2167
2168 /*
2169  * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2170  * the null padding characters as "\000".
2171  */
2172 gchar *
2173 tvb_format_stringzpad_wsp(tvbuff_t *tvb, gint offset, gint size)
2174 {
2175   const guint8 *ptr, *p;
2176   gint len = size;
2177   gint stringlen;
2178
2179   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2180
2181         len = tvb_length_remaining(tvb, offset);
2182         ptr = ensure_contiguous(tvb, offset, len);
2183
2184   }
2185
2186   for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2187         ;
2188   return format_text_wsp(ptr, stringlen);
2189
2190 }
2191
2192 /*
2193  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2194  * to hold a non-null-terminated string of that length at that offset,
2195  * plus a trailing '\0', copy the string into it, and return a pointer
2196  * to the string.
2197  *
2198  * Throws an exception if the tvbuff ends before the string does.
2199  */
2200 guint8 *
2201 tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
2202 {
2203         const guint8 *ptr;
2204         guint8 *strbuf = NULL;
2205
2206         tvb_ensure_bytes_exist(tvb, offset, length);
2207
2208         ptr = ensure_contiguous(tvb, offset, length);
2209         strbuf = g_malloc(length + 1);
2210         if (length != 0) {
2211                 memcpy(strbuf, ptr, length);
2212         }
2213         strbuf[length] = '\0';
2214         return strbuf;
2215 }
2216 /*
2217  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2218  * to hold a non-null-terminated string of that length at that offset,
2219  * plus a trailing '\0', copy the string into it, and return a pointer
2220  * to the string.
2221  *
2222  * Throws an exception if the tvbuff ends before the string does.
2223  *
2224  * This function allocates memory from a buffer with packet lifetime.
2225  * You do not have to free this buffer, it will be automatically freed
2226  * when wireshark starts decoding the next packet.
2227  * Do not use this function if you want the allocated memory to be persistent
2228  * after the current packet has been dissected.
2229  */
2230 guint8 *
2231 tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, gint length)
2232 {
2233         const guint8 *ptr;
2234         guint8 *strbuf = NULL;
2235
2236         tvb_ensure_bytes_exist(tvb, offset, length);
2237
2238         ptr = ensure_contiguous(tvb, offset, length);
2239         strbuf = ep_alloc(length + 1);
2240         if (length != 0) {
2241                 memcpy(strbuf, ptr, length);
2242         }
2243         strbuf[length] = '\0';
2244         return strbuf;
2245 }
2246
2247 /*
2248  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2249  * to hold a non-null-terminated string of that length at that offset,
2250  * plus a trailing '\0', copy the string into it, and return a pointer
2251  * to the string.
2252  *
2253  * Throws an exception if the tvbuff ends before the string does.
2254  *
2255  * This function allocates memory from a buffer with capture session lifetime.
2256  * You do not have to free this buffer, it will be automatically freed
2257  * when wireshark starts or opens a new capture.
2258  */
2259 guint8 *
2260 tvb_get_seasonal_string(tvbuff_t *tvb, gint offset, gint length)
2261 {
2262         const guint8 *ptr;
2263         guint8 *strbuf = NULL;
2264
2265         tvb_ensure_bytes_exist(tvb, offset, length);
2266
2267         ptr = ensure_contiguous(tvb, offset, length);
2268         strbuf = se_alloc(length + 1);
2269         if (length != 0) {
2270                 memcpy(strbuf, ptr, length);
2271         }
2272         strbuf[length] = '\0';
2273         return strbuf;
2274 }
2275
2276 /*
2277  * Given a tvbuff and an offset, with the offset assumed to refer to
2278  * a null-terminated string, find the length of that string (and throw
2279  * an exception if the tvbuff ends before we find the null), allocate
2280  * a buffer big enough to hold the string, copy the string into it,
2281  * and return a pointer to the string.  Also return the length of the
2282  * string (including the terminating null) through a pointer.
2283  */
2284 guint8 *
2285 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2286 {
2287         guint size;
2288         guint8 *strptr;
2289
2290         size = tvb_strsize(tvb, offset);
2291         strptr = g_malloc(size);
2292         tvb_memcpy(tvb, strptr, offset, size);
2293         *lengthp = size;
2294         return strptr;
2295 }
2296 /*
2297  * Given a tvbuff and an offset, with the offset assumed to refer to
2298  * a null-terminated string, find the length of that string (and throw
2299  * an exception if the tvbuff ends before we find the null), allocate
2300  * a buffer big enough to hold the string, copy the string into it,
2301  * and return a pointer to the string.  Also return the length of the
2302  * string (including the terminating null) through a pointer.
2303  *
2304  * This function allocates memory from a buffer with packet lifetime.
2305  * You do not have to free this buffer, it will be automatically freed
2306  * when wireshark starts decoding the next packet.
2307  * Do not use this function if you want the allocated memory to be persistent
2308  * after the current packet has been dissected.
2309  */
2310 guint8 *
2311 tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2312 {
2313         guint size;
2314         guint8 *strptr;
2315
2316         size = tvb_strsize(tvb, offset);
2317         strptr = ep_alloc(size);
2318         tvb_memcpy(tvb, strptr, offset, size);
2319         *lengthp = size;
2320         return strptr;
2321 }
2322
2323 /*
2324  * Given a tvbuff and an offset, with the offset assumed to refer to
2325  * a null-terminated string, find the length of that string (and throw
2326  * an exception if the tvbuff ends before we find the null), allocate
2327  * a buffer big enough to hold the string, copy the string into it,
2328  * and return a pointer to the string.  Also return the length of the
2329  * string (including the terminating null) through a pointer.
2330  *
2331  * This function allocates memory from a buffer with capture session lifetime.
2332  * You do not have to free this buffer, it will be automatically freed
2333  * when wireshark starts or opens a new capture.
2334  */
2335 guint8 *
2336 tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2337 {
2338         guint size;
2339         guint8 *strptr;
2340
2341         size = tvb_strsize(tvb, offset);
2342         strptr = se_alloc(size);
2343         tvb_memcpy(tvb, strptr, offset, size);
2344         *lengthp = size;
2345         return strptr;
2346 }
2347
2348 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2349  * no more than bufsize number of bytes, including terminating NUL, to buffer.
2350  * Returns length of string (not including terminating NUL), or -1 if the string was
2351  * truncated in the buffer due to not having reached the terminating NUL.
2352  * In this way, it acts like g_snprintf().
2353  *
2354  * bufsize MUST be greater than 0.
2355  *
2356  * When processing a packet where the remaining number of bytes is less
2357  * than bufsize, an exception is not thrown if the end of the packet
2358  * is reached before the NUL is found. If no NUL is found before reaching
2359  * the end of the short packet, -1 is still returned, and the string
2360  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2361  * at the correct spot, terminating the string.
2362  *
2363  * *bytes_copied will contain the number of bytes actually copied,
2364  * including the terminating-NUL.
2365  */
2366 static gint
2367 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
2368                 gint *bytes_copied)
2369 {
2370         gint    stringlen;
2371         guint   abs_offset, junk_length;
2372         gint    limit, len;
2373         gboolean decreased_max = FALSE;
2374
2375         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
2376
2377         /* There must at least be room for the terminating NUL. */
2378         DISSECTOR_ASSERT(bufsize != 0);
2379
2380         /* If there's no room for anything else, just return the NUL. */
2381         if (bufsize == 1) {
2382                 buffer[0] = 0;
2383                 *bytes_copied = 1;
2384                 return 0;
2385         }
2386
2387         /* Only read to end of tvbuff, w/o throwing exception. */
2388         len = tvb_length_remaining(tvb, abs_offset);
2389
2390         /* check_offset_length() won't throw an exception if we're
2391          * looking at the byte immediately after the end of the tvbuff. */
2392         if (len == 0) {
2393                 THROW(ReportedBoundsError);
2394         }
2395
2396         /* This should not happen because check_offset_length() would
2397          * have already thrown an exception if 'offset' were out-of-bounds.
2398          */
2399         DISSECTOR_ASSERT(len != -1);
2400
2401         /*
2402          * If we've been passed a negative number, bufsize will
2403          * be huge.
2404          */
2405         DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2406
2407         if ((guint)len < bufsize) {
2408                 limit = len;
2409                 decreased_max = TRUE;
2410         }
2411         else {
2412                 limit = bufsize;
2413         }
2414
2415         stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2416         /* If NUL wasn't found, copy the data and return -1 */
2417         if (stringlen == -1) {
2418                 tvb_memcpy(tvb, buffer, abs_offset, limit);
2419                 if (decreased_max) {
2420                         buffer[limit] = 0;
2421                         /* Add 1 for the extra NUL that we set at buffer[limit],
2422                          * pretending that it was copied as part of the string. */
2423                         *bytes_copied = limit + 1;
2424                 }
2425                 else {
2426                         *bytes_copied = limit;
2427                 }
2428                 return -1;
2429         }
2430
2431         /* Copy the string to buffer */
2432         tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2433         *bytes_copied = stringlen + 1;
2434         return stringlen;
2435 }
2436
2437 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2438  * no more than bufsize number of bytes, including terminating NUL, to buffer.
2439  * Returns length of string (not including terminating NUL), or -1 if the string was
2440  * truncated in the buffer due to not having reached the terminating NUL.
2441  * In this way, it acts like g_snprintf().
2442  *
2443  * When processing a packet where the remaining number of bytes is less
2444  * than bufsize, an exception is not thrown if the end of the packet
2445  * is reached before the NUL is found. If no NUL is found before reaching
2446  * the end of the short packet, -1 is still returned, and the string
2447  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2448  * at the correct spot, terminating the string.
2449  */
2450 gint
2451 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2452 {
2453         gint bytes_copied;
2454
2455         DISSECTOR_ASSERT(tvb && tvb->initialized);
2456
2457         return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2458 }
2459
2460 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2461  * have a terminating NUL. If the string was truncated when copied into buffer,
2462  * a NUL is placed at the end of buffer to terminate it.
2463  */
2464 gint
2465 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2466 {
2467         gint    len, bytes_copied;
2468
2469         DISSECTOR_ASSERT(tvb && tvb->initialized);
2470
2471         len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2472
2473         if (len == -1) {
2474                 buffer[bufsize - 1] = 0;
2475                 return bytes_copied - 1;
2476         }
2477         else {
2478                 return len;
2479         }
2480 }
2481
2482 /*
2483  * Given a tvbuff, an offset into the tvbuff, and a length that starts
2484  * at that offset (which may be -1 for "all the way to the end of the
2485  * tvbuff"), find the end of the (putative) line that starts at the
2486  * specified offset in the tvbuff, going no further than the specified
2487  * length.
2488  *
2489  * Return the length of the line (not counting the line terminator at
2490  * the end), or, if we don't find a line terminator:
2491  *
2492  *      if "deseg" is true, return -1;
2493  *
2494  *      if "deseg" is false, return the amount of data remaining in
2495  *      the buffer.
2496  *
2497  * Set "*next_offset" to the offset of the character past the line
2498  * terminator, or past the end of the buffer if we don't find a line
2499  * terminator.  (It's not set if we return -1.)
2500  */
2501 gint
2502 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
2503         gboolean desegment)
2504 {
2505         gint eob_offset;
2506         gint eol_offset;
2507         int linelen;
2508
2509         if (len == -1)
2510                 len = tvb_length_remaining(tvb, offset);
2511         /*
2512          * XXX - what if "len" is still -1, meaning "offset is past the
2513          * end of the tvbuff"?
2514          */
2515         eob_offset = offset + len;
2516
2517         /*
2518          * Look either for a CR or an LF.
2519          */
2520         eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n");
2521         if (eol_offset == -1) {
2522                 /*
2523                  * No CR or LF - line is presumably continued in next packet.
2524                  */
2525                 if (desegment) {
2526                         /*
2527                          * Tell our caller we saw no EOL, so they can
2528                          * try to desegment and get the entire line
2529                          * into one tvbuff.
2530                          */
2531                         return -1;
2532                 } else {
2533                         /*
2534                          * Pretend the line runs to the end of the tvbuff.
2535                          */
2536                         linelen = eob_offset - offset;
2537                         *next_offset = eob_offset;
2538                 }
2539         } else {
2540                 /*
2541                  * Find the number of bytes between the starting offset
2542                  * and the CR or LF.
2543                  */
2544                 linelen = eol_offset - offset;
2545
2546                 /*
2547                  * Is it a CR?
2548                  */
2549                 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2550                         /*
2551                          * Yes - is it followed by an LF?
2552                          */
2553                         if (eol_offset + 1 >= eob_offset) {
2554                                 /*
2555                                  * Dunno - the next byte isn't in this
2556                                  * tvbuff.
2557                                  */
2558                                 if (desegment) {
2559                                         /*
2560                                          * We'll return -1, although that
2561                                          * runs the risk that if the line
2562                                          * really *is* terminated with a CR,
2563                                          * we won't properly dissect this
2564                                          * tvbuff.
2565                                          *
2566                                          * It's probably more likely that
2567                                          * the line ends with CR-LF than
2568                                          * that it ends with CR by itself.
2569                                          */
2570                                         return -1;
2571                                 }
2572                         } else {
2573                                 /*
2574                                  * Well, we can at least look at the next
2575                                  * byte.
2576                                  */
2577                                 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2578                                         /*
2579                                          * It's an LF; skip over the CR.
2580                                          */
2581                                         eol_offset++;
2582                                 }
2583                         }
2584                 }
2585
2586                 /*
2587                  * Return the offset of the character after the last
2588                  * character in the line, skipping over the last character
2589                  * in the line terminator.
2590                  */
2591                 *next_offset = eol_offset + 1;
2592         }
2593         return linelen;
2594 }
2595
2596 /*
2597  * Given a tvbuff, an offset into the tvbuff, and a length that starts
2598  * at that offset (which may be -1 for "all the way to the end of the
2599  * tvbuff"), find the end of the (putative) line that starts at the
2600  * specified offset in the tvbuff, going no further than the specified
2601  * length.
2602  *
2603  * However, treat quoted strings inside the buffer specially - don't
2604  * treat newlines in quoted strings as line terminators.
2605  *
2606  * Return the length of the line (not counting the line terminator at
2607  * the end), or the amount of data remaining in the buffer if we don't
2608  * find a line terminator.
2609  *
2610  * Set "*next_offset" to the offset of the character past the line
2611  * terminator, or past the end of the buffer if we don't find a line
2612  * terminator.
2613  */
2614 gint
2615 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2616         gint *next_offset)
2617 {
2618         gint cur_offset, char_offset;
2619         gboolean is_quoted;
2620         guchar c;
2621         gint eob_offset;
2622         int linelen;
2623
2624         if (len == -1)
2625                 len = tvb_length_remaining(tvb, offset);
2626         /*
2627          * XXX - what if "len" is still -1, meaning "offset is past the
2628          * end of the tvbuff"?
2629          */
2630         eob_offset = offset + len;
2631
2632         cur_offset = offset;
2633         is_quoted = FALSE;
2634         for (;;) {
2635                         /*
2636                  * Is this part of the string quoted?
2637                  */
2638                 if (is_quoted) {
2639                         /*
2640                          * Yes - look only for the terminating quote.
2641                          */
2642                         char_offset = tvb_find_guint8(tvb, cur_offset, len,
2643                                 '"');
2644                 } else {
2645                         /*
2646                          * Look either for a CR, an LF, or a '"'.
2647                          */
2648                         char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2649                                 (const guint8 *)"\r\n\"");
2650                 }
2651                 if (char_offset == -1) {
2652                         /*
2653                          * Not found - line is presumably continued in
2654                          * next packet.
2655                          * We pretend the line runs to the end of the tvbuff.
2656                          */
2657                         linelen = eob_offset - offset;
2658                         *next_offset = eob_offset;
2659                         break;
2660                 }
2661
2662                 if (is_quoted) {
2663                         /*
2664                          * We're processing a quoted string.
2665                          * We only looked for ", so we know it's a ";
2666                          * as we're processing a quoted string, it's a
2667                          * closing quote.
2668                          */
2669                         is_quoted = FALSE;
2670                 } else {
2671                         /*
2672                          * OK, what is it?
2673                          */
2674                         c = tvb_get_guint8(tvb, char_offset);
2675                         if (c == '"') {
2676                                 /*
2677                                  * Un-quoted "; it begins a quoted
2678                                  * string.
2679                                  */
2680                                 is_quoted = TRUE;
2681                         } else {
2682                                 /*
2683                                  * It's a CR or LF; we've found a line
2684                                  * terminator.
2685                                  *
2686                                  * Find the number of bytes between the
2687                                  * starting offset and the CR or LF.
2688                                  */
2689                                 linelen = char_offset - offset;
2690
2691                                 /*
2692                                  * Is it a CR?
2693                                  */
2694                                 if (c == '\r') {
2695                                         /*
2696                                          * Yes; is it followed by an LF?
2697                                          */
2698                                         if (char_offset + 1 < eob_offset &&
2699                                                 tvb_get_guint8(tvb, char_offset + 1)
2700                                                   == '\n') {
2701                                                 /*
2702                                                  * Yes; skip over the CR.
2703                                                  */
2704                                                 char_offset++;
2705                                         }
2706                                 }
2707
2708                                 /*
2709                                  * Return the offset of the character after
2710                                  * the last character in the line, skipping
2711                                  * over the last character in the line
2712                                  * terminator, and quit.
2713                                  */
2714                                 *next_offset = char_offset + 1;
2715                                 break;
2716                         }
2717                 }
2718
2719                 /*
2720                  * Step past the character we found.
2721                  */
2722                 cur_offset = char_offset + 1;
2723                 if (cur_offset >= eob_offset) {
2724                         /*
2725                          * The character we found was the last character
2726                          * in the tvbuff - line is presumably continued in
2727                          * next packet.
2728                          * We pretend the line runs to the end of the tvbuff.
2729                          */
2730                         linelen = eob_offset - offset;
2731                         *next_offset = eob_offset;
2732                         break;
2733                 }
2734         }
2735         return linelen;
2736 }
2737
2738 /*
2739  * Copied from the mgcp dissector. (This function should be moved to /epan )
2740  * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
2741  *                                character following offset or offset + maxlength -1 whichever
2742  *                                is smaller.
2743  *
2744  * Parameters:
2745  * tvb - The tvbuff in which we are skipping whitespace.
2746  * offset - The offset in tvb from which we begin trying to skip whitespace.
2747  * maxlength - The maximum distance from offset that we may try to skip
2748  * whitespace.
2749  *
2750  * Returns: The position in tvb of the first non-whitespace
2751  *                      character following offset or offset + maxlength -1 whichever
2752  *                      is smaller.
2753  */
2754 gint tvb_skip_wsp(tvbuff_t* tvb, gint offset, gint maxlength)
2755 {
2756         gint counter = offset;
2757         gint end = offset + maxlength,tvb_len;
2758         guint8 tempchar;
2759
2760         /* Get the length remaining */
2761         tvb_len = tvb_length(tvb);
2762         end = offset + maxlength;
2763         if (end >= tvb_len)
2764         {
2765                 end = tvb_len;
2766         }
2767
2768         /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
2769         for (counter = offset;
2770                  counter < end &&
2771                   ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2772                   tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
2773                  counter++);
2774
2775         return (counter);
2776 }
2777
2778 gint tvb_skip_wsp_return(tvbuff_t* tvb, gint offset){
2779         gint counter = offset;
2780         gint end;
2781         guint8 tempchar;
2782         end = 0;
2783
2784         for(counter = offset; counter > end &&
2785                 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2786                 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
2787         counter++;
2788         return (counter);
2789 }
2790
2791
2792 /*
2793  * Format a bunch of data from a tvbuff as bytes, returning a pointer
2794  * to the string with the formatted data, with "punct" as a byte
2795  * separator.
2796  */
2797 gchar *
2798 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2799 {
2800         return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2801 }
2802
2803 /*
2804  * Format a bunch of data from a tvbuff as bytes, returning a pointer
2805  * to the string with the formatted data.
2806  */
2807 gchar *
2808 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2809 {
2810         return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2811 }
2812
2813 /* Find a needle tvbuff within a haystack tvbuff. */
2814 gint
2815 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2816 {
2817         guint           haystack_abs_offset, haystack_abs_length;
2818         const guint8    *haystack_data;
2819         const guint8    *needle_data;
2820         const guint     needle_len = needle_tvb->length;
2821         const guint8    *location;
2822
2823         DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
2824
2825         if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2826                 return -1;
2827         }
2828
2829         /* Get pointers to the tvbuffs' data. */
2830         haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2831         needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2832
2833         check_offset_length(haystack_tvb->length, haystack_tvb->reported_length, haystack_offset, -1,
2834                         &haystack_abs_offset, &haystack_abs_length);
2835
2836         location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2837                         needle_data, needle_len);
2838
2839         if (location) {
2840                 return (gint) (location - haystack_data);
2841         }
2842
2843         return -1;
2844 }
2845
2846 #ifdef HAVE_LIBZ
2847 /*
2848  * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2849  * length comprlen.  Returns an uncompressed tvbuffer if uncompression
2850  * succeeded or NULL if uncompression failed.
2851  */
2852 #define TVB_Z_MIN_BUFSIZ 32768
2853 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2854 /* #define TVB_Z_DEBUG 1 */
2855 #undef TVB_Z_DEBUG
2856
2857 tvbuff_t *
2858 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2859 {
2860         gint err = Z_OK;
2861         guint bytes_out = 0;
2862         guint8 *compr = NULL;
2863         guint8 *uncompr = NULL;
2864         tvbuff_t *uncompr_tvb = NULL;
2865         z_streamp strm = NULL;
2866         Bytef *strmbuf = NULL;
2867         guint inits_done = 0;
2868         gint wbits = MAX_WBITS;
2869         guint8 *next = NULL;
2870         guint bufsiz = TVB_Z_MIN_BUFSIZ;
2871 #ifdef TVB_Z_DEBUG
2872         guint inflate_passes = 0;
2873         guint bytes_in = tvb_length_remaining(tvb, offset);
2874 #endif
2875
2876         if (tvb == NULL) {
2877                 return NULL;
2878         }
2879
2880         compr = tvb_memdup(tvb, offset, comprlen);
2881
2882         if (!compr)
2883                 return NULL;
2884
2885         /*
2886          * Assume that the uncompressed data is at least twice as big as
2887          * the compressed size.
2888          */
2889         bufsiz = tvb_length_remaining(tvb, offset) * 2;
2890         bufsiz = CLAMP(bufsiz, TVB_Z_MIN_BUFSIZ, TVB_Z_MAX_BUFSIZ);
2891
2892 #ifdef TVB_Z_DEBUG
2893         printf("bufsiz: %u bytes\n", bufsiz);
2894 #endif
2895
2896         next = compr;
2897
2898         strm = g_malloc0(sizeof(z_stream));
2899         strm->next_in = next;
2900         strm->avail_in = comprlen;
2901
2902         strmbuf = g_malloc0(bufsiz);
2903         strm->next_out = strmbuf;
2904         strm->avail_out = bufsiz;
2905
2906         err = inflateInit2(strm, wbits);
2907         inits_done = 1;
2908         if (err != Z_OK) {
2909                 inflateEnd(strm);
2910                 g_free(strm);
2911                 g_free(compr);
2912                 g_free(strmbuf);
2913                 return NULL;
2914         }
2915
2916         while (1) {
2917                 memset(strmbuf, '\0', bufsiz);
2918                 strm->next_out = strmbuf;
2919                 strm->avail_out = bufsiz;
2920
2921                 err = inflate(strm, Z_SYNC_FLUSH);
2922
2923                 if (err == Z_OK || err == Z_STREAM_END) {
2924                         guint bytes_pass = bufsiz - strm->avail_out;
2925
2926 #ifdef TVB_Z_DEBUG
2927                         ++inflate_passes;
2928 #endif
2929
2930                         if (uncompr == NULL) {
2931                                 uncompr = g_memdup(strmbuf, bytes_pass);
2932                         } else {
2933                                 guint8 *new_data = g_malloc0(bytes_out + bytes_pass);
2934
2935                                 g_memmove(new_data, uncompr, bytes_out);
2936                                 g_memmove((new_data + bytes_out), strmbuf,
2937                                         bytes_pass);
2938
2939                                 g_free(uncompr);
2940                                 uncompr = new_data;
2941                         }
2942
2943                         bytes_out += bytes_pass;
2944
2945                         if ( err == Z_STREAM_END) {
2946                                 inflateEnd(strm);
2947                                 g_free(strm);
2948                                 g_free(strmbuf);
2949                                 break;
2950                         }
2951                 } else if (err == Z_BUF_ERROR) {
2952                         /*
2953                          * It's possible that not enough frames were captured
2954                          * to decompress this fully, so return what we've done
2955                          * so far, if any.
2956                          */
2957                         inflateEnd(strm);
2958                         g_free(strm);
2959                         g_free(strmbuf);
2960
2961                         if (uncompr != NULL) {
2962                                 break;
2963                         } else {
2964                                 g_free(compr);
2965                                 return NULL;
2966                         }
2967
2968                 } else if (err == Z_DATA_ERROR && inits_done == 1
2969                         && uncompr == NULL && (*compr  == 0x1f) &&
2970                         (*(compr + 1) == 0x8b)) {
2971                         /*
2972                          * inflate() is supposed to handle both gzip and deflate
2973                          * streams automatically, but in reality it doesn't
2974                          * seem to handle either (at least not within the
2975                          * context of an HTTP response.)  We have to try
2976                          * several tweaks, depending on the type of data and
2977                          * version of the library installed.
2978                          */
2979
2980                         /*
2981                          * Gzip file format.  Skip past the header, since the
2982                          * fix to make it work (setting windowBits to 31)
2983                          * doesn't work with all versions of the library.
2984                          */
2985                         Bytef *c = compr + 2;
2986                         Bytef flags = 0;
2987
2988                         if (*c == Z_DEFLATED) {
2989                                 c++;
2990                         } else {
2991                                 inflateEnd(strm);
2992                                 g_free(strm);
2993                                 g_free(compr);
2994                                 g_free(strmbuf);
2995                                 return NULL;
2996                         }
2997
2998                         flags = *c;
2999
3000                         /* Skip past the MTIME, XFL, and OS fields. */
3001                         c += 7;
3002
3003                         if (flags & (1 << 2)) {
3004                                 /* An Extra field is present. */
3005                                 gint xsize = (gint)(*c |
3006                                         (*(c + 1) << 8));
3007
3008                                 c += xsize;
3009                         }
3010
3011                         if (flags & (1 << 3)) {
3012                                 /* A null terminated filename */
3013
3014                                 while ((c - compr) < comprlen && *c != '\0') {
3015                                         c++;
3016                                 }
3017
3018                                 c++;
3019                         }
3020
3021                         if (flags & (1 << 4)) {
3022                                 /* A null terminated comment */
3023
3024                                 while ((c - compr) < comprlen && *c != '\0') {
3025                                         c++;
3026                                 }
3027
3028                                 c++;
3029                         }
3030
3031
3032                         inflateReset(strm);
3033                         next = c;
3034                         strm->next_in = next;
3035                         if (c - compr > comprlen) {
3036                                 inflateEnd(strm);
3037                                 g_free(strm);
3038                                 g_free(compr);
3039                                 g_free(strmbuf);
3040                                 return NULL;
3041                         }
3042                         comprlen -= (int) (c - compr);
3043
3044                         inflateEnd(strm);
3045                         err = inflateInit2(strm, wbits);
3046                         inits_done++;
3047                 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
3048                         inits_done <= 3) {
3049
3050                         /*
3051                          * Re-init the stream with a negative
3052                          * MAX_WBITS. This is necessary due to
3053                          * some servers (Apache) not sending
3054                          * the deflate header with the
3055                          * content-encoded response.
3056                          */
3057                         wbits = -MAX_WBITS;
3058
3059                         inflateReset(strm);
3060
3061                         strm->next_in = next;
3062                         strm->avail_in = comprlen;
3063
3064                         inflateEnd(strm);
3065                         memset(strmbuf, '\0', bufsiz);
3066                         strm->next_out = strmbuf;
3067                         strm->avail_out = bufsiz;
3068
3069                         err = inflateInit2(strm, wbits);
3070
3071                         inits_done++;
3072
3073                         if (err != Z_OK) {
3074                                 g_free(strm);
3075                                 g_free(strmbuf);
3076                                 g_free(compr);
3077                                 g_free(uncompr);
3078
3079                                 return NULL;
3080                         }
3081                 } else {
3082                         inflateEnd(strm);
3083                         g_free(strm);
3084                         g_free(strmbuf);
3085                         g_free(compr);
3086
3087                         if (uncompr == NULL) {
3088                                 return NULL;
3089                         }
3090
3091                         break;
3092                 }
3093         }
3094
3095 #ifdef TVB_Z_DEBUG
3096         printf("inflate() total passes: %u\n", inflate_passes);
3097         printf("bytes  in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
3098 #endif
3099
3100         if (uncompr != NULL) {
3101                 uncompr_tvb =  tvb_new_real_data((guint8*) uncompr, bytes_out,
3102                         bytes_out);
3103                 tvb_set_free_cb(uncompr_tvb, g_free);
3104         }
3105         g_free(compr);
3106         return uncompr_tvb;
3107 }
3108 #else
3109 tvbuff_t *
3110 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)
3111 {
3112         return NULL;
3113 }
3114 #endif
3115
3116 tvbuff_t* tvb_child_uncompress(tvbuff_t *parent _U_, tvbuff_t *tvb, int offset, int comprlen)
3117 {
3118         tvbuff_t *new_tvb = tvb_uncompress(tvb, offset, comprlen);
3119         if (new_tvb)
3120                 tvb_set_child_real_data_tvbuff (parent, new_tvb);
3121         return new_tvb;
3122 }
3123