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