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