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