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