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