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