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