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