wmem: allow wmem_destroy_list to ignore a NULL list.
[wireshark-sm.git] / epan / proto_data.c
blob662383ca1676da0aa39e52e941b3870639eaa020
1 /* proto_data.c
2 * Protocol-specific data
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <glib.h>
15 #include <epan/wmem_scopes.h>
16 #include <epan/packet_info.h>
17 #include <epan/proto_data.h>
18 #include <epan/proto.h>
20 /* Protocol-specific data attached to a frame_data structure - protocol
21 index, key for multiple items with the same protocol index,
22 and opaque pointer. */
23 typedef struct _proto_data {
24 int proto;
25 uint32_t key;
26 void *proto_data;
27 } proto_data_t;
29 static int
30 p_compare(const void *a, const void *b)
32 const proto_data_t *ap = (const proto_data_t *)a;
33 const proto_data_t *bp = (const proto_data_t *)b;
35 if (ap -> proto > bp -> proto) {
36 return 1;
37 } else if (ap -> proto == bp -> proto) {
38 if (ap->key > bp->key){
39 return 1;
40 } else if (ap -> key == bp -> key) {
41 return 0;
43 return -1;
44 } else {
45 return -1;
49 void
50 p_add_proto_data(wmem_allocator_t *tmp_scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
52 proto_data_t *p1;
53 GSList **proto_list;
54 wmem_allocator_t *scope;
56 if (tmp_scope == pinfo->pool) {
57 scope = tmp_scope;
58 proto_list = &pinfo->proto_data;
59 } else if (tmp_scope == wmem_file_scope()) {
60 scope = wmem_file_scope();
61 proto_list = &pinfo->fd->pfd;
62 } else {
63 DISSECTOR_ASSERT(!"invalid wmem scope");
66 p1 = wmem_new(scope, proto_data_t);
68 p1->proto = proto;
69 p1->key = key;
70 p1->proto_data = proto_data;
72 /* Add it to the GSLIST */
73 *proto_list = g_slist_prepend(*proto_list, p1);
76 void
77 p_set_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
79 proto_data_t temp;
80 GSList *item;
82 temp.proto = proto;
83 temp.key = key;
84 temp.proto_data = NULL;
86 if (scope == pinfo->pool) {
87 item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
88 } else if (scope == wmem_file_scope()) {
89 item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
90 } else {
91 DISSECTOR_ASSERT(!"invalid wmem scope");
94 if (item) {
95 proto_data_t *pd = (proto_data_t *)item->data;
96 pd->proto_data = proto_data;
97 return;
100 p_add_proto_data(scope, pinfo, proto, key, proto_data);
103 void *
104 p_get_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key)
106 proto_data_t temp, *p1;
107 GSList *item;
109 temp.proto = proto;
110 temp.key = key;
111 temp.proto_data = NULL;
113 if (scope == pinfo->pool) {
114 item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
115 } else if (scope == wmem_file_scope()) {
116 item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
117 } else {
118 DISSECTOR_ASSERT(!"invalid wmem scope");
121 if (item) {
122 p1 = (proto_data_t *)item->data;
123 return p1->proto_data;
126 return NULL;
129 void
130 p_remove_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key)
132 proto_data_t temp;
133 GSList *item;
134 GSList **proto_list;
136 temp.proto = proto;
137 temp.key = key;
138 temp.proto_data = NULL;
140 if (scope == pinfo->pool) {
141 item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
142 proto_list = &pinfo->proto_data;
143 } else if (scope == wmem_file_scope()) {
144 item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
145 proto_list = &pinfo->fd->pfd;
146 } else {
147 DISSECTOR_ASSERT(!"invalid wmem scope");
150 if (item) {
151 *proto_list = g_slist_remove(*proto_list, item->data);
155 char *
156 p_get_proto_name_and_key(wmem_allocator_t *scope, struct _packet_info* pinfo, unsigned pfd_index){
157 proto_data_t *temp;
159 if (scope == pinfo->pool) {
160 temp = (proto_data_t *)g_slist_nth_data(pinfo->proto_data, pfd_index);
161 } else if (scope == wmem_file_scope()) {
162 temp = (proto_data_t *)g_slist_nth_data(pinfo->fd->pfd, pfd_index);
163 } else {
164 DISSECTOR_ASSERT(!"invalid wmem scope");
167 return wmem_strdup_printf(pinfo->pool, "[%s, key %u]",proto_get_protocol_name(temp->proto), temp->key);
170 #define PROTO_DEPTH_KEY 0x3c233fb5 // printf "0x%02x%02x\n" ${RANDOM} ${RANDOM}
172 void p_set_proto_depth(struct _packet_info *pinfo, int proto, unsigned depth) {
173 p_set_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY, GUINT_TO_POINTER(depth));
176 unsigned p_get_proto_depth(struct _packet_info *pinfo, int proto) {
177 return GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY));
181 * Editor modelines - https://www.wireshark.org/tools/modelines.html
183 * Local variables:
184 * c-basic-offset: 2
185 * tab-width: 8
186 * indent-tabs-mode: nil
187 * End:
189 * vi: set shiftwidth=2 tabstop=8 expandtab:
190 * :indentSize=2:tabSize=8:noTabs=true: