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