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