/src/wireshark/epan/tvbuff_real.c
Line | Count | Source |
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 | 465k | { |
29 | 465k | struct tvb_real *real_tvb = (struct tvb_real *) tvb; |
30 | | |
31 | 465k | if (real_tvb->free_cb) { |
32 | | /* |
33 | | * XXX - do this with a union? |
34 | | */ |
35 | 222k | real_tvb->free_cb((void *)tvb->real_data); |
36 | 222k | } |
37 | 465k | } |
38 | | |
39 | | static unsigned |
40 | | real_offset(const tvbuff_t *tvb _U_, const unsigned counter) |
41 | 874k | { |
42 | 874k | return counter; |
43 | 874k | } |
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_uint8 */ |
53 | | NULL, /* pbrk_uint8 */ |
54 | | NULL, /* clone */ |
55 | | }; |
56 | | |
57 | | tvbuff_t * |
58 | | tvb_new_real_data(const uint8_t* data, const unsigned length, const int reported_length) |
59 | 479k | { |
60 | 479k | tvbuff_t *tvb; |
61 | 479k | struct tvb_real *real_tvb; |
62 | | |
63 | 479k | THROW_ON(reported_length < -1, ReportedBoundsError); |
64 | | |
65 | 479k | tvb = tvb_new(&tvb_real_ops); |
66 | | |
67 | 479k | tvb->real_data = data; |
68 | 479k | tvb->length = length; |
69 | 479k | tvb->reported_length = reported_length; |
70 | 479k | tvb->contained_length = reported_length; |
71 | 479k | 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 | 479k | tvb->ds_tvb = tvb; |
78 | | |
79 | 479k | real_tvb = (struct tvb_real *) tvb; |
80 | 479k | real_tvb->free_cb = NULL; |
81 | | |
82 | 479k | return tvb; |
83 | 479k | } |
84 | | |
85 | | void |
86 | | tvb_set_free_cb(tvbuff_t *tvb, const tvbuff_free_cb_t func) |
87 | 238k | { |
88 | 238k | struct tvb_real *real_tvb = (struct tvb_real *) tvb; |
89 | | |
90 | 238k | DISSECTOR_ASSERT(tvb); |
91 | 238k | DISSECTOR_ASSERT(tvb->ops == &tvb_real_ops); |
92 | 238k | real_tvb->free_cb = func; |
93 | 238k | } |
94 | | |
95 | | void |
96 | | tvb_set_child_real_data_tvbuff(tvbuff_t *parent, tvbuff_t *child) |
97 | 354k | { |
98 | 354k | DISSECTOR_ASSERT(parent && child); |
99 | 354k | DISSECTOR_ASSERT(parent->initialized); |
100 | 354k | DISSECTOR_ASSERT(child->initialized); |
101 | 354k | DISSECTOR_ASSERT(child->ops == &tvb_real_ops); |
102 | 354k | tvb_add_to_chain(parent, child); |
103 | 354k | } |
104 | | |
105 | | tvbuff_t * |
106 | | tvb_new_child_real_data(tvbuff_t *parent, const uint8_t* data, const unsigned length, const int reported_length) |
107 | 353k | { |
108 | 353k | tvbuff_t *tvb = tvb_new_real_data(data, length, reported_length); |
109 | | |
110 | 353k | tvb_set_child_real_data_tvbuff(parent, tvb); |
111 | | |
112 | 353k | return tvb; |
113 | 353k | } |
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 | | */ |