1 /* proto_data.c
2 * Protocol-specific data
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "config.h"
12
13 #include <glib.h>
14
15 #include <epan/wmem_scopes.h>
16 #include <epan/packet_info.h>
17 #include <epan/proto_data.h>
18 #include <epan/proto.h>
19
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 guint32 key;
26 void *proto_data;
27 } proto_data_t;
28
29 static gint
p_compare(gconstpointer a,gconstpointer b)30 p_compare(gconstpointer a, gconstpointer b)
31 {
32 const proto_data_t *ap = (const proto_data_t *)a;
33 const proto_data_t *bp = (const proto_data_t *)b;
34
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;
42 }
43 return -1;
44 } else {
45 return -1;
46 }
47 }
48
49 void
p_add_proto_data(wmem_allocator_t * tmp_scope,struct _packet_info * pinfo,int proto,guint32 key,void * proto_data)50 p_add_proto_data(wmem_allocator_t *tmp_scope, struct _packet_info* pinfo, int proto, guint32 key, void *proto_data)
51 {
52 proto_data_t *p1;
53 GSList **proto_list;
54 wmem_allocator_t *scope;
55
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");
64 }
65
66 p1 = wmem_new(scope, proto_data_t);
67
68 p1->proto = proto;
69 p1->key = key;
70 p1->proto_data = proto_data;
71
72 /* Add it to the GSLIST */
73 *proto_list = g_slist_prepend(*proto_list, p1);
74 }
75
76 void *
p_get_proto_data(wmem_allocator_t * scope,struct _packet_info * pinfo,int proto,guint32 key)77 p_get_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, guint32 key)
78 {
79 proto_data_t temp, *p1;
80 GSList *item;
81
82 temp.proto = proto;
83 temp.key = key;
84 temp.proto_data = NULL;
85
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");
92 }
93
94 if (item) {
95 p1 = (proto_data_t *)item->data;
96 return p1->proto_data;
97 }
98
99 return NULL;
100 }
101
102 void
p_remove_proto_data(wmem_allocator_t * scope,struct _packet_info * pinfo,int proto,guint32 key)103 p_remove_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, guint32 key)
104 {
105 proto_data_t temp;
106 GSList *item;
107 GSList **proto_list;
108
109 temp.proto = proto;
110 temp.key = key;
111 temp.proto_data = NULL;
112
113 if (scope == pinfo->pool) {
114 item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
115 proto_list = &pinfo->proto_data;
116 } else if (scope == wmem_file_scope()) {
117 item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
118 proto_list = &pinfo->fd->pfd;
119 } else {
120 DISSECTOR_ASSERT(!"invalid wmem scope");
121 }
122
123 if (item) {
124 *proto_list = g_slist_remove(*proto_list, item->data);
125 }
126 }
127
128 gchar *
p_get_proto_name_and_key(wmem_allocator_t * scope,struct _packet_info * pinfo,guint pfd_index)129 p_get_proto_name_and_key(wmem_allocator_t *scope, struct _packet_info* pinfo, guint pfd_index){
130 proto_data_t *temp;
131
132 if (scope == pinfo->pool) {
133 temp = (proto_data_t *)g_slist_nth_data(pinfo->proto_data, pfd_index);
134 } else if (scope == wmem_file_scope()) {
135 temp = (proto_data_t *)g_slist_nth_data(pinfo->fd->pfd, pfd_index);
136 } else {
137 DISSECTOR_ASSERT(!"invalid wmem scope");
138 }
139
140 return wmem_strdup_printf(pinfo->pool, "[%s, key %u]",proto_get_protocol_name(temp->proto), temp->key);
141 }
142
143 #define PROTO_DEPTH_KEY 0x3c233fb5 // printf "0x%02x%02x\n" ${RANDOM} ${RANDOM}
144
p_set_proto_depth(struct _packet_info * pinfo,int proto,unsigned depth)145 void p_set_proto_depth(struct _packet_info *pinfo, int proto, unsigned depth) {
146 p_add_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY, GUINT_TO_POINTER(depth));
147 }
148
p_get_proto_depth(struct _packet_info * pinfo,int proto)149 unsigned p_get_proto_depth(struct _packet_info *pinfo, int proto) {
150 return GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY));
151 }
152
153 /*
154 * Editor modelines - https://www.wireshark.org/tools/modelines.html
155 *
156 * Local variables:
157 * c-basic-offset: 2
158 * tab-width: 8
159 * indent-tabs-mode: nil
160 * End:
161 *
162 * vi: set shiftwidth=2 tabstop=8 expandtab:
163 * :indentSize=2:tabSize=8:noTabs=true:
164 */
165