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