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