1 /* tvbuff_real.c
2  *
3  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include "config.h"
13 
14 #include "tvbuff.h"
15 #include "tvbuff-int.h"
16 #include "proto.h"	/* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
17 #include "exceptions.h"
18 
19 struct tvb_real {
20 	struct tvbuff tvb;
21 
22 	/** Func to call when actually freed */
23 	tvbuff_free_cb_t	free_cb;
24 };
25 
26 static void
27 real_free(tvbuff_t *tvb)
28 {
29 	struct tvb_real *real_tvb = (struct tvb_real *) tvb;
30 
31 	if (real_tvb->free_cb) {
32 		/*
33 		 * XXX - do this with a union?
34 		 */
35 		real_tvb->free_cb((gpointer)tvb->real_data);
36 	}
37 }
38 
39 static guint
40 real_offset(const tvbuff_t *tvb _U_, const guint counter)
41 {
42 	return counter;
43 }
44 
45 static const struct tvb_ops tvb_real_ops = {
46 	sizeof(struct tvb_real), /* size */
47 
48 	real_free,            /* free */
49 	real_offset,          /* offset */
50 	NULL,                 /* get_ptr */
51 	NULL,                 /* memcpy */
52 	NULL,                 /* find_guint8 */
53 	NULL,                 /* pbrk_guint8 */
54 	NULL,                 /* clone */
55 };
56 
57 tvbuff_t *
58 tvb_new_real_data(const guint8* data, const guint length, const gint reported_length)
59 {
60 	tvbuff_t *tvb;
61 	struct tvb_real *real_tvb;
62 
63 	THROW_ON(reported_length < -1, ReportedBoundsError);
64 
65 	tvb = tvb_new(&tvb_real_ops);
66 
67 	tvb->real_data           = data;
68 	tvb->length              = length;
69 	tvb->reported_length     = reported_length;
70 	tvb->contained_length    = reported_length;
71 	tvb->initialized         = TRUE;
72 
73 	/*
74 	 * This is the top-level real tvbuff for this data source,
75 	 * so its data source tvbuff is itself.
76 	 */
77 	tvb->ds_tvb = tvb;
78 
79 	real_tvb = (struct tvb_real *) tvb;
80 	real_tvb->free_cb = NULL;
81 
82 	return tvb;
83 }
84 
85 void
86 tvb_set_free_cb(tvbuff_t *tvb, const tvbuff_free_cb_t func)
87 {
88 	struct tvb_real *real_tvb = (struct tvb_real *) tvb;
89 
90 	DISSECTOR_ASSERT(tvb);
91 	DISSECTOR_ASSERT(tvb->ops == &tvb_real_ops);
92 	real_tvb->free_cb = func;
93 }
94 
95 void
96 tvb_set_child_real_data_tvbuff(tvbuff_t *parent, tvbuff_t *child)
97 {
98 	DISSECTOR_ASSERT(parent && child);
99 	DISSECTOR_ASSERT(parent->initialized);
100 	DISSECTOR_ASSERT(child->initialized);
101 	DISSECTOR_ASSERT(child->ops == &tvb_real_ops);
102 	tvb_add_to_chain(parent, child);
103 }
104 
105 tvbuff_t *
106 tvb_new_child_real_data(tvbuff_t *parent, const guint8* data, const guint length, const gint reported_length)
107 {
108 	tvbuff_t *tvb = tvb_new_real_data(data, length, reported_length);
109 
110 	tvb_set_child_real_data_tvbuff(parent, tvb);
111 
112 	return tvb;
113 }
114 
115 /*
116  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
117  *
118  * Local variables:
119  * c-basic-offset: 8
120  * tab-width: 8
121  * indent-tabs-mode: t
122  * End:
123  *
124  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
125  * :indentSize=8:tabSize=8:noTabs=false:
126  */
127