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