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