tvbuff.[ch]: Accept more size_t's.
[metze/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, size_t length, size_t 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             = (guint) length;
268         tvb->reported_length    = (guint) reported_length;
269         tvb->initialized        = TRUE;
270 }
271
272 tvbuff_t*
273 tvb_new_real_data(const guint8* data, size_t length, size_t 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, size_t length, size_t 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, size_t 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 = (guint) length;
384         }
385
386         return TRUE;
387 }
388
389
390 static gboolean
391 check_offset_length_no_exception(tvbuff_t *tvb, gint offset, size_t 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, size_t 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, size_t backing_length, size_t 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    = (guint) 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, size_t backing_length, size_t 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, size_t 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, size_t 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  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2116  * to hold a non-null-terminated string of that length at that offset,
2117  * plus a trailing '\0', copy the string into it, and return a pointer
2118  * to the string.
2119  *
2120  * Throws an exception if the tvbuff ends before the string does.
2121  */
2122 guint8 *
2123 tvb_get_string(tvbuff_t *tvb, gint offset, size_t length)
2124 {
2125         const guint8 *ptr;
2126         guint8 *strbuf = NULL;
2127
2128         tvb_ensure_bytes_exist(tvb, offset, length);
2129
2130         ptr = ensure_contiguous(tvb, offset, (gint) length);
2131         strbuf = g_malloc(length + 1);
2132         if (length != 0) {
2133                 memcpy(strbuf, ptr, length);
2134         }
2135         strbuf[length] = '\0';
2136         return strbuf;
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  * This function allocates memory from a buffer with packet lifetime.
2147  * You do not have to free this buffer, it will be automatically freed
2148  * when wireshark starts decoding the next packet.
2149  * Do not use this function if you want the allocated memory to be persistent
2150  * after the current packet has been dissected.
2151  */
2152 guint8 *
2153 tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, size_t length)
2154 {
2155         const guint8 *ptr;
2156         guint8 *strbuf = NULL;
2157
2158         tvb_ensure_bytes_exist(tvb, offset, length);
2159
2160         ptr = ensure_contiguous(tvb, offset, (gint) length);
2161         strbuf = ep_alloc(length + 1);
2162         if (length != 0) {
2163                 memcpy(strbuf, ptr, length);
2164         }
2165         strbuf[length] = '\0';
2166         return strbuf;
2167 }
2168
2169 /*
2170  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2171  * to hold a non-null-terminated string of that length at that offset,
2172  * plus a trailing '\0', copy the string into it, and return a pointer
2173  * to the string.
2174  *
2175  * Throws an exception if the tvbuff ends before the string does.
2176  *
2177  * This function allocates memory from a buffer with capture session lifetime.
2178  * You do not have to free this buffer, it will be automatically freed
2179  * when wireshark starts or opens a new capture.
2180  */
2181 guint8 *
2182 tvb_get_seasonal_string(tvbuff_t *tvb, gint offset, size_t length)
2183 {
2184         const guint8 *ptr;
2185         guint8 *strbuf = NULL;
2186
2187         tvb_ensure_bytes_exist(tvb, offset, length);
2188
2189         ptr = ensure_contiguous(tvb, offset, (gint) length);
2190         strbuf = se_alloc(length + 1);
2191         if (length != 0) {
2192                 memcpy(strbuf, ptr, length);
2193         }
2194         strbuf[length] = '\0';
2195         return strbuf;
2196 }
2197
2198 /*
2199  * Given a tvbuff and an offset, with the offset assumed to refer to
2200  * a null-terminated string, find the length of that string (and throw
2201  * an exception if the tvbuff ends before we find the null), allocate
2202  * a buffer big enough to hold the string, copy the string into it,
2203  * and return a pointer to the string.  Also return the length of the
2204  * string (including the terminating null) through a pointer.
2205  */
2206 guint8 *
2207 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2208 {
2209         guint size;
2210         guint8 *strptr;
2211
2212         size = tvb_strsize(tvb, offset);
2213         strptr = g_malloc(size);
2214         tvb_memcpy(tvb, strptr, offset, size);
2215         *lengthp = size;
2216         return strptr;
2217 }
2218 /*
2219  * Given a tvbuff and an offset, with the offset assumed to refer to
2220  * a null-terminated string, find the length of that string (and throw
2221  * an exception if the tvbuff ends before we find the null), allocate
2222  * a buffer big enough to hold the string, copy the string into it,
2223  * and return a pointer to the string.  Also return the length of the
2224  * string (including the terminating null) through a pointer.
2225  *
2226  * This function allocates memory from a buffer with packet lifetime.
2227  * You do not have to free this buffer, it will be automatically freed
2228  * when wireshark starts decoding the next packet.
2229  * Do not use this function if you want the allocated memory to be persistent
2230  * after the current packet has been dissected.
2231  */
2232 guint8 *
2233 tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2234 {
2235         guint size;
2236         guint8 *strptr;
2237
2238         size = tvb_strsize(tvb, offset);
2239         strptr = ep_alloc(size);
2240         tvb_memcpy(tvb, strptr, offset, size);
2241         *lengthp = size;
2242         return strptr;
2243 }
2244
2245 /*
2246  * Given a tvbuff and an offset, with the offset assumed to refer to
2247  * a null-terminated string, find the length of that string (and throw
2248  * an exception if the tvbuff ends before we find the null), allocate
2249  * a buffer big enough to hold the string, copy the string into it,
2250  * and return a pointer to the string.  Also return the length of the
2251  * string (including the terminating null) through a pointer.
2252  *
2253  * This function allocates memory from a buffer with capture session lifetime.
2254  * You do not have to free this buffer, it will be automatically freed
2255  * when wireshark starts or opens a new capture.
2256  */
2257 guint8 *
2258 tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2259 {
2260         guint size;
2261         guint8 *strptr;
2262
2263         size = tvb_strsize(tvb, offset);
2264         strptr = se_alloc(size);
2265         tvb_memcpy(tvb, strptr, offset, size);
2266         *lengthp = size;
2267         return strptr;
2268 }
2269
2270 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2271  * no more than bufsize number of bytes, including terminating NUL, to buffer.
2272  * Returns length of string (not including terminating NUL), or -1 if the string was
2273  * truncated in the buffer due to not having reached the terminating NUL.
2274  * In this way, it acts like g_snprintf().
2275  *
2276  * bufsize MUST be greater than 0.
2277  *
2278  * When processing a packet where the remaining number of bytes is less
2279  * than bufsize, an exception is not thrown if the end of the packet
2280  * is reached before the NUL is found. If no NUL is found before reaching
2281  * the end of the short packet, -1 is still returned, and the string
2282  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2283  * at the correct spot, terminating the string.
2284  *
2285  * *bytes_copied will contain the number of bytes actually copied,
2286  * including the terminating-NUL.
2287  */
2288 static gint
2289 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
2290                 gint *bytes_copied)
2291 {
2292         gint    stringlen;
2293         guint   abs_offset, junk_length;
2294         gint    limit, len;
2295         gboolean decreased_max = FALSE;
2296
2297         check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2298
2299         /* There must at least be room for the terminating NUL. */
2300         DISSECTOR_ASSERT(bufsize != 0);
2301
2302         /* If there's no room for anything else, just return the NUL. */
2303         if (bufsize == 1) {
2304                 buffer[0] = 0;
2305                 *bytes_copied = 1;
2306                 return 0;
2307         }
2308
2309         /* Only read to end of tvbuff, w/o throwing exception. */
2310         len = tvb_length_remaining(tvb, abs_offset);
2311
2312         /* check_offset_length() won't throw an exception if we're
2313          * looking at the byte immediately after the end of the tvbuff. */
2314         if (len == 0) {
2315                 THROW(ReportedBoundsError);
2316         }
2317
2318         /* This should not happen because check_offset_length() would
2319          * have already thrown an exception if 'offset' were out-of-bounds.
2320          */
2321         DISSECTOR_ASSERT(len != -1);
2322
2323         /*
2324          * If we've been passed a negative number, bufsize will
2325          * be huge.
2326          */
2327         DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2328
2329         if ((guint)len < bufsize) {
2330                 limit = len;
2331                 decreased_max = TRUE;
2332         }
2333         else {
2334                 limit = bufsize;
2335         }
2336
2337         stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2338         /* If NUL wasn't found, copy the data and return -1 */
2339         if (stringlen == -1) {
2340                 tvb_memcpy(tvb, buffer, abs_offset, limit);
2341                 if (decreased_max) {
2342                         buffer[limit] = 0;
2343                         /* Add 1 for the extra NUL that we set at buffer[limit],
2344                          * pretending that it was copied as part of the string. */
2345                         *bytes_copied = limit + 1;
2346                 }
2347                 else {
2348                         *bytes_copied = limit;
2349                 }
2350                 return -1;
2351         }
2352
2353         /* Copy the string to buffer */
2354         tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2355         *bytes_copied = stringlen + 1;
2356         return stringlen;
2357 }
2358
2359 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2360  * no more than bufsize number of bytes, including terminating NUL, to buffer.
2361  * Returns length of string (not including terminating NUL), or -1 if the string was
2362  * truncated in the buffer due to not having reached the terminating NUL.
2363  * In this way, it acts like g_snprintf().
2364  *
2365  * When processing a packet where the remaining number of bytes is less
2366  * than bufsize, an exception is not thrown if the end of the packet
2367  * is reached before the NUL is found. If no NUL is found before reaching
2368  * the end of the short packet, -1 is still returned, and the string
2369  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2370  * at the correct spot, terminating the string.
2371  */
2372 gint
2373 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2374 {
2375         gint bytes_copied;
2376
2377         return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2378 }
2379
2380 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2381  * have a terminating NUL. If the string was truncated when copied into buffer,
2382  * a NUL is placed at the end of buffer to terminate it.
2383  */
2384 gint
2385 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2386 {
2387         gint    len, bytes_copied;
2388
2389         len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2390
2391         if (len == -1) {
2392                 buffer[bufsize - 1] = 0;
2393                 return bytes_copied - 1;
2394         }
2395         else {
2396                 return len;
2397         }
2398 }
2399
2400 /*
2401  * Given a tvbuff, an offset into the tvbuff, and a length that starts
2402  * at that offset (which may be -1 for "all the way to the end of the
2403  * tvbuff"), find the end of the (putative) line that starts at the
2404  * specified offset in the tvbuff, going no further than the specified
2405  * length.
2406  *
2407  * Return the length of the line (not counting the line terminator at
2408  * the end), or, if we don't find a line terminator:
2409  *
2410  *      if "deseg" is true, return -1;
2411  *
2412  *      if "deseg" is false, return the amount of data remaining in
2413  *      the buffer.
2414  *
2415  * Set "*next_offset" to the offset of the character past the line
2416  * terminator, or past the end of the buffer if we don't find a line
2417  * terminator.  (It's not set if we return -1.)
2418  */
2419 gint
2420 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
2421     gboolean desegment)
2422 {
2423         gint eob_offset;
2424         gint eol_offset;
2425         int linelen;
2426
2427         if (len == -1)
2428                 len = tvb_length_remaining(tvb, offset);
2429         /*
2430          * XXX - what if "len" is still -1, meaning "offset is past the
2431          * end of the tvbuff"?
2432          */
2433         eob_offset = offset + len;
2434
2435         /*
2436          * Look either for a CR or an LF.
2437          */
2438         eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n");
2439         if (eol_offset == -1) {
2440                 /*
2441                  * No CR or LF - line is presumably continued in next packet.
2442                  */
2443                 if (desegment) {
2444                         /*
2445                          * Tell our caller we saw no EOL, so they can
2446                          * try to desegment and get the entire line
2447                          * into one tvbuff.
2448                          */
2449                         return -1;
2450                 } else {
2451                         /*
2452                          * Pretend the line runs to the end of the tvbuff.
2453                          */
2454                         linelen = eob_offset - offset;
2455                         *next_offset = eob_offset;
2456                 }
2457         } else {
2458                 /*
2459                  * Find the number of bytes between the starting offset
2460                  * and the CR or LF.
2461                  */
2462                 linelen = eol_offset - offset;
2463
2464                 /*
2465                  * Is it a CR?
2466                  */
2467                 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2468                         /*
2469                          * Yes - is it followed by an LF?
2470                          */
2471                         if (eol_offset + 1 >= eob_offset) {
2472                                 /*
2473                                  * Dunno - the next byte isn't in this
2474                                  * tvbuff.
2475                                  */
2476                                 if (desegment) {
2477                                         /*
2478                                          * We'll return -1, although that
2479                                          * runs the risk that if the line
2480                                          * really *is* terminated with a CR,
2481                                          * we won't properly dissect this
2482                                          * tvbuff.
2483                                          *
2484                                          * It's probably more likely that
2485                                          * the line ends with CR-LF than
2486                                          * that it ends with CR by itself.
2487                                          */
2488                                         return -1;
2489                                 }
2490                         } else {
2491                                 /*
2492                                  * Well, we can at least look at the next
2493                                  * byte.
2494                                  */
2495                                 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2496                                         /*
2497                                          * It's an LF; skip over the CR.
2498                                          */
2499                                         eol_offset++;
2500                                 }
2501                         }
2502                 }
2503
2504                 /*
2505                  * Return the offset of the character after the last
2506                  * character in the line, skipping over the last character
2507                  * in the line terminator.
2508                  */
2509                 *next_offset = eol_offset + 1;
2510         }
2511         return linelen;
2512 }
2513
2514 /*
2515  * Given a tvbuff, an offset into the tvbuff, and a length that starts
2516  * at that offset (which may be -1 for "all the way to the end of the
2517  * tvbuff"), find the end of the (putative) line that starts at the
2518  * specified offset in the tvbuff, going no further than the specified
2519  * length.
2520  *
2521  * However, treat quoted strings inside the buffer specially - don't
2522  * treat newlines in quoted strings as line terminators.
2523  *
2524  * Return the length of the line (not counting the line terminator at
2525  * the end), or the amount of data remaining in the buffer if we don't
2526  * find a line terminator.
2527  *
2528  * Set "*next_offset" to the offset of the character past the line
2529  * terminator, or past the end of the buffer if we don't find a line
2530  * terminator.
2531  */
2532 gint
2533 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2534     gint *next_offset)
2535 {
2536         gint cur_offset, char_offset;
2537         gboolean is_quoted;
2538         guchar c;
2539         gint eob_offset;
2540         int linelen;
2541
2542         if (len == -1)
2543                 len = tvb_length_remaining(tvb, offset);
2544         /*
2545          * XXX - what if "len" is still -1, meaning "offset is past the
2546          * end of the tvbuff"?
2547          */
2548         eob_offset = offset + len;
2549
2550         cur_offset = offset;
2551         is_quoted = FALSE;
2552         for (;;) {
2553                 /*
2554                  * Is this part of the string quoted?
2555                  */
2556                 if (is_quoted) {
2557                         /*
2558                          * Yes - look only for the terminating quote.
2559                          */
2560                         char_offset = tvb_find_guint8(tvb, cur_offset, len,
2561                             '"');
2562                 } else {
2563                         /*
2564                          * Look either for a CR, an LF, or a '"'.
2565                          */
2566                         char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2567                             (const guint8 *)"\r\n\"");
2568                 }
2569                 if (char_offset == -1) {
2570                         /*
2571                          * Not found - line is presumably continued in
2572                          * next packet.
2573                          * We pretend the line runs to the end of the tvbuff.
2574                          */
2575                         linelen = eob_offset - offset;
2576                         *next_offset = eob_offset;
2577                         break;
2578                 }
2579
2580                 if (is_quoted) {
2581                         /*
2582                          * We're processing a quoted string.
2583                          * We only looked for ", so we know it's a ";
2584                          * as we're processing a quoted string, it's a
2585                          * closing quote.
2586                          */
2587                         is_quoted = FALSE;
2588                 } else {
2589                         /*
2590                          * OK, what is it?
2591                          */
2592                         c = tvb_get_guint8(tvb, char_offset);
2593                         if (c == '"') {
2594                                 /*
2595                                  * Un-quoted "; it begins a quoted
2596                                  * string.
2597                                  */
2598                                 is_quoted = TRUE;
2599                         } else {
2600                                 /*
2601                                  * It's a CR or LF; we've found a line
2602                                  * terminator.
2603                                  *
2604                                  * Find the number of bytes between the
2605                                  * starting offset and the CR or LF.
2606                                  */
2607                                 linelen = char_offset - offset;
2608
2609                                 /*
2610                                  * Is it a CR?
2611                                  */
2612                                 if (c == '\r') {
2613                                         /*
2614                                          * Yes; is it followed by an LF?
2615                                          */
2616                                         if (char_offset + 1 < eob_offset &&
2617                                             tvb_get_guint8(tvb, char_offset + 1)
2618                                               == '\n') {
2619                                                 /*
2620                                                  * Yes; skip over the CR.
2621                                                  */
2622                                                 char_offset++;
2623                                         }
2624                                 }
2625
2626                                 /*
2627                                  * Return the offset of the character after
2628                                  * the last character in the line, skipping
2629                                  * over the last character in the line
2630                                  * terminator, and quit.
2631                                  */
2632                                 *next_offset = char_offset + 1;
2633                                 break;
2634                         }
2635                 }
2636
2637                 /*
2638                  * Step past the character we found.
2639                  */
2640                 cur_offset = char_offset + 1;
2641                 if (cur_offset >= eob_offset) {
2642                         /*
2643                          * The character we found was the last character
2644                          * in the tvbuff - line is presumably continued in
2645                          * next packet.
2646                          * We pretend the line runs to the end of the tvbuff.
2647                          */
2648                         linelen = eob_offset - offset;
2649                         *next_offset = eob_offset;
2650                         break;
2651                 }
2652         }
2653         return linelen;
2654 }
2655
2656 /*
2657  * Copied from the mgcp dissector. (This function should be moved to /epan )
2658  * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
2659  *                character following offset or offset + maxlength -1 whichever
2660  *                is smaller.
2661  *
2662  * Parameters:
2663  * tvb - The tvbuff in which we are skipping whitespace.
2664  * offset - The offset in tvb from which we begin trying to skip whitespace.
2665  * maxlength - The maximum distance from offset that we may try to skip
2666  * whitespace.
2667  *
2668  * Returns: The position in tvb of the first non-whitespace
2669  *          character following offset or offset + maxlength -1 whichever
2670  *          is smaller.
2671  */
2672 gint tvb_skip_wsp(tvbuff_t* tvb, gint offset, gint maxlength)
2673 {
2674         gint counter = offset;
2675         gint end = offset + maxlength,tvb_len;
2676         guint8 tempchar;
2677
2678         /* Get the length remaining */
2679         tvb_len = tvb_length(tvb);
2680         end = offset + maxlength;
2681         if (end >= tvb_len)
2682         {
2683                 end = tvb_len;
2684         }
2685
2686         /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
2687         for (counter = offset;
2688              counter < end &&
2689               ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2690               tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
2691              counter++);
2692
2693         return (counter);
2694 }
2695
2696 gint tvb_skip_wsp_return(tvbuff_t* tvb, gint offset){
2697         gint counter = offset;
2698         gint end;
2699         guint8 tempchar;
2700         end = 0;
2701
2702         for(counter = offset; counter > end &&
2703                 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2704                 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
2705         counter++;
2706         return (counter);
2707 }
2708
2709
2710 /*
2711  * Format a bunch of data from a tvbuff as bytes, returning a pointer
2712  * to the string with the formatted data, with "punct" as a byte
2713  * separator.
2714  */
2715 gchar *
2716 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2717 {
2718         return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2719 }
2720
2721 /*
2722  * Format a bunch of data from a tvbuff as bytes, returning a pointer
2723  * to the string with the formatted data.
2724  */
2725 gchar *
2726 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2727 {
2728         return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2729 }
2730
2731 /* Find a needle tvbuff within a haystack tvbuff. */
2732 gint
2733 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2734 {
2735         guint           haystack_abs_offset, haystack_abs_length;
2736         const guint8    *haystack_data;
2737         const guint8    *needle_data;
2738         const guint     needle_len = needle_tvb->length;
2739         const guint8    *location;
2740
2741         if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2742                 return -1;
2743         }
2744
2745         /* Get pointers to the tvbuffs' data. */
2746         haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2747         needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2748
2749         check_offset_length(haystack_tvb, haystack_offset, -1,
2750                         &haystack_abs_offset, &haystack_abs_length);
2751
2752         location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2753                         needle_data, needle_len);
2754
2755         if (location) {
2756                 return (gint) (location - haystack_data);
2757         }
2758         else {
2759                 return -1;
2760         }
2761
2762         return -1;
2763 }
2764
2765 #ifdef HAVE_LIBZ
2766 /*
2767  * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2768  * length comprlen.  Returns an uncompressed tvbuffer if uncompression
2769  * succeeded or NULL if uncompression failed.
2770  */
2771 #define TVB_Z_MIN_BUFSIZ 32768
2772 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2773 /* #define TVB_Z_DEBUG 1 */
2774 #undef TVB_Z_DEBUG
2775
2776 tvbuff_t *
2777 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2778 {
2779
2780
2781         gint err = Z_OK;
2782         guint bytes_out = 0;
2783         guint8 *compr = NULL;
2784         guint8 *uncompr = NULL;
2785         tvbuff_t *uncompr_tvb = NULL;
2786         z_streamp strm = NULL;
2787         Bytef *strmbuf = NULL;
2788         guint inits_done = 0;
2789         gint wbits = MAX_WBITS;
2790         guint8 *next = NULL;
2791         guint bufsiz = TVB_Z_MIN_BUFSIZ;
2792 #ifdef TVB_Z_DEBUG
2793         guint inflate_passes = 0;
2794         guint bytes_in = tvb_length_remaining(tvb, offset);
2795 #endif
2796
2797         if (tvb == NULL) {
2798                 return NULL;
2799         }
2800
2801         strm = g_malloc0(sizeof(z_stream));
2802
2803         if (strm == NULL) {
2804                 return NULL;
2805         }
2806
2807         compr = tvb_memdup(tvb, offset, comprlen);
2808
2809         if (!compr) {
2810                 g_free(strm);
2811                 return NULL;
2812         }
2813
2814         /*
2815          * Assume that the uncompressed data is at least twice as big as
2816          * the compressed size.
2817          */
2818         bufsiz = tvb_length_remaining(tvb, offset) * 2;
2819
2820         if (bufsiz < TVB_Z_MIN_BUFSIZ) {
2821                 bufsiz = TVB_Z_MIN_BUFSIZ;
2822         } else if (bufsiz > TVB_Z_MAX_BUFSIZ) {
2823                 bufsiz = TVB_Z_MIN_BUFSIZ;
2824         }
2825
2826 #ifdef TVB_Z_DEBUG
2827         printf("bufsiz: %u bytes\n", bufsiz);
2828 #endif
2829
2830         next = compr;
2831
2832         strm->next_in = next;
2833         strm->avail_in = comprlen;
2834
2835
2836         strmbuf = g_malloc0(bufsiz);
2837
2838         if(strmbuf == NULL) {
2839                 g_free(compr);
2840                 g_free(strm);
2841                 return NULL;
2842         }
2843
2844         strm->next_out = strmbuf;
2845         strm->avail_out = bufsiz;
2846
2847         err = inflateInit2(strm, wbits);
2848         inits_done = 1;
2849         if (err != Z_OK) {
2850                 inflateEnd(strm);
2851                 g_free(strm);
2852                 g_free(compr);
2853                 g_free(strmbuf);
2854                 return NULL;
2855         }
2856
2857         while (1) {
2858                 memset(strmbuf, '\0', bufsiz);
2859                 strm->next_out = strmbuf;
2860                 strm->avail_out = bufsiz;
2861
2862                 err = inflate(strm, Z_SYNC_FLUSH);
2863
2864                 if (err == Z_OK || err == Z_STREAM_END) {
2865                         guint bytes_pass = bufsiz - strm->avail_out;
2866
2867 #ifdef TVB_Z_DEBUG
2868                         ++inflate_passes;
2869 #endif
2870
2871                         if (uncompr == NULL) {
2872                                 uncompr = g_memdup(strmbuf, bytes_pass);
2873                         } else {
2874                                 guint8 *new_data = g_malloc0(bytes_out +
2875                                     bytes_pass);
2876
2877                                 if (new_data == NULL) {
2878                                         inflateEnd(strm);
2879                                         g_free(strm);
2880                                         g_free(strmbuf);
2881                                         g_free(compr);
2882
2883                                         if (uncompr != NULL) {
2884                                                 g_free(uncompr);
2885                                         }
2886
2887                                         return NULL;
2888                                 }
2889
2890                                 g_memmove(new_data, uncompr, bytes_out);
2891                                 g_memmove((new_data + bytes_out), strmbuf,
2892                                     bytes_pass);
2893
2894                                 g_free(uncompr);
2895                                 uncompr = new_data;
2896                         }
2897
2898                         bytes_out += bytes_pass;
2899
2900                         if ( err == Z_STREAM_END) {
2901                                 inflateEnd(strm);
2902                                 g_free(strm);
2903                                 g_free(strmbuf);
2904                                 break;
2905                         }
2906                 } else if (err == Z_BUF_ERROR) {
2907                         /*
2908                          * It's possible that not enough frames were captured
2909                          * to decompress this fully, so return what we've done
2910                          * so far, if any.
2911                          */
2912                         inflateEnd(strm);
2913                         g_free(strm);
2914                         g_free(strmbuf);
2915
2916                         if (uncompr != NULL) {
2917                                 break;
2918                         } else {
2919                                 g_free(compr);
2920                                 return NULL;
2921                         }
2922
2923                 } else if (err == Z_DATA_ERROR && inits_done == 1
2924                     && uncompr == NULL && (*compr  == 0x1f) &&
2925                     (*(compr + 1) == 0x8b)) {
2926                         /*
2927                          * inflate() is supposed to handle both gzip and deflate
2928                          * streams automatically, but in reality it doesn't
2929                          * seem to handle either (at least not within the
2930                          * context of an HTTP response.)  We have to try
2931                          * several tweaks, depending on the type of data and
2932                          * version of the library installed.
2933                          */
2934
2935                         /*
2936                          * Gzip file format.  Skip past the header, since the
2937                          * fix to make it work (setting windowBits to 31)
2938                          * doesn't work with all versions of the library.
2939                          */
2940                         Bytef *c = compr + 2;
2941                         Bytef flags = 0;
2942
2943                         if (*c == Z_DEFLATED) {
2944                                 c++;
2945                         } else {
2946                                 inflateEnd(strm);
2947                                 g_free(strm);
2948                                 g_free(compr);
2949                                 g_free(strmbuf);
2950                                 return NULL;
2951                         }
2952
2953                         flags = *c;
2954
2955                         /* Skip past the MTIME, XFL, and OS fields. */
2956                         c += 7;
2957
2958                         if (flags & (1 << 2)) {
2959                                 /* An Extra field is present. */
2960                                 gint xsize = (gint)(*c |
2961                                     (*(c + 1) << 8));
2962
2963                                 c += xsize;
2964                         }
2965
2966                         if (flags & (1 << 3)) {
2967                                 /* A null terminated filename */
2968
2969                                 while ((c - compr) < comprlen && *c != '\0') {
2970                                         c++;
2971                                 }
2972
2973                                 c++;
2974                         }
2975
2976                         if (flags & (1 << 4)) {
2977                                 /* A null terminated comment */
2978
2979                                 while ((c - compr) < comprlen && *c != '\0') {
2980                                         c++;
2981                                 }
2982
2983                                 c++;
2984                         }
2985
2986
2987                         inflateReset(strm);
2988                         next = c;
2989                         strm->next_in = next;
2990                         if (c - compr > comprlen) {
2991                                 inflateEnd(strm);
2992                                 g_free(strm);
2993                                 g_free(compr);
2994                                 g_free(strmbuf);
2995                                 return NULL;
2996                         }
2997                         comprlen -= (int) (c - compr);
2998
2999                         inflateEnd(strm);
3000                         err = inflateInit2(strm, wbits);
3001                         inits_done++;
3002                 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
3003                     inits_done <= 3) {
3004
3005                         /*
3006                          * Re-init the stream with a negative
3007                          * MAX_WBITS. This is necessary due to
3008                          * some servers (Apache) not sending
3009                          * the deflate header with the
3010                          * content-encoded response.
3011                          */
3012                         wbits = -MAX_WBITS;
3013
3014                         inflateReset(strm);
3015
3016                         strm->next_in = next;
3017                         strm->avail_in = comprlen;
3018
3019                         inflateEnd(strm);
3020                         memset(strmbuf, '\0', bufsiz);
3021                         strm->next_out = strmbuf;
3022                         strm->avail_out = bufsiz;
3023
3024                         err = inflateInit2(strm, wbits);
3025
3026                         inits_done++;
3027
3028                         if (err != Z_OK) {
3029                                 g_free(strm);
3030                                 g_free(strmbuf);
3031                                 g_free(compr);
3032                                 g_free(uncompr);
3033
3034                                 return NULL;
3035                         }
3036                 } else {
3037                         inflateEnd(strm);
3038                         g_free(strm);
3039                         g_free(strmbuf);
3040                         g_free(compr);
3041
3042                         if (uncompr == NULL) {
3043                                 return NULL;
3044                         }
3045
3046                         break;
3047                 }
3048         }
3049
3050 #ifdef TVB_Z_DEBUG
3051         printf("inflate() total passes: %u\n", inflate_passes);
3052         printf("bytes  in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
3053 #endif
3054
3055         if (uncompr != NULL) {
3056                 uncompr_tvb =  tvb_new_real_data((guint8*) uncompr, bytes_out,
3057                     bytes_out);
3058                 tvb_set_free_cb(uncompr_tvb, g_free);
3059         }
3060         g_free(compr);
3061         return uncompr_tvb;
3062 }
3063 #else
3064 tvbuff_t *
3065 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)
3066 {
3067         return NULL;
3068 }
3069 #endif
3070
3071 tvbuff_t* tvb_child_uncompress(tvbuff_t *parent _U_, tvbuff_t *tvb, int offset, int comprlen)
3072 {
3073         tvbuff_t *new_tvb = tvb_uncompress(tvb, offset, comprlen);
3074         if (new_tvb)
3075                 tvb_set_child_real_data_tvbuff (parent, new_tvb);
3076         return new_tvb;
3077 }
3078
3079