Add generic tvb_get_bits_buf() which accepts any no_of_bits.
[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         DISSECTOR_ASSERT(tvb->reported_length == 0);
608
609         composite = &tvb->tvbuffs.composite;
610         num_members = g_slist_length(composite->tvbs);
611
612         composite->start_offsets = g_new(guint, num_members);
613         composite->end_offsets = g_new(guint, num_members);
614
615         for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
616                 DISSECTOR_ASSERT((guint) i < num_members);
617                 member_tvb = slist->data;
618                 composite->start_offsets[i] = tvb->length;
619                 tvb->length += member_tvb->length;
620                 tvb->reported_length += member_tvb->reported_length;
621                 composite->end_offsets[i] = tvb->length - 1;
622                 i++;
623         }
624
625         tvb->initialized = TRUE;
626 }
627
628
629
630 guint
631 tvb_length(const tvbuff_t* tvb)
632 {
633         DISSECTOR_ASSERT(tvb && tvb->initialized);
634
635         return tvb->length;
636 }
637
638 gint
639 tvb_length_remaining(const tvbuff_t *tvb, const gint offset)
640 {
641         guint   abs_offset, abs_length;
642
643         DISSECTOR_ASSERT(tvb && tvb->initialized);
644
645         if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
646                 return abs_length;
647         }
648         else {
649                 return -1;
650         }
651 }
652
653 guint
654 tvb_ensure_length_remaining(const tvbuff_t *tvb, const gint offset)
655 {
656         guint   abs_offset, abs_length;
657         int     exception;
658
659         DISSECTOR_ASSERT(tvb && tvb->initialized);
660
661         if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, &exception)) {
662                 THROW(exception);
663         }
664         if (abs_length == 0) {
665                 /*
666                  * This routine ensures there's at least one byte available.
667                  * There aren't any bytes available, so throw the appropriate
668                  * exception.
669                  */
670                 if (abs_offset >= tvb->reported_length)
671                         THROW(ReportedBoundsError);
672                 else
673                         THROW(BoundsError);
674         }
675         return abs_length;
676 }
677
678
679
680
681 /* Validates that 'length' bytes are available starting from
682  * offset (pos/neg). Does not throw an exception. */
683 gboolean
684 tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
685 {
686         guint           abs_offset, abs_length;
687
688         DISSECTOR_ASSERT(tvb && tvb->initialized);
689
690         if (!compute_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length, NULL))
691                 return FALSE;
692
693         if (abs_offset + abs_length <= tvb->length) {
694                 return TRUE;
695         }
696         else {
697                 return FALSE;
698         }
699 }
700
701 /* Validates that 'length' bytes are available starting from
702  * offset (pos/neg). Throws an exception if they aren't. */
703 void
704 tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
705 {
706         guint           abs_offset, abs_length;
707
708         DISSECTOR_ASSERT(tvb && tvb->initialized);
709
710         /*
711          * -1 doesn't mean "until end of buffer", as that's pointless
712          * for this routine.  We must treat it as a Really Large Positive
713          * Number, so that we throw an exception; we throw
714          * ReportedBoundsError, as if it were past even the end of a
715          * reassembled packet, and past the end of even the data we
716          * didn't capture.
717          *
718          * We do the same with other negative lengths.
719          */
720         if (length < 0) {
721                 THROW(ReportedBoundsError);
722         }
723         check_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length);
724 }
725
726 gboolean
727 tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
728 {
729         guint           abs_offset, abs_length;
730
731         DISSECTOR_ASSERT(tvb && tvb->initialized);
732         if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL))
733                 return FALSE;
734
735         if (abs_offset < tvb->length) {
736                 return TRUE;
737         }
738         else {
739                 return FALSE;
740         }
741 }
742
743 guint
744 tvb_reported_length(const tvbuff_t* tvb)
745 {
746         DISSECTOR_ASSERT(tvb && tvb->initialized);
747
748         return tvb->reported_length;
749 }
750
751 gint
752 tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset)
753 {
754         guint   abs_offset, abs_length;
755
756         DISSECTOR_ASSERT(tvb && tvb->initialized);
757
758         if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
759                 if (tvb->reported_length >= abs_offset)
760                         return tvb->reported_length - abs_offset;
761                 else
762                         return -1;
763         }
764         else {
765                 return -1;
766         }
767 }
768
769 /* Set the reported length of a tvbuff to a given value; used for protocols
770    whose headers contain an explicit length and where the calling
771    dissector's payload may include padding as well as the packet for
772    this protocol.
773
774    Also adjusts the data length. */
775 void
776 tvb_set_reported_length(tvbuff_t* tvb, const guint reported_length)
777 {
778         DISSECTOR_ASSERT(tvb && tvb->initialized);
779
780         if (reported_length > tvb->reported_length)
781                 THROW(ReportedBoundsError);
782
783         tvb->reported_length = reported_length;
784         if (reported_length < tvb->length)
785                 tvb->length = reported_length;
786 }
787
788
789 #if 0
790 static const guint8*
791 first_real_data_ptr(tvbuff_t *tvb)
792 {
793         tvbuff_t        *member;
794
795         switch(tvb->type) {
796                 case TVBUFF_REAL_DATA:
797                         return tvb->real_data;
798                 case TVBUFF_SUBSET:
799                         member = tvb->tvbuffs.subset.tvb;
800                         return first_real_data_ptr(member);
801                 case TVBUFF_COMPOSITE:
802                         member = tvb->tvbuffs.composite.tvbs->data;
803                         return first_real_data_ptr(member);
804         }
805
806         DISSECTOR_ASSERT_NOT_REACHED();
807         return NULL;
808 }
809 #endif
810
811 static guint
812 offset_from_real_beginning(const tvbuff_t *tvb, const guint counter)
813 {
814         tvbuff_t        *member;
815
816         switch(tvb->type) {
817                 case TVBUFF_REAL_DATA:
818                         return counter;
819                 case TVBUFF_SUBSET:
820                         member = tvb->tvbuffs.subset.tvb;
821                         return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
822                 case TVBUFF_COMPOSITE:
823                         member = tvb->tvbuffs.composite.tvbs->data;
824                         return offset_from_real_beginning(member, counter);
825         }
826
827         DISSECTOR_ASSERT_NOT_REACHED();
828         return 0;
829 }
830
831 guint
832 tvb_offset_from_real_beginning(const tvbuff_t *tvb)
833 {
834         return offset_from_real_beginning(tvb, 0);
835 }
836
837 static const guint8*
838 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset,
839                 const guint abs_length)
840 {
841         guint           i, num_members;
842         tvb_comp_t      *composite;
843         tvbuff_t        *member_tvb = NULL;
844         guint           member_offset, member_length;
845         GSList          *slist;
846
847         DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
848
849         /* Maybe the range specified by offset/length
850          * is contiguous inside one of the member tvbuffs */
851         composite = &tvb->tvbuffs.composite;
852         num_members = g_slist_length(composite->tvbs);
853
854         for (i = 0; i < num_members; i++) {
855                 if (abs_offset <= composite->end_offsets[i]) {
856                         slist = g_slist_nth(composite->tvbs, i);
857                         member_tvb = slist->data;
858                         break;
859                 }
860         }
861         DISSECTOR_ASSERT(member_tvb);
862
863         if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
864                                 abs_length, &member_offset, &member_length, NULL)) {
865
866                 /*
867                  * The range is, in fact, contiguous within member_tvb.
868                  */
869                 DISSECTOR_ASSERT(!tvb->real_data);
870                 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
871         }
872         else {
873                 tvb->real_data = tvb_memdup(tvb, 0, -1);
874                 return tvb->real_data + abs_offset;
875         }
876
877         DISSECTOR_ASSERT_NOT_REACHED();
878 }
879
880 static const guint8*
881 ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length,
882                 int *exception)
883 {
884         guint   abs_offset, abs_length;
885
886         if (!check_offset_length_no_exception(tvb->length, tvb->reported_length, offset, length,
887                 &abs_offset, &abs_length, exception)) {
888                 return NULL;
889         }
890
891         /*
892          * We know that all the data is present in the tvbuff, so
893          * no exceptions should be thrown.
894          */
895         if (tvb->real_data) {
896                 return tvb->real_data + abs_offset;
897         }
898         else {
899                 switch(tvb->type) {
900                         case TVBUFF_REAL_DATA:
901                                 DISSECTOR_ASSERT_NOT_REACHED();
902                         case TVBUFF_SUBSET:
903                                 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
904                                                 abs_offset - tvb->tvbuffs.subset.offset,
905                                                 abs_length, NULL);
906                         case TVBUFF_COMPOSITE:
907                                 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
908                 }
909         }
910
911         DISSECTOR_ASSERT_NOT_REACHED();
912         return NULL;
913 }
914
915 static const guint8*
916 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length)
917 {
918         int exception;
919         const guint8 *p;
920
921         p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
922         if (p == NULL) {
923                 DISSECTOR_ASSERT(exception > 0);
924                 THROW(exception);
925         }
926         return p;
927 }
928
929 static const guint8*
930 fast_ensure_contiguous(tvbuff_t *tvb, const gint offset, const guint length)
931 {
932         guint   end_offset;
933         guint   u_offset;
934
935         DISSECTOR_ASSERT(tvb && tvb->initialized);
936         /* We don't check for overflow in this fast path so we only handle simple types */
937         DISSECTOR_ASSERT(length <= 8);
938
939         if (offset < 0 || !tvb->real_data) {
940                 return ensure_contiguous(tvb, offset, length);
941         }
942
943         u_offset = offset;
944         end_offset = u_offset + length;
945
946         if (end_offset <= tvb->length) {
947                 return tvb->real_data + u_offset;
948         }
949
950         if (end_offset > tvb->reported_length) {
951                 THROW(ReportedBoundsError);
952         }
953         THROW(BoundsError);
954         /* not reached */
955         return NULL;
956 }
957
958 static const guint8*
959 guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles, guchar *found_needle)
960 {
961         gchar tmp[256] = { 0 };
962         const guint8 *haystack_end;
963
964         while (*needles)
965                 tmp[*needles++] = 1;
966
967         haystack_end = haystack + haystacklen;
968         while (haystack < haystack_end) {
969                 if (tmp[*haystack]) {
970                         if(found_needle)
971                                 *found_needle = *haystack;
972                         return haystack;
973                 }
974                 haystack++;
975         }
976
977         return NULL;
978 }
979
980
981
982 /************** ACCESSORS **************/
983
984 static void*
985 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_length)
986 {
987         guint           i, num_members;
988         tvb_comp_t      *composite;
989         tvbuff_t        *member_tvb = NULL;
990         guint           member_offset, member_length;
991         gboolean        retval;
992         GSList          *slist;
993
994         DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
995
996         /* Maybe the range specified by offset/length
997          * is contiguous inside one of the member tvbuffs */
998         composite = &tvb->tvbuffs.composite;
999         num_members = g_slist_length(composite->tvbs);
1000
1001         for (i = 0; i < num_members; i++) {
1002                 if (abs_offset <= composite->end_offsets[i]) {
1003                         slist = g_slist_nth(composite->tvbs, i);
1004                         member_tvb = slist->data;
1005                         break;
1006                 }
1007         }
1008         DISSECTOR_ASSERT(member_tvb);
1009
1010         if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
1011                                 (gint) abs_length, &member_offset, &member_length, NULL)) {
1012
1013                 DISSECTOR_ASSERT(!tvb->real_data);
1014                 return tvb_memcpy(member_tvb, target, member_offset, member_length);
1015         }
1016         else {
1017                 /* The requested data is non-contiguous inside
1018                  * the member tvb. We have to memcpy() the part that's in the member tvb,
1019                  * then iterate across the other member tvb's, copying their portions
1020                  * until we have copied all data.
1021                  */
1022                 retval = compute_offset_length(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i], -1,
1023                                 &member_offset, &member_length, NULL);
1024                 DISSECTOR_ASSERT(retval);
1025
1026                 tvb_memcpy(member_tvb, target, member_offset, member_length);
1027                 abs_offset      += member_length;
1028                 abs_length      -= member_length;
1029
1030                 /* Recurse */
1031                 if (abs_length > 0) {
1032                         composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
1033                 }
1034
1035                 return target;
1036         }
1037
1038         DISSECTOR_ASSERT_NOT_REACHED();
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_ntoh40(tvbuff_t *tvb, const gint offset)
1185 {
1186         const guint8* ptr;
1187
1188         ptr = fast_ensure_contiguous(tvb, offset, 5);
1189         return pntoh40(ptr);
1190 }
1191
1192 guint64
1193 tvb_get_ntoh48(tvbuff_t *tvb, const gint offset)
1194 {
1195         const guint8* ptr;
1196
1197         ptr = fast_ensure_contiguous(tvb, offset, 6);
1198         return pntoh48(ptr);
1199 }
1200
1201 guint64
1202 tvb_get_ntoh56(tvbuff_t *tvb, const gint offset)
1203 {
1204         const guint8* ptr;
1205
1206         ptr = fast_ensure_contiguous(tvb, offset, 7);
1207         return pntoh56(ptr);
1208 }
1209
1210 guint64
1211 tvb_get_ntoh64(tvbuff_t *tvb, const gint offset)
1212 {
1213         const guint8* ptr;
1214
1215         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1216         return pntoh64(ptr);
1217 }
1218
1219 /*
1220  * Stuff for IEEE float handling on platforms that don't have IEEE
1221  * format as the native floating-point format.
1222  *
1223  * For now, we treat only the VAX as such a platform.
1224  *
1225  * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1226  * and possibly other machines.
1227  *
1228  * It appears that the official Linux port to System/390 and
1229  * zArchitecture uses IEEE format floating point (not a
1230  * huge surprise).
1231  *
1232  * I don't know whether there are any other machines that
1233  * could run Wireshark and that don't use IEEE format.
1234  * As far as I know, all of the main commercial microprocessor
1235  * families on which OSes that support Wireshark can run
1236  * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1237  * IA-64, and so on).
1238  */
1239
1240 #if defined(vax)
1241
1242 #include <math.h>
1243
1244 /*
1245  * Single-precision.
1246  */
1247 #define IEEE_SP_NUMBER_WIDTH    32      /* bits in number */
1248 #define IEEE_SP_EXP_WIDTH       8       /* bits in exponent */
1249 #define IEEE_SP_MANTISSA_WIDTH  23      /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1250
1251 #define IEEE_SP_SIGN_MASK       0x80000000
1252 #define IEEE_SP_EXPONENT_MASK   0x7F800000
1253 #define IEEE_SP_MANTISSA_MASK   0x007FFFFF
1254 #define IEEE_SP_INFINITY        IEEE_SP_EXPONENT_MASK
1255
1256 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1257 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1258 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1259
1260 static int
1261 ieee_float_is_zero(const guint32 w)
1262 {
1263         return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1264 }
1265
1266 static gfloat
1267 get_ieee_float(const guint32 w)
1268 {
1269         long sign;
1270         long exponent;
1271         long mantissa;
1272
1273         sign = w & IEEE_SP_SIGN_MASK;
1274         exponent = w & IEEE_SP_EXPONENT_MASK;
1275         mantissa = w & IEEE_SP_MANTISSA_MASK;
1276
1277         if (ieee_float_is_zero(w)) {
1278                 /* number is zero, unnormalized, or not-a-number */
1279                 return 0.0;
1280         }
1281 #if 0
1282         /*
1283          * XXX - how to handle this?
1284          */
1285         if (IEEE_SP_INFINITY == exponent) {
1286                 /*
1287                  * number is positive or negative infinity, or a special value
1288                  */
1289                 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1290         }
1291 #endif
1292
1293         exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1294                 IEEE_SP_MANTISSA_WIDTH;
1295         mantissa |= IEEE_SP_IMPLIED_BIT;
1296
1297         if (sign)
1298                 return -mantissa * pow(2, exponent);
1299         else
1300                 return mantissa * pow(2, exponent);
1301 }
1302
1303 /*
1304  * Double-precision.
1305  * We assume that if you don't have IEEE floating-point, you have a
1306  * compiler that understands 64-bit integral quantities.
1307  */
1308 #define IEEE_DP_NUMBER_WIDTH    64      /* bits in number */
1309 #define IEEE_DP_EXP_WIDTH       11      /* bits in exponent */
1310 #define IEEE_DP_MANTISSA_WIDTH  52      /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1311
1312 #define IEEE_DP_SIGN_MASK       0x8000000000000000LL
1313 #define IEEE_DP_EXPONENT_MASK   0x7FF0000000000000LL
1314 #define IEEE_DP_MANTISSA_MASK   0x000FFFFFFFFFFFFFLL
1315 #define IEEE_DP_INFINITY        IEEE_DP_EXPONENT_MASK
1316
1317 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1318 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1319 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1320
1321 static int
1322 ieee_double_is_zero(const guint64 w)
1323 {
1324         return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1325 }
1326
1327 static gdouble
1328 get_ieee_double(const guint64 w)
1329 {
1330         gint64 sign;
1331         gint64 exponent;
1332         gint64 mantissa;
1333
1334         sign = w & IEEE_DP_SIGN_MASK;
1335         exponent = w & IEEE_DP_EXPONENT_MASK;
1336         mantissa = w & IEEE_DP_MANTISSA_MASK;
1337
1338         if (ieee_double_is_zero(w)) {
1339                 /* number is zero, unnormalized, or not-a-number */
1340                 return 0.0;
1341         }
1342 #if 0
1343         /*
1344          * XXX - how to handle this?
1345          */
1346         if (IEEE_DP_INFINITY == exponent) {
1347                 /*
1348                  * number is positive or negative infinity, or a special value
1349                  */
1350                 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1351         }
1352 #endif
1353
1354         exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1355                 IEEE_DP_MANTISSA_WIDTH;
1356         mantissa |= IEEE_DP_IMPLIED_BIT;
1357
1358         if (sign)
1359                 return -mantissa * pow(2, exponent);
1360         else
1361                 return mantissa * pow(2, exponent);
1362 }
1363 #endif
1364
1365 /*
1366  * Fetches an IEEE single-precision floating-point number, in
1367  * big-endian form, and returns a "float".
1368  *
1369  * XXX - should this be "double", in case there are IEEE single-
1370  * precision numbers that won't fit in some platform's native
1371  * "float" format?
1372  */
1373 gfloat
1374 tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1375 {
1376 #if defined(vax)
1377         return get_ieee_float(tvb_get_ntohl(tvb, offset));
1378 #else
1379         union {
1380                 gfloat f;
1381                 guint32 w;
1382         } ieee_fp_union;
1383
1384         ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1385         return ieee_fp_union.f;
1386 #endif
1387 }
1388
1389 /*
1390  * Fetches an IEEE double-precision floating-point number, in
1391  * big-endian form, and returns a "double".
1392  */
1393 gdouble
1394 tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1395 {
1396 #if defined(vax)
1397         union {
1398                 guint32 w[2];
1399                 guint64 dw;
1400         } ieee_fp_union;
1401 #else
1402         union {
1403                 gdouble d;
1404                 guint32 w[2];
1405         } ieee_fp_union;
1406 #endif
1407
1408 #ifdef WORDS_BIGENDIAN
1409         ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1410         ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1411 #else
1412         ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1413         ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1414 #endif
1415 #if defined(vax)
1416         return get_ieee_double(ieee_fp_union.dw);
1417 #else
1418         return ieee_fp_union.d;
1419 #endif
1420 }
1421
1422 guint16
1423 tvb_get_letohs(tvbuff_t *tvb, const gint offset)
1424 {
1425         const guint8* ptr;
1426
1427         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1428         return pletohs(ptr);
1429 }
1430
1431 guint32
1432 tvb_get_letoh24(tvbuff_t *tvb, const gint offset)
1433 {
1434         const guint8* ptr;
1435
1436         ptr = fast_ensure_contiguous(tvb, offset, 3);
1437         return pletoh24(ptr);
1438 }
1439
1440 guint32
1441 tvb_get_letohl(tvbuff_t *tvb, const gint offset)
1442 {
1443         const guint8* ptr;
1444
1445         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1446         return pletohl(ptr);
1447 }
1448
1449 guint64
1450 tvb_get_letoh40(tvbuff_t *tvb, const gint offset)
1451 {
1452         const guint8* ptr;
1453
1454         ptr = fast_ensure_contiguous(tvb, offset, 5);
1455         return pletoh40(ptr);
1456 }
1457
1458 guint64
1459 tvb_get_letoh48(tvbuff_t *tvb, const gint offset)
1460 {
1461         const guint8* ptr;
1462
1463         ptr = fast_ensure_contiguous(tvb, offset, 6);
1464         return pletoh48(ptr);
1465 }
1466
1467 guint64
1468 tvb_get_letoh56(tvbuff_t *tvb, const gint offset)
1469 {
1470         const guint8* ptr;
1471
1472         ptr = fast_ensure_contiguous(tvb, offset, 7);
1473         return pletoh56(ptr);
1474 }
1475
1476 guint64
1477 tvb_get_letoh64(tvbuff_t *tvb, const gint offset)
1478 {
1479         const guint8* ptr;
1480
1481         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1482         return pletoh64(ptr);
1483 }
1484
1485 /*
1486  * Fetches an IEEE single-precision floating-point number, in
1487  * little-endian form, and returns a "float".
1488  *
1489  * XXX - should this be "double", in case there are IEEE single-
1490  * precision numbers that won't fit in some platform's native
1491  * "float" format?
1492  */
1493 gfloat
1494 tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1495 {
1496 #if defined(vax)
1497         return get_ieee_float(tvb_get_letohl(tvb, offset));
1498 #else
1499         union {
1500                 gfloat f;
1501                 guint32 w;
1502         } ieee_fp_union;
1503
1504         ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1505         return ieee_fp_union.f;
1506 #endif
1507 }
1508
1509 /*
1510  * Fetches an IEEE double-precision floating-point number, in
1511  * little-endian form, and returns a "double".
1512  */
1513 gdouble
1514 tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1515 {
1516 #if defined(vax)
1517         union {
1518                 guint32 w[2];
1519                 guint64 dw;
1520         } ieee_fp_union;
1521 #else
1522         union {
1523                 gdouble d;
1524                 guint32 w[2];
1525         } ieee_fp_union;
1526 #endif
1527
1528 #ifdef WORDS_BIGENDIAN
1529         ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1530         ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1531 #else
1532         ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1533         ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1534 #endif
1535 #if defined(vax)
1536         return get_ieee_double(ieee_fp_union.dw);
1537 #else
1538         return ieee_fp_union.d;
1539 #endif
1540 }
1541
1542 /* Fetch an IPv4 address, in network byte order.
1543  * We do *not* convert them to host byte order; we leave them in
1544  * network byte order. */
1545 guint32
1546 tvb_get_ipv4(tvbuff_t *tvb, const gint offset)
1547 {
1548         const guint8* ptr;
1549         guint32 addr;
1550
1551         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1552         memcpy(&addr, ptr, sizeof addr);
1553         return addr;
1554 }
1555
1556 /* Fetch an IPv6 address. */
1557 void
1558 tvb_get_ipv6(tvbuff_t *tvb, const gint offset, struct e_in6_addr *addr)
1559 {
1560         const guint8* ptr;
1561
1562         ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1563         memcpy(addr, ptr, sizeof *addr);
1564 }
1565
1566 /* Fetch a GUID. */
1567 void
1568 tvb_get_ntohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1569 {
1570         ensure_contiguous(tvb, offset, sizeof(*guid));
1571         guid->data1 = tvb_get_ntohl(tvb, offset);
1572         guid->data2 = tvb_get_ntohs(tvb, offset + 4);
1573         guid->data3 = tvb_get_ntohs(tvb, offset + 6);
1574         tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1575 }
1576
1577 void
1578 tvb_get_letohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1579 {
1580         ensure_contiguous(tvb, offset, sizeof(*guid));
1581         guid->data1 = tvb_get_letohl(tvb, offset);
1582         guid->data2 = tvb_get_letohs(tvb, offset + 4);
1583         guid->data3 = tvb_get_letohs(tvb, offset + 6);
1584         tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1585 }
1586
1587 /*
1588  * NOTE: to support code written when proto_tree_add_item() took a
1589  * gboolean as its last argument, with FALSE meaning "big-endian"
1590  * and TRUE meaning "little-endian", we treat any non-zero value of
1591  * "representation" as meaning "little-endian".
1592  */
1593 void
1594 tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint representation)
1595 {
1596         if (representation) {
1597                 tvb_get_letohguid(tvb, offset, guid);
1598         } else {
1599                 tvb_get_ntohguid(tvb, offset, guid);
1600         }
1601 }
1602
1603 static const guint8 bit_mask8[] = {
1604         0xff,
1605         0x7f,
1606         0x3f,
1607         0x1f,
1608         0x0f,
1609         0x07,
1610         0x03,
1611         0x01
1612 };
1613
1614 /* Bit offset mask for number of bits = 8 - 16 */
1615 static const guint16 bit_mask16[] = {
1616         0xffff,
1617         0x7fff,
1618         0x3fff,
1619         0x1fff,
1620         0x0fff,
1621         0x07ff,
1622         0x03ff,
1623         0x01ff
1624 };
1625
1626 /* Get 1 - 8 bits */
1627 guint8
1628 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits)
1629 {
1630         gint    offset;
1631         guint16 value = 0;
1632         guint8  tot_no_bits;
1633
1634         if (no_of_bits>8) {
1635                 DISSECTOR_ASSERT_NOT_REACHED();
1636         }
1637         /* Byte align offset */
1638         offset = bit_offset>>3;
1639
1640         /* Find out which mask to use for the most significant octet
1641          * by convering bit_offset into the offset into the first
1642          * fetched octet.
1643          */
1644         bit_offset = bit_offset & 0x7;
1645         tot_no_bits = bit_offset+no_of_bits;
1646         if(tot_no_bits<=8){
1647                 /* Read one octet, mask off bit_offset bits and left shift out the unused bits */
1648                 value = tvb_get_guint8(tvb,offset) & bit_mask8[bit_offset];
1649                 value = value >> (8-tot_no_bits);
1650         }else{
1651                 /* Read two octets, mask off bit_offset bits and left shift out the unused bits */
1652                 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1653                 value = value >> (16 - tot_no_bits);
1654         }
1655
1656         return (guint8)value;
1657 }
1658
1659 void
1660 tvb_get_bits_buf(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, guint8 *buf)
1661 {
1662         /* Byte align offset */
1663         gint offset = bit_offset >> 3;
1664         bit_offset = bit_offset & 0x7;
1665
1666         if (G_LIKELY(bit_offset != 0)) {
1667                 /* XXX, this can be optimized */
1668                 while (no_of_bits >= 8) {
1669                         guint16 value = (tvb_get_ntohs(tvb, offset) & bit_mask16[bit_offset]) >> (8 - bit_offset);
1670
1671                         *buf++ = (guint8) value;
1672                         offset++;
1673                         no_of_bits -= 8;
1674                 }
1675
1676                 /* something left? */
1677                 if (no_of_bits > 0)
1678                         *buf = tvb_get_bits8(tvb, offset * 8 + bit_offset, no_of_bits);
1679
1680         } else {
1681                 /* fast code path for bit_offset == 0 */
1682                 while (no_of_bits >= 8) {
1683                         *buf++ = tvb_get_guint8(tvb, offset);
1684                         offset++;
1685                         no_of_bits -= 8;
1686                 }
1687
1688                 /* something left? */
1689                 if (no_of_bits > 0)
1690                         *buf = tvb_get_guint8(tvb, offset) >> (8-no_of_bits);
1691         }
1692 }
1693
1694 guint8 *
1695 ep_tvb_get_bits(tvbuff_t *tvb, gint bit_offset, gint no_of_bits)
1696 {
1697         gint no_of_bytes;
1698         guint8 *buf;
1699
1700         /* XXX, no_of_bits == -1 -> to end of tvb? */
1701
1702         if (no_of_bits < 0 || bit_offset < 0) {
1703                 DISSECTOR_ASSERT_NOT_REACHED();
1704         }
1705
1706         no_of_bytes = (no_of_bits >> 3) + ((no_of_bits & 0x7) != 0);    /* ceil(no_of_bits / 8.0) */
1707         buf = ep_alloc(no_of_bytes);
1708         tvb_get_bits_buf(tvb, bit_offset, no_of_bits, buf);
1709         return buf;
1710 }
1711
1712 /* Get 9 - 16 bits */
1713 /* Bit offset mask for number of bits = 16 - 32 */
1714 static const guint32 bit_mask32[] = {
1715         0xffffffff,
1716         0x7fffffff,
1717         0x3fffffff,
1718         0x1fffffff,
1719         0x0fffffff,
1720         0x07ffffff,
1721         0x03ffffff,
1722         0x01ffffff
1723 };
1724
1725 guint16
1726 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits,const gboolean little_endian)
1727 {
1728         gint    offset;
1729         guint16 value = 0;
1730         guint16 tempval = 0;
1731         guint8  tot_no_bits;
1732
1733         if ((no_of_bits<=8)||(no_of_bits>16)) {
1734                 /* If bits <= 8 use tvb_get_bits8 */
1735                 DISSECTOR_ASSERT_NOT_REACHED();
1736         }
1737         if(little_endian){
1738                 DISSECTOR_ASSERT_NOT_REACHED();
1739                 /* This part is not implemented yet */
1740         }
1741
1742         /* Byte align offset */
1743         offset = bit_offset>>3;
1744
1745         /* Find out which mask to use for the most significant octet
1746          * by convering bit_offset into the offset into the first
1747          * fetched octet.
1748          */
1749         bit_offset = bit_offset & 0x7;
1750         tot_no_bits = bit_offset+no_of_bits;
1751         /* Read two octets and mask off bit_offset bits */
1752         value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1753         if(tot_no_bits < 16){
1754                 /* Left shift out the unused bits */
1755                 value = value >> (16 - tot_no_bits);
1756         }else if(tot_no_bits > 16){
1757                 /* Spans three octets, read next octet and shift as needed */
1758                 value = value << (tot_no_bits - 16);
1759                 tempval = tvb_get_guint8(tvb,offset+2);
1760                 tempval = tempval >> (24-tot_no_bits);
1761                 value = value | tempval;
1762         }
1763
1764         return value;
1765 }
1766
1767 /* Bit offset mask for number of bits = 32 - 64 */
1768 static const guint64 bit_mask64[] = {
1769         G_GINT64_CONSTANT(0xffffffffffffffffU),
1770         G_GINT64_CONSTANT(0x7fffffffffffffffU),
1771         G_GINT64_CONSTANT(0x3fffffffffffffffU),
1772         G_GINT64_CONSTANT(0x1fffffffffffffffU),
1773         G_GINT64_CONSTANT(0x0fffffffffffffffU),
1774         G_GINT64_CONSTANT(0x07ffffffffffffffU),
1775         G_GINT64_CONSTANT(0x03ffffffffffffffU),
1776         G_GINT64_CONSTANT(0x01ffffffffffffffU)
1777 };
1778
1779 guint32
1780 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1781 {
1782         gint    offset;
1783         guint32 value = 0;
1784         guint32 tempval = 0;
1785         guint8  tot_no_bits;
1786         guint8  tot_no_octets = 0;
1787         guint8  i = 0;
1788         gint8   shift = 0;
1789
1790         if ((no_of_bits<=16)||(no_of_bits>32)) {
1791                 /* If bits <= 16 use tvb_get_bits8 or tvb_get_bits16 */
1792                 DISSECTOR_ASSERT_NOT_REACHED();
1793         }
1794         if(little_endian){
1795                 DISSECTOR_ASSERT_NOT_REACHED();
1796                 /* This part is not implemented yet */
1797         }
1798
1799         /* Byte align offset */
1800         offset = bit_offset>>3;
1801
1802         bit_offset = bit_offset & 0x7;
1803         tot_no_bits = bit_offset+no_of_bits;
1804         tot_no_octets = tot_no_bits / 8;
1805         if (tot_no_bits % 8)
1806                 tot_no_octets++;
1807         shift = no_of_bits - (8 - bit_offset);
1808
1809         value = tvb_get_guint8(tvb, offset) & bit_mask8[bit_offset];
1810         value = value << shift;
1811
1812         for (i = 1; i < tot_no_octets; i++)
1813         {
1814                 shift = shift - 8;
1815                 tempval = tvb_get_guint8(tvb, offset+i);
1816                 if (shift >= 0)
1817                 {
1818                         tempval = tempval << shift;
1819                 }
1820                 else
1821                 {
1822                         tempval = tempval >> (- shift);
1823                 }
1824                 value = value | tempval;
1825         }
1826
1827         return value;
1828 }
1829
1830 guint64
1831 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1832 {
1833         gint    offset;
1834         guint64 value = 0;
1835         guint64 tempval = 0;
1836         guint8  tot_no_bits;
1837
1838         if ((no_of_bits<=32)||(no_of_bits>64)) {
1839                 /* If bits <= 32 use tvb_get_bits8, tvb_get_bits16 or tvb_get_bits32 */
1840                 DISSECTOR_ASSERT_NOT_REACHED();
1841         }
1842         if(little_endian){
1843                 DISSECTOR_ASSERT_NOT_REACHED();
1844                 /* This part is not implemented yet */
1845         }
1846
1847         /* Byte align offset */
1848         offset = bit_offset>>3;
1849
1850         /* Find out which mask to use for the most significant octet
1851          * by convering bit_offset into the offset into the first
1852          * fetched octet.
1853          */
1854         bit_offset = bit_offset & 0x7;
1855         tot_no_bits = bit_offset+no_of_bits;
1856         /* Read eight octets and mask off bit_offset bits */
1857         value = tvb_get_ntoh64(tvb,offset) & bit_mask64[bit_offset];
1858         if (tot_no_bits < 64){
1859                 /* Left shift out the unused bits */
1860                 value = value >> (64 - tot_no_bits);
1861         }else if (tot_no_bits > 64){
1862                 /* Spans nine octets, read next octet and shift as needed */
1863                 value = value << (tot_no_bits - 64);
1864                 tempval = tvb_get_guint8(tvb,offset+8);
1865                 tempval = tempval >> (72-tot_no_bits);
1866                 value = value | tempval;
1867         }
1868
1869         return value;
1870 }
1871
1872 guint32
1873 tvb_get_bits(tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1874 {
1875         /* This function can handle only up to 32 requested bits */
1876         if (no_of_bits > 32)
1877                 DISSECTOR_ASSERT_NOT_REACHED();
1878
1879         if (no_of_bits == 0)
1880                 return 0;
1881
1882         /* Number of requested bits is in range [17, 32] */
1883         if (no_of_bits > 16)
1884                 return tvb_get_bits32(tvb, bit_offset, no_of_bits, little_endian);
1885
1886         /* Number of requested bits is in range [9, 16] */
1887         if (no_of_bits > 8)
1888                 return tvb_get_bits16(tvb, bit_offset, no_of_bits, little_endian);
1889
1890         /* Number of requested bits is in range [1, 8] */
1891         return tvb_get_bits8(tvb, bit_offset, no_of_bits);
1892 }
1893
1894 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1895  * at most maxlength number of bytes; if maxlength is -1, searches to
1896  * end of tvbuff.
1897  * Returns the offset of the found needle, or -1 if not found.
1898  * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1899  * in that case, -1 will be returned if the boundary is reached before
1900  * finding needle. */
1901 gint
1902 tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
1903 {
1904         const guint8    *result;
1905         guint           abs_offset, junk_length;
1906         guint           tvbufflen;
1907         guint           limit;
1908
1909         DISSECTOR_ASSERT(tvb && tvb->initialized);
1910
1911         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1912
1913         /* Only search to end of tvbuff, w/o throwing exception. */
1914         tvbufflen = tvb_length_remaining(tvb, abs_offset);
1915         if (maxlength == -1) {
1916                 /* No maximum length specified; search to end of tvbuff. */
1917                 limit = tvbufflen;
1918         }
1919         else if (tvbufflen < (guint) maxlength) {
1920                 /* Maximum length goes past end of tvbuff; search to end
1921                    of tvbuff. */
1922                 limit = tvbufflen;
1923         }
1924         else {
1925                 /* Maximum length doesn't go past end of tvbuff; search
1926                    to that value. */
1927                 limit = maxlength;
1928         }
1929
1930         /* If we have real data, perform our search now. */
1931         if (tvb->real_data) {
1932                 result = memchr(tvb->real_data + abs_offset, needle, limit);
1933                 if (result == NULL) {
1934                         return -1;
1935                 }
1936                 else {
1937                         return (gint) (result - tvb->real_data);
1938                 }
1939         }
1940
1941         switch(tvb->type) {
1942                 case TVBUFF_REAL_DATA:
1943                         DISSECTOR_ASSERT_NOT_REACHED();
1944
1945                 case TVBUFF_SUBSET:
1946                         return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1947                                         abs_offset - tvb->tvbuffs.subset.offset,
1948                                         limit, needle);
1949
1950                 case TVBUFF_COMPOSITE:
1951                         DISSECTOR_ASSERT_NOT_REACHED();
1952                         /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1953         }
1954
1955         DISSECTOR_ASSERT_NOT_REACHED();
1956         return -1;
1957 }
1958
1959 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1960  * Searches at most maxlength number of bytes; if maxlength is -1, searches
1961  * to end of tvbuff.
1962  * Returns the offset of the found needle, or -1 if not found.
1963  * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1964  * in that case, -1 will be returned if the boundary is reached before
1965  * finding needle. */
1966 gint
1967 tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 *needles, guchar *found_needle)
1968 {
1969         const guint8    *result;
1970         guint           abs_offset, junk_length;
1971         guint           tvbufflen;
1972         guint           limit;
1973
1974         DISSECTOR_ASSERT(tvb && tvb->initialized);
1975
1976         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1977
1978         /* Only search to end of tvbuff, w/o throwing exception. */
1979         tvbufflen = tvb_length_remaining(tvb, abs_offset);
1980         if (maxlength == -1) {
1981                 /* No maximum length specified; search to end of tvbuff. */
1982                 limit = tvbufflen;
1983         }
1984         else if (tvbufflen < (guint) maxlength) {
1985                 /* Maximum length goes past end of tvbuff; search to end
1986                    of tvbuff. */
1987                 limit = tvbufflen;
1988         }
1989         else {
1990                 /* Maximum length doesn't go past end of tvbuff; search
1991                    to that value. */
1992                 limit = maxlength;
1993         }
1994
1995         /* If we have real data, perform our search now. */
1996         if (tvb->real_data) {
1997                 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles, found_needle);
1998                 if (result == NULL) {
1999                         return -1;
2000                 }
2001                 else {
2002                         return (gint) (result - tvb->real_data);
2003                 }
2004         }
2005
2006         switch(tvb->type) {
2007                 case TVBUFF_REAL_DATA:
2008                         DISSECTOR_ASSERT_NOT_REACHED();
2009
2010                 case TVBUFF_SUBSET:
2011                         return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
2012                                         abs_offset - tvb->tvbuffs.subset.offset,
2013                                         limit, needles, found_needle);
2014
2015                 case TVBUFF_COMPOSITE:
2016                         DISSECTOR_ASSERT_NOT_REACHED();
2017                         /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
2018         }
2019
2020         DISSECTOR_ASSERT_NOT_REACHED();
2021         return -1;
2022 }
2023
2024 /* Find size of stringz (NUL-terminated string) by looking for terminating
2025  * NUL.  The size of the string includes the terminating NUL.
2026  *
2027  * If the NUL isn't found, it throws the appropriate exception.
2028  */
2029 guint
2030 tvb_strsize(tvbuff_t *tvb, const gint offset)
2031 {
2032         guint   abs_offset, junk_length;
2033         gint    nul_offset;
2034
2035         DISSECTOR_ASSERT(tvb && tvb->initialized);
2036
2037         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
2038         nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
2039         if (nul_offset == -1) {
2040                 /*
2041                  * OK, we hit the end of the tvbuff, so we should throw
2042                  * an exception.
2043                  *
2044                  * Did we hit the end of the captured data, or the end
2045                  * of the actual data?  If there's less captured data
2046                  * than actual data, we presumably hit the end of the
2047                  * captured data, otherwise we hit the end of the actual
2048                  * data.
2049                  */
2050                 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
2051                         THROW(BoundsError);
2052                 } else {
2053                         THROW(ReportedBoundsError);
2054                 }
2055         }
2056         return (nul_offset - abs_offset) + 1;
2057 }
2058
2059 /* Unicode (UTF-16) version of tvb_strsize */
2060 /* Returns number of *UTF-16 characters* (not bytes) excluding the null terminator */
2061 guint
2062 tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
2063 {
2064         guint      i = 0;
2065         gunichar2  uchar;
2066
2067         DISSECTOR_ASSERT(tvb && tvb->initialized);
2068
2069         do {
2070                 /* Endianness doesn't matter when looking for null */
2071                 uchar = tvb_get_ntohs(tvb, offset + i);
2072                 i += 2;
2073         } while(uchar != 0);
2074
2075         return i; /* Number of *UTF-16* characters */
2076 }
2077
2078 /* Find length of string by looking for end of string ('\0'), up to
2079  * 'maxlength' characters'; if 'maxlength' is -1, searches to end
2080  * of tvbuff.
2081  * Returns -1 if 'maxlength' reached before finding EOS. */
2082 gint
2083 tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
2084 {
2085         gint    result_offset;
2086         guint   abs_offset, junk_length;
2087
2088         DISSECTOR_ASSERT(tvb && tvb->initialized);
2089
2090         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
2091
2092         result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
2093
2094         if (result_offset == -1) {
2095                 return -1;
2096         }
2097         else {
2098                 return result_offset - abs_offset;
2099         }
2100 }
2101
2102 /*
2103  * Implement strneql etc
2104  */
2105
2106 /*
2107  * Call strncmp after checking if enough chars left, returning 0 if
2108  * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2109  */
2110 gint
2111 tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2112 {
2113         const guint8 *ptr;
2114
2115         ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2116
2117         if (ptr) {
2118                 int cmp = strncmp((const char *)ptr, str, size);
2119
2120                 /*
2121                  * Return 0 if equal, -1 otherwise.
2122                  */
2123                 return (cmp == 0 ? 0 : -1);
2124         } else {
2125                 /*
2126                  * Not enough characters in the tvbuff to match the
2127                  * string.
2128                  */
2129                 return -1;
2130         }
2131 }
2132
2133 /*
2134  * Call g_ascii_strncasecmp after checking if enough chars left, returning
2135  * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2136  */
2137 gint
2138 tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2139 {
2140         const guint8 *ptr;
2141
2142         ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2143
2144         if (ptr) {
2145                 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2146
2147                 /*
2148                  * Return 0 if equal, -1 otherwise.
2149                  */
2150                 return (cmp == 0 ? 0 : -1);
2151         } else {
2152                 /*
2153                  * Not enough characters in the tvbuff to match the
2154                  * string.
2155                  */
2156                 return -1;
2157         }
2158 }
2159
2160 /*
2161  * Call memcmp after checking if enough chars left, returning 0 if
2162  * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2163  */
2164 gint
2165 tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str, size_t size)
2166 {
2167         const guint8 *ptr;
2168
2169         ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2170
2171         if (ptr) {
2172                 int cmp = memcmp(ptr, str, size);
2173
2174                 /*
2175                  * Return 0 if equal, -1 otherwise.
2176                  */
2177                 return (cmp == 0 ? 0 : -1);
2178         } else {
2179                 /*
2180                  * Not enough characters in the tvbuff to match the
2181                  * string.
2182                  */
2183                 return -1;
2184         }
2185 }
2186
2187 /* Convert a string from Unicode to ASCII.      At the moment we fake it by
2188  * replacing all non-ASCII characters with a '.' )-:  The caller must
2189  * free the result returned.  The len parameter is the number of guint16's
2190  * to convert from Unicode. */
2191 /* XXX - this function has been superceded by tvb_get_unicode_string() */
2192 char *
2193 tvb_fake_unicode(tvbuff_t *tvb, int offset, const int len, const gboolean little_endian)
2194 {
2195         char *buffer;
2196         int i;
2197         guint16 character;
2198
2199         /* Make sure we have enough data before allocating the buffer,
2200            so we don't blow up if the length is huge. */
2201         tvb_ensure_bytes_exist(tvb, offset, 2*len);
2202
2203         /* We know we won't throw an exception, so we don't have to worry
2204            about leaking this buffer. */
2205         buffer = g_malloc(len + 1);
2206
2207         for (i = 0; i < len; i++) {
2208                 character = little_endian ? tvb_get_letohs(tvb, offset)
2209                                           : tvb_get_ntohs(tvb, offset);
2210                 buffer[i] = character < 256 ? character : '.';
2211                 offset += 2;
2212         }
2213
2214         buffer[len] = 0;
2215
2216         return buffer;
2217 }
2218
2219 /* Convert a string from Unicode to ASCII.      At the moment we fake it by
2220  * replacing all non-ASCII characters with a '.' )-:   The len parameter is
2221  * the number of guint16's to convert from Unicode.
2222  *
2223  * This function allocates memory from a buffer with packet lifetime.
2224  * You do not have to free this buffer, it will be automatically freed
2225  * when wireshark starts decoding the next packet.
2226  */
2227 char *
2228 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, const int len, const gboolean little_endian)
2229 {
2230         char *buffer;
2231         int i;
2232         guint16 character;
2233
2234         /* Make sure we have enough data before allocating the buffer,
2235            so we don't blow up if the length is huge. */
2236         tvb_ensure_bytes_exist(tvb, offset, 2*len);
2237
2238         /* We know we won't throw an exception, so we don't have to worry
2239            about leaking this buffer. */
2240         buffer = ep_alloc(len + 1);
2241
2242         for (i = 0; i < len; i++) {
2243                 character = little_endian ? tvb_get_letohs(tvb, offset)
2244                                           : tvb_get_ntohs(tvb, offset);
2245                 buffer[i] = character < 256 ? character : '.';
2246                 offset += 2;
2247         }
2248
2249         buffer[len] = 0;
2250
2251         return buffer;
2252 }
2253
2254 /*
2255  * Format the data in the tvb from offset for length ...
2256  */
2257
2258 gchar *
2259 tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size)
2260 {
2261   const guint8 *ptr;
2262   gint len = size;
2263
2264   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2265     len = tvb_length_remaining(tvb, offset);
2266     ptr = ensure_contiguous(tvb, offset, len);
2267   }
2268
2269   return format_text(ptr, len);
2270 }
2271
2272 /*
2273  * Format the data in the tvb from offset for length ...
2274  */
2275
2276 gchar *
2277 tvb_format_text_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2278 {
2279   const guint8 *ptr;
2280   gint len = size;
2281
2282   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2283
2284         len = tvb_length_remaining(tvb, offset);
2285         ptr = ensure_contiguous(tvb, offset, len);
2286
2287   }
2288
2289   return format_text_wsp(ptr, len);
2290
2291 }
2292
2293 /*
2294  * Like "tvb_format_text()", but for null-padded strings; don't show
2295  * the null padding characters as "\000".
2296  */
2297 gchar *
2298 tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size)
2299 {
2300   const guint8 *ptr, *p;
2301   gint len = size;
2302   gint stringlen;
2303
2304   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2305
2306         len = tvb_length_remaining(tvb, offset);
2307         ptr = ensure_contiguous(tvb, offset, len);
2308
2309   }
2310
2311   for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2312         ;
2313   return format_text(ptr, stringlen);
2314
2315 }
2316
2317 /*
2318  * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2319  * the null padding characters as "\000".
2320  */
2321 gchar *
2322 tvb_format_stringzpad_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2323 {
2324   const guint8 *ptr, *p;
2325   gint len = size;
2326   gint stringlen;
2327
2328   if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2329
2330         len = tvb_length_remaining(tvb, offset);
2331         ptr = ensure_contiguous(tvb, offset, len);
2332
2333   }
2334
2335   for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2336         ;
2337   return format_text_wsp(ptr, stringlen);
2338
2339 }
2340
2341 /*
2342  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2343  * to hold a non-null-terminated string of that length at that offset,
2344  * plus a trailing '\0', copy the string into it, and return a pointer
2345  * to the string.
2346  *
2347  * Throws an exception if the tvbuff ends before the string does.
2348  */
2349 guint8 *
2350 tvb_get_string(tvbuff_t *tvb, const gint offset, const gint length)
2351 {
2352         const guint8 *ptr;
2353         guint8 *strbuf = NULL;
2354
2355         tvb_ensure_bytes_exist(tvb, offset, length);
2356
2357         ptr = ensure_contiguous(tvb, offset, length);
2358         strbuf = g_malloc(length + 1);
2359         if (length != 0) {
2360                 memcpy(strbuf, ptr, length);
2361         }
2362         strbuf[length] = '\0';
2363         return strbuf;
2364 }
2365
2366 /*
2367  * Unicode (UTF-16) version of tvb_get_string()
2368  *
2369  * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2370  *
2371  * Specify length in bytes
2372  *
2373  * Returns an UTF-8 string that must be freed by the caller
2374  */
2375 gchar *
2376 tvb_get_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2377 {
2378         gchar *tmpbuf = NULL;
2379         gunichar2 uchar;
2380         gint i; /* Byte counter for tvbuff */
2381         gint tmpbuf_len;
2382         GString *strbuf = NULL;
2383
2384         strbuf = g_string_new(NULL);
2385
2386         for(i = 0; i < length; i += 2) {
2387
2388                 if(encoding == ENC_BIG_ENDIAN)
2389                         uchar = tvb_get_ntohs(tvb, offset + i);
2390                 else
2391                         uchar = tvb_get_letohs(tvb, offset + i);
2392
2393                 /* Calculate how much space is needed to store UTF-16 character
2394                  * in UTF-8 */
2395                 tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
2396
2397                 tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
2398                                                     * terminator */
2399
2400                 g_unichar_to_utf8(uchar, tmpbuf);
2401
2402                 /* NULL terminate the tmpbuf so g_string_append knows where
2403                  * to stop */
2404                 tmpbuf[tmpbuf_len] = '\0';
2405
2406                 g_string_append(strbuf, tmpbuf);
2407
2408                 g_free(tmpbuf);
2409         }
2410
2411         return g_string_free(strbuf, FALSE);
2412 }
2413
2414 /*
2415  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2416  * to hold a non-null-terminated string of that length at that offset,
2417  * plus a trailing '\0', copy the string into it, and return a pointer
2418  * to the string.
2419  *
2420  * Throws an exception if the tvbuff ends before the string does.
2421  *
2422  * This function allocates memory from a buffer with packet lifetime.
2423  * You do not have to free this buffer, it will be automatically freed
2424  * when wireshark starts decoding the next packet.
2425  * Do not use this function if you want the allocated memory to be persistent
2426  * after the current packet has been dissected.
2427  */
2428 guint8 *
2429 tvb_get_ephemeral_string(tvbuff_t *tvb, const gint offset, const gint length)
2430 {
2431         const guint8 *ptr;
2432         guint8 *strbuf = NULL;
2433
2434         tvb_ensure_bytes_exist(tvb, offset, length);
2435
2436         ptr = ensure_contiguous(tvb, offset, length);
2437         strbuf = ep_alloc(length + 1);
2438         if (length != 0) {
2439                 memcpy(strbuf, ptr, length);
2440         }
2441         strbuf[length] = '\0';
2442         return strbuf;
2443 }
2444
2445 /*
2446  * Unicode (UTF-16) version of tvb_get_ephemeral_string()
2447  *
2448  * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2449  *
2450  * Specify length in bytes
2451  *
2452  * Returns an ep_ allocated UTF-8 string
2453  */
2454 gchar *
2455 tvb_get_ephemeral_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2456 {
2457         gchar *tmpbuf = NULL;
2458         gunichar2 uchar;
2459         gint i; /* Byte counter for tvbuff */
2460         gint tmpbuf_len;
2461         emem_strbuf_t *strbuf = NULL;
2462
2463         strbuf = ep_strbuf_new(NULL);
2464
2465         for(i = 0; i < length; i += 2) {
2466
2467                 if(encoding == ENC_BIG_ENDIAN)
2468                         uchar = tvb_get_ntohs(tvb, offset + i);
2469                 else
2470                         uchar = tvb_get_letohs(tvb, offset + i);
2471
2472                 /* Calculate how much space is needed to store UTF-16 character
2473                  * in UTF-8 */
2474                 tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
2475
2476                 tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
2477                                                     * terminator */
2478
2479                 g_unichar_to_utf8(uchar, tmpbuf);
2480
2481                 /* NULL terminate the tmpbuf so ep_strbuf_append knows where
2482                  * to stop */
2483                 tmpbuf[tmpbuf_len] = '\0';
2484
2485                 ep_strbuf_append(strbuf, tmpbuf);
2486
2487                 g_free(tmpbuf);
2488         }
2489
2490         return strbuf->str;
2491 }
2492
2493 /*
2494  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2495  * to hold a non-null-terminated string of that length at that offset,
2496  * plus a trailing '\0', copy the string into it, and return a pointer
2497  * to the string.
2498  *
2499  * Throws an exception if the tvbuff ends before the string does.
2500  *
2501  * This function allocates memory from a buffer with capture session lifetime.
2502  * You do not have to free this buffer, it will be automatically freed
2503  * when wireshark starts or opens a new capture.
2504  */
2505 guint8 *
2506 tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const gint length)
2507 {
2508         const guint8 *ptr;
2509         guint8 *strbuf = NULL;
2510
2511         tvb_ensure_bytes_exist(tvb, offset, length);
2512
2513         ptr = ensure_contiguous(tvb, offset, length);
2514         strbuf = se_alloc(length + 1);
2515         if (length != 0) {
2516                 memcpy(strbuf, ptr, length);
2517         }
2518         strbuf[length] = '\0';
2519         return strbuf;
2520 }
2521
2522 /*
2523  * Given a tvbuff and an offset, with the offset assumed to refer to
2524  * a null-terminated string, find the length of that string (and throw
2525  * an exception if the tvbuff ends before we find the null), allocate
2526  * a buffer big enough to hold the string, copy the string into it,
2527  * and return a pointer to the string.  Also return the length of the
2528  * string (including the terminating null) through a pointer.
2529  */
2530 guint8 *
2531 tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2532 {
2533         guint size;
2534         guint8 *strptr;
2535
2536         size = tvb_strsize(tvb, offset);
2537         strptr = g_malloc(size);
2538         tvb_memcpy(tvb, strptr, offset, size);
2539         if (lengthp)
2540                 *lengthp = size;
2541         return strptr;
2542 }
2543 /*
2544  * Given a tvbuff and an offset, with the offset assumed to refer to
2545  * a null-terminated string, find the length of that string (and throw
2546  * an exception if the tvbuff ends before we find the null), ensure that
2547  * the TVB is flat, and return a pointer to the string (in the TVB).
2548  * Also return the length of the string (including the terminating null)
2549  * through a pointer.
2550  *
2551  * As long as we aren't using composite TVBs, this saves the cycles used
2552  * (often unnecessariliy) in allocating a buffer and copying the string into
2553  * it.  (If we do start using composite TVBs, we may want to replace this
2554  * function with the _ephemeral versoin.)
2555  */
2556 const guint8 *
2557 tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2558 {
2559         guint size;
2560         const guint8 *strptr;
2561
2562         size = tvb_strsize(tvb, offset);
2563         strptr = ensure_contiguous(tvb, offset, size);
2564         if (lengthp)
2565                 *lengthp = size;
2566         return strptr;
2567 }
2568 /*
2569  * Given a tvbuff and an offset, with the offset assumed to refer to
2570  * a null-terminated string, find the length of that string (and throw
2571  * an exception if the tvbuff ends before we find the null), allocate
2572  * a buffer big enough to hold the string, copy the string into it,
2573  * and return a pointer to the string.  Also return the length of the
2574  * string (including the terminating null) through a pointer.
2575  *
2576  * This function allocates memory from a buffer with packet lifetime.
2577  * You do not have to free this buffer, it will be automatically freed
2578  * when wireshark starts decoding the next packet.
2579  * Do not use this function if you want the allocated memory to be persistent
2580  * after the current packet has been dissected.
2581  */
2582 guint8 *
2583 tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2584 {
2585         guint size;
2586         guint8 *strptr;
2587
2588         size = tvb_strsize(tvb, offset);
2589         strptr = ep_alloc(size);
2590         tvb_memcpy(tvb, strptr, offset, size);
2591         if (lengthp)
2592                 *lengthp = size;
2593         return strptr;
2594 }
2595
2596 /*
2597  * Unicode (UTF-16) version of tvb_get_ephemeral_stringz()
2598  *
2599  * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2600  *
2601  * Returns an ep_ allocated UTF-8 string and updates lengthp pointer with length of string (in bytes)
2602  */
2603 gchar *
2604 tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2605 {
2606         gchar *tmpbuf = NULL;
2607         gunichar2 uchar;
2608         gint size; /* Number of UTF-16 characters */
2609         gint i; /* Byte counter for tvbuff */
2610         gint tmpbuf_len;
2611         emem_strbuf_t *strbuf = NULL;
2612
2613         strbuf = ep_strbuf_new(NULL);
2614
2615         size = tvb_unicode_strsize(tvb, offset);
2616
2617         for(i = 0; i < size; i += 2) {
2618
2619                 if(encoding == ENC_BIG_ENDIAN)
2620                         uchar = tvb_get_ntohs(tvb, offset + i);
2621                 else
2622                         uchar = tvb_get_letohs(tvb, offset + i);
2623
2624                 /* Calculate how much space is needed to store UTF-16 character
2625                  * in UTF-8 */
2626                 tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
2627
2628                 tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
2629                                                     * terminator */
2630
2631                 g_unichar_to_utf8(uchar, tmpbuf);
2632
2633                 /* NULL terminate the tmpbuf so ep_strbuf_append knows where
2634                  * to stop */
2635                 tmpbuf[tmpbuf_len] = '\0';
2636
2637                 ep_strbuf_append(strbuf, tmpbuf);
2638
2639                 g_free(tmpbuf);
2640         }
2641
2642         if(lengthp)
2643                 *lengthp = i; /* Number of *bytes* processed */
2644
2645         return strbuf->str;
2646 }
2647
2648 /*
2649  * Given a tvbuff and an offset, with the offset assumed to refer to
2650  * a null-terminated string, find the length of that string (and throw
2651  * an exception if the tvbuff ends before we find the null), allocate
2652  * a buffer big enough to hold the string, copy the string into it,
2653  * and return a pointer to the string.  Also return the length of the
2654  * string (including the terminating null) through a pointer.
2655  *
2656  * This function allocates memory from a buffer with capture session lifetime.
2657  * You do not have to free this buffer, it will be automatically freed
2658  * when wireshark starts or opens a new capture.
2659  */
2660 guint8 *
2661 tvb_get_seasonal_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2662 {
2663         guint size;
2664         guint8 *strptr;
2665
2666         size = tvb_strsize(tvb, offset);
2667         strptr = se_alloc(size);
2668         tvb_memcpy(tvb, strptr, offset, size);
2669         if (lengthp)
2670                 *lengthp = size;
2671         return strptr;
2672 }
2673
2674 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2675  * no more than bufsize number of bytes, including terminating NUL, to buffer.
2676  * Returns length of string (not including terminating NUL), or -1 if the string was
2677  * truncated in the buffer due to not having reached the terminating NUL.
2678  * In this way, it acts like g_snprintf().
2679  *
2680  * bufsize MUST be greater than 0.
2681  *
2682  * When processing a packet where the remaining number of bytes is less
2683  * than bufsize, an exception is not thrown if the end of the packet
2684  * is reached before the NUL is found. If no NUL is found before reaching
2685  * the end of the short packet, -1 is still returned, and the string
2686  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2687  * at the correct spot, terminating the string.
2688  *
2689  * *bytes_copied will contain the number of bytes actually copied,
2690  * including the terminating-NUL.
2691  */
2692 static gint
2693 _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer,
2694                 gint *bytes_copied)
2695 {
2696         gint    stringlen;
2697         guint   abs_offset, junk_length;
2698         gint    limit, len;
2699         gboolean decreased_max = FALSE;
2700
2701         check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
2702
2703         /* There must at least be room for the terminating NUL. */
2704         DISSECTOR_ASSERT(bufsize != 0);
2705
2706         /* If there's no room for anything else, just return the NUL. */
2707         if (bufsize == 1) {
2708                 buffer[0] = 0;
2709                 *bytes_copied = 1;
2710                 return 0;
2711         }
2712
2713         /* Only read to end of tvbuff, w/o throwing exception. */
2714         len = tvb_length_remaining(tvb, abs_offset);
2715
2716         /* check_offset_length() won't throw an exception if we're
2717          * looking at the byte immediately after the end of the tvbuff. */
2718         if (len == 0) {
2719                 THROW(ReportedBoundsError);
2720         }
2721
2722         /* This should not happen because check_offset_length() would
2723          * have already thrown an exception if 'offset' were out-of-bounds.
2724          */
2725         DISSECTOR_ASSERT(len != -1);
2726
2727         /*
2728          * If we've been passed a negative number, bufsize will
2729          * be huge.
2730          */
2731         DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2732
2733         if ((guint)len < bufsize) {
2734                 limit = len;
2735                 decreased_max = TRUE;
2736         }
2737         else {
2738                 limit = bufsize;
2739         }
2740
2741         stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2742         /* If NUL wasn't found, copy the data and return -1 */
2743         if (stringlen == -1) {
2744                 tvb_memcpy(tvb, buffer, abs_offset, limit);
2745                 if (decreased_max) {
2746                         buffer[limit] = 0;
2747                         /* Add 1 for the extra NUL that we set at buffer[limit],
2748                          * pretending that it was copied as part of the string. */
2749                         *bytes_copied = limit + 1;
2750                 }
2751                 else {
2752                         *bytes_copied = limit;
2753                 }
2754                 return -1;
2755         }
2756
2757         /* Copy the string to buffer */
2758         tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2759         *bytes_copied = stringlen + 1;
2760         return stringlen;
2761 }
2762
2763 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2764  * no more than bufsize number of bytes, including terminating NUL, to buffer.
2765  * Returns length of string (not including terminating NUL), or -1 if the string was
2766  * truncated in the buffer due to not having reached the terminating NUL.
2767  * In this way, it acts like g_snprintf().
2768  *
2769  * When processing a packet where the remaining number of bytes is less
2770  * than bufsize, an exception is not thrown if the end of the packet
2771  * is reached before the NUL is found. If no NUL is found before reaching
2772  * the end of the short packet, -1 is still returned, and the string
2773  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2774  * at the correct spot, terminating the string.
2775  */
2776 gint
2777 tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2778 {
2779         gint bytes_copied;
2780
2781         DISSECTOR_ASSERT(tvb && tvb->initialized);
2782
2783         return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2784 }
2785
2786 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2787  * have a terminating NUL. If the string was truncated when copied into buffer,
2788  * a NUL is placed at the end of buffer to terminate it.
2789  */
2790 gint
2791 tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2792 {
2793         gint    len, bytes_copied;
2794
2795         DISSECTOR_ASSERT(tvb && tvb->initialized);
2796
2797         len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2798
2799         if (len == -1) {
2800                 buffer[bufsize - 1] = 0;
2801                 return bytes_copied - 1;
2802         }
2803         else {
2804                 return len;
2805         }
2806 }
2807
2808 /*
2809  * Given a tvbuff, an offset into the tvbuff, and a length that starts
2810  * at that offset (which may be -1 for "all the way to the end of the
2811  * tvbuff"), find the end of the (putative) line that starts at the
2812  * specified offset in the tvbuff, going no further than the specified
2813  * length.
2814  *
2815  * Return the length of the line (not counting the line terminator at
2816  * the end), or, if we don't find a line terminator:
2817  *
2818  *      if "deseg" is true, return -1;
2819  *
2820  *      if "deseg" is false, return the amount of data remaining in
2821  *      the buffer.
2822  *
2823  * Set "*next_offset" to the offset of the character past the line
2824  * terminator, or past the end of the buffer if we don't find a line
2825  * terminator.  (It's not set if we return -1.)
2826  */
2827 gint
2828 tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset,
2829         const gboolean desegment)
2830 {
2831         gint eob_offset;
2832         gint eol_offset;
2833         int linelen;
2834         guchar found_needle = 0;
2835
2836         if (len == -1)
2837                 len = tvb_length_remaining(tvb, offset);
2838         /*
2839          * XXX - what if "len" is still -1, meaning "offset is past the
2840          * end of the tvbuff"?
2841          */
2842         eob_offset = offset + len;
2843
2844         /*
2845          * Look either for a CR or an LF.
2846          */
2847         eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n", &found_needle);
2848         if (eol_offset == -1) {
2849                 /*
2850                  * No CR or LF - line is presumably continued in next packet.
2851                  */
2852                 if (desegment) {
2853                         /*
2854                          * Tell our caller we saw no EOL, so they can
2855                          * try to desegment and get the entire line
2856                          * into one tvbuff.
2857                          */
2858                         return -1;
2859                 } else {
2860                         /*
2861                          * Pretend the line runs to the end of the tvbuff.
2862                          */
2863                         linelen = eob_offset - offset;
2864                         if (next_offset)
2865                                 *next_offset = eob_offset;
2866                 }
2867         } else {
2868                 /*
2869                  * Find the number of bytes between the starting offset
2870                  * and the CR or LF.
2871                  */
2872                 linelen = eol_offset - offset;
2873
2874                 /*
2875                  * Is it a CR?
2876                  */
2877                 if (found_needle == '\r') {
2878                         /*
2879                          * Yes - is it followed by an LF?
2880                          */
2881                         if (eol_offset + 1 >= eob_offset) {
2882                                 /*
2883                                  * Dunno - the next byte isn't in this
2884                                  * tvbuff.
2885                                  */
2886                                 if (desegment) {
2887                                         /*
2888                                          * We'll return -1, although that
2889                                          * runs the risk that if the line
2890                                          * really *is* terminated with a CR,
2891                                          * we won't properly dissect this
2892                                          * tvbuff.
2893                                          *
2894                                          * It's probably more likely that
2895                                          * the line ends with CR-LF than
2896                                          * that it ends with CR by itself.
2897                                          */
2898                                         return -1;
2899                                 }
2900                         } else {
2901                                 /*
2902                                  * Well, we can at least look at the next
2903                                  * byte.
2904                                  */
2905                                 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2906                                         /*
2907                                          * It's an LF; skip over the CR.
2908                                          */
2909                                         eol_offset++;
2910                                 }
2911                         }
2912                 }
2913
2914                 /*
2915                  * Return the offset of the character after the last
2916                  * character in the line, skipping over the last character
2917                  * in the line terminator.
2918                  */
2919                 if (next_offset)
2920                         *next_offset = eol_offset + 1;
2921         }
2922         return linelen;
2923 }
2924
2925 /*
2926  * Given a tvbuff, an offset into the tvbuff, and a length that starts
2927  * at that offset (which may be -1 for "all the way to the end of the
2928  * tvbuff"), find the end of the (putative) line that starts at the
2929  * specified offset in the tvbuff, going no further than the specified
2930  * length.
2931  *
2932  * However, treat quoted strings inside the buffer specially - don't
2933  * treat newlines in quoted strings as line terminators.
2934  *
2935  * Return the length of the line (not counting the line terminator at
2936  * the end), or the amount of data remaining in the buffer if we don't
2937  * find a line terminator.
2938  *
2939  * Set "*next_offset" to the offset of the character past the line
2940  * terminator, or past the end of the buffer if we don't find a line
2941  * terminator.
2942  */
2943 gint
2944 tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len,
2945         gint *next_offset)
2946 {
2947         gint cur_offset, char_offset;
2948         gboolean is_quoted;
2949         guchar c = 0;
2950         gint eob_offset;
2951         int linelen;
2952
2953         if (len == -1)
2954                 len = tvb_length_remaining(tvb, offset);
2955         /*
2956          * XXX - what if "len" is still -1, meaning "offset is past the
2957          * end of the tvbuff"?
2958          */
2959         eob_offset = offset + len;
2960
2961         cur_offset = offset;
2962         is_quoted = FALSE;
2963         for (;;) {
2964                         /*
2965                  * Is this part of the string quoted?
2966                  */
2967                 if (is_quoted) {
2968                         /*
2969                          * Yes - look only for the terminating quote.
2970                          */
2971                         char_offset = tvb_find_guint8(tvb, cur_offset, len,
2972                                 '"');
2973                 } else {
2974                         /*
2975                          * Look either for a CR, an LF, or a '"'.
2976                          */
2977                         char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2978                                 (const guint8 *)"\r\n\"", &c);
2979                 }
2980                 if (char_offset == -1) {
2981                         /*
2982                          * Not found - line is presumably continued in
2983                          * next packet.
2984                          * We pretend the line runs to the end of the tvbuff.
2985                          */
2986                         linelen = eob_offset - offset;
2987                         if (next_offset)
2988                                 *next_offset = eob_offset;
2989                         break;
2990                 }
2991
2992                 if (is_quoted) {
2993                         /*
2994                          * We're processing a quoted string.
2995                          * We only looked for ", so we know it's a ";
2996                          * as we're processing a quoted string, it's a
2997                          * closing quote.
2998                          */
2999                         is_quoted = FALSE;
3000                 } else {
3001                         /*
3002                          * OK, what is it?
3003                          */
3004                         if (c == '"') {
3005                                 /*
3006                                  * Un-quoted "; it begins a quoted
3007                                  * string.
3008                                  */
3009                                 is_quoted = TRUE;
3010                         } else {
3011                                 /*
3012                                  * It's a CR or LF; we've found a line
3013                                  * terminator.
3014                                  *
3015                                  * Find the number of bytes between the
3016                                  * starting offset and the CR or LF.
3017                                  */
3018                                 linelen = char_offset - offset;
3019
3020                                 /*
3021                                  * Is it a CR?
3022                                  */
3023                                 if (c == '\r') {
3024                                         /*
3025                                          * Yes; is it followed by an LF?
3026                                          */
3027                                         if (char_offset + 1 < eob_offset &&
3028                                                 tvb_get_guint8(tvb, char_offset + 1)
3029                                                   == '\n') {
3030                                                 /*
3031                                                  * Yes; skip over the CR.
3032                                                  */
3033                                                 char_offset++;
3034                                         }
3035                                 }
3036
3037                                 /*
3038                                  * Return the offset of the character after
3039                                  * the last character in the line, skipping
3040                                  * over the last character in the line
3041                                  * terminator, and quit.
3042                                  */
3043                                 if (next_offset)
3044                                         *next_offset = char_offset + 1;
3045                                 break;
3046                         }
3047                 }
3048
3049                 /*
3050                  * Step past the character we found.
3051                  */
3052                 cur_offset = char_offset + 1;
3053                 if (cur_offset >= eob_offset) {
3054                         /*
3055                          * The character we found was the last character
3056                          * in the tvbuff - line is presumably continued in
3057                          * next packet.
3058                          * We pretend the line runs to the end of the tvbuff.
3059                          */
3060                         linelen = eob_offset - offset;
3061                         if (next_offset)
3062                                 *next_offset = eob_offset;
3063                         break;
3064                 }
3065         }
3066         return linelen;
3067 }
3068
3069 /*
3070  * Copied from the mgcp dissector. (This function should be moved to /epan )
3071  * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3072  *                                character following offset or offset + maxlength -1 whichever
3073  *                                is smaller.
3074  *
3075  * Parameters:
3076  * tvb - The tvbuff in which we are skipping whitespace.
3077  * offset - The offset in tvb from which we begin trying to skip whitespace.
3078  * maxlength - The maximum distance from offset that we may try to skip
3079  * whitespace.
3080  *
3081  * Returns: The position in tvb of the first non-whitespace
3082  *                      character following offset or offset + maxlength -1 whichever
3083  *                      is smaller.
3084  */
3085 gint tvb_skip_wsp(tvbuff_t* tvb, const gint offset, const gint maxlength)
3086 {
3087         gint counter = offset;
3088         gint end, tvb_len;
3089         guint8 tempchar;
3090
3091         /* Get the length remaining */
3092         tvb_len = tvb_length(tvb);
3093         end = offset + maxlength;
3094         if (end >= tvb_len)
3095         {
3096                 end = tvb_len;
3097         }
3098
3099         /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
3100         for (counter = offset;
3101                  counter < end &&
3102                   ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3103                   tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
3104                  counter++);
3105
3106         return (counter);
3107 }
3108
3109 gint tvb_skip_wsp_return(tvbuff_t* tvb, const gint offset){
3110         gint counter = offset;
3111         gint end;
3112         guint8 tempchar;
3113         end = 0;
3114
3115         for(counter = offset; counter > end &&
3116                 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3117                 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
3118         counter++;
3119         return (counter);
3120 }
3121
3122
3123 /*
3124  * Format a bunch of data from a tvbuff as bytes, returning a pointer
3125  * to the string with the formatted data, with "punct" as a byte
3126  * separator.
3127  */
3128 gchar *
3129 tvb_bytes_to_str_punct(tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
3130 {
3131         return bytes_to_str_punct(ensure_contiguous(tvb, offset, len), len, punct);
3132 }
3133
3134
3135 /*
3136  * Given a tvbuff, an offset into the tvbuff, and a length that starts
3137  * at that offset (which may be -1 for "all the way to the end of the
3138  * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
3139  * the low or high half byte, formating the digits according to an input digit set,
3140  * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
3141  * A pointer to the EP allocated string will be returned.
3142  * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
3143  */
3144 static dgt_set_t Dgt1_9_bcd = {
3145     {
3146   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
3147      '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
3148     }
3149 };
3150 gchar *
3151 tvb_bcd_dig_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_t *dgt, gboolean skip_first)
3152 {
3153         int length;
3154         guint8 octet;
3155         int i=0;
3156         char *digit_str;
3157         gint t_offset = offset;
3158
3159         if (!dgt)
3160                 dgt = &Dgt1_9_bcd;
3161
3162         if( len == -1){
3163                 length = tvb_length(tvb);
3164                 if (length < offset){
3165                         return "";
3166                 }
3167         }else{
3168                 length = offset + len;
3169         }
3170         digit_str = ep_alloc((length - offset)*2+1);
3171
3172         while ( t_offset < length ){
3173
3174                 octet = tvb_get_guint8(tvb,t_offset);
3175                 if (!skip_first){
3176                         digit_str[i] = dgt->out[octet & 0x0f];
3177                         i++;
3178                 }
3179                 skip_first = FALSE;
3180
3181                 /*
3182                  * unpack second value in byte
3183                  */
3184                 octet = octet >> 4;
3185
3186                 if (octet == 0x0f)      /* odd number bytes - hit filler */
3187                         break;
3188
3189                 digit_str[i] = dgt->out[octet & 0x0f];
3190                 i++;
3191                 t_offset++;
3192
3193         }
3194         digit_str[i]= '\0';
3195         return digit_str;
3196
3197 }
3198
3199 /*
3200  * Format a bunch of data from a tvbuff as bytes, returning a pointer
3201  * to the string with the formatted data.
3202  */
3203 gchar *
3204 tvb_bytes_to_str(tvbuff_t *tvb, const gint offset, const gint len)
3205 {
3206         return bytes_to_str(ensure_contiguous(tvb, offset, len), len);
3207 }
3208
3209 /* Find a needle tvbuff within a haystack tvbuff. */
3210 gint
3211 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
3212 {
3213         guint           haystack_abs_offset, haystack_abs_length;
3214         const guint8    *haystack_data;
3215         const guint8    *needle_data;
3216         const guint     needle_len = needle_tvb->length;
3217         const guint8    *location;
3218
3219         DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
3220
3221         if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
3222                 return -1;
3223         }
3224
3225         /* Get pointers to the tvbuffs' data. */
3226         haystack_data = ensure_contiguous(haystack_tvb, 0, -1);
3227         needle_data = ensure_contiguous(needle_tvb, 0, -1);
3228
3229         check_offset_length(haystack_tvb->length, haystack_tvb->reported_length, haystack_offset, -1,
3230                         &haystack_abs_offset, &haystack_abs_length);
3231
3232         location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
3233                         needle_data, needle_len);
3234
3235         if (location) {
3236                 return (gint) (location - haystack_data);
3237         }
3238
3239         return -1;
3240 }
3241
3242 #ifdef HAVE_LIBZ
3243 /*
3244  * Uncompresses a zlib compressed packet inside a message of tvb at offset with
3245  * length comprlen.  Returns an uncompressed tvbuffer if uncompression
3246  * succeeded or NULL if uncompression failed.
3247  */
3248 #define TVB_Z_MIN_BUFSIZ 32768
3249 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
3250 /* #define TVB_Z_DEBUG 1 */
3251 #undef TVB_Z_DEBUG
3252
3253 tvbuff_t *
3254 tvb_uncompress(tvbuff_t *tvb, const int offset, int comprlen)
3255 {
3256         gint err = Z_OK;
3257         guint bytes_out = 0;
3258         guint8 *compr = NULL;
3259         guint8 *uncompr = NULL;
3260         tvbuff_t *uncompr_tvb = NULL;
3261         z_streamp strm = NULL;
3262         Bytef *strmbuf = NULL;
3263         guint inits_done = 0;
3264         gint wbits = MAX_WBITS;
3265         guint8 *next = NULL;
3266         guint bufsiz = TVB_Z_MIN_BUFSIZ;
3267 #ifdef TVB_Z_DEBUG
3268         guint inflate_passes = 0;
3269         guint bytes_in = tvb_length_remaining(tvb, offset);
3270 #endif
3271
3272         if (tvb == NULL) {
3273                 return NULL;
3274         }
3275
3276         compr = tvb_memdup(tvb, offset, comprlen);
3277
3278         if (!compr)
3279                 return NULL;
3280
3281         /*
3282          * Assume that the uncompressed data is at least twice as big as
3283          * the compressed size.
3284          */
3285         bufsiz = tvb_length_remaining(tvb, offset) * 2;
3286         bufsiz = CLAMP(bufsiz, TVB_Z_MIN_BUFSIZ, TVB_Z_MAX_BUFSIZ);
3287
3288 #ifdef TVB_Z_DEBUG
3289         printf("bufsiz: %u bytes\n", bufsiz);
3290 #endif
3291
3292         next = compr;
3293
3294         strm = g_new0(z_stream, 1);
3295         strm->next_in = next;
3296         strm->avail_in = comprlen;
3297
3298         strmbuf = g_malloc0(bufsiz);
3299         strm->next_out = strmbuf;
3300         strm->avail_out = bufsiz;
3301
3302         err = inflateInit2(strm, wbits);
3303         inits_done = 1;
3304         if (err != Z_OK) {
3305                 inflateEnd(strm);
3306                 g_free(strm);
3307                 g_free(compr);
3308                 g_free(strmbuf);
3309                 return NULL;
3310         }
3311
3312         while (1) {
3313                 memset(strmbuf, '\0', bufsiz);
3314                 strm->next_out = strmbuf;
3315                 strm->avail_out = bufsiz;
3316
3317                 err = inflate(strm, Z_SYNC_FLUSH);
3318
3319                 if (err == Z_OK || err == Z_STREAM_END) {
3320                         guint bytes_pass = bufsiz - strm->avail_out;
3321
3322 #ifdef TVB_Z_DEBUG
3323                         ++inflate_passes;
3324 #endif
3325
3326                         if (uncompr == NULL) {
3327                                 uncompr = g_memdup(strmbuf, bytes_pass);
3328                         } else {
3329                                 guint8 *new_data = g_malloc0(bytes_out + bytes_pass);
3330
3331                                 g_memmove(new_data, uncompr, bytes_out);
3332                                 g_memmove((new_data + bytes_out), strmbuf,
3333                                         bytes_pass);
3334
3335                                 g_free(uncompr);
3336                                 uncompr = new_data;
3337                         }
3338
3339                         bytes_out += bytes_pass;
3340
3341                         if ( err == Z_STREAM_END) {
3342                                 inflateEnd(strm);
3343                                 g_free(strm);
3344                                 g_free(strmbuf);
3345                                 break;
3346                         }
3347                 } else if (err == Z_BUF_ERROR) {
3348                         /*
3349                          * It's possible that not enough frames were captured
3350                          * to decompress this fully, so return what we've done
3351                          * so far, if any.
3352                          */
3353                         inflateEnd(strm);
3354                         g_free(strm);
3355                         g_free(strmbuf);
3356
3357                         if (uncompr != NULL) {
3358                                 break;
3359                         } else {
3360                                 g_free(compr);
3361                                 return NULL;
3362                         }
3363
3364                 } else if (err == Z_DATA_ERROR && inits_done == 1
3365                         && uncompr == NULL && (*compr  == 0x1f) &&
3366                         (*(compr + 1) == 0x8b)) {
3367                         /*
3368                          * inflate() is supposed to handle both gzip and deflate
3369                          * streams automatically, but in reality it doesn't
3370                          * seem to handle either (at least not within the
3371                          * context of an HTTP response.)  We have to try
3372                          * several tweaks, depending on the type of data and
3373                          * version of the library installed.
3374                          */
3375
3376                         /*
3377                          * Gzip file format.  Skip past the header, since the
3378                          * fix to make it work (setting windowBits to 31)
3379                          * doesn't work with all versions of the library.
3380                          */
3381                         Bytef *c = compr + 2;
3382                         Bytef flags = 0;
3383
3384                         if (*c == Z_DEFLATED) {
3385                                 c++;
3386                         } else {
3387                                 inflateEnd(strm);
3388                                 g_free(strm);
3389                                 g_free(compr);
3390                                 g_free(strmbuf);
3391                                 return NULL;
3392                         }
3393
3394                         flags = *c;
3395
3396                         /* Skip past the MTIME, XFL, and OS fields. */
3397                         c += 7;
3398
3399             &