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