/src/wireshark/epan/proto_data.c
Line | Count | Source |
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 | | uint32_t key; |
26 | | void *proto_data; |
27 | | } proto_data_t; |
28 | | |
29 | | static int |
30 | | p_compare(const void *a, const void *b) |
31 | 2.43M | { |
32 | 2.43M | const proto_data_t *ap = (const proto_data_t *)a; |
33 | 2.43M | const proto_data_t *bp = (const proto_data_t *)b; |
34 | | |
35 | 2.43M | if (ap -> proto > bp -> proto) { |
36 | 650k | return 1; |
37 | 1.78M | } else if (ap -> proto == bp -> proto) { |
38 | 1.49M | if (ap->key > bp->key){ |
39 | 362k | return 1; |
40 | 1.12M | } else if (ap -> key == bp -> key) { |
41 | 1.02M | return 0; |
42 | 1.02M | } |
43 | 106k | return -1; |
44 | 1.49M | } else { |
45 | 296k | return -1; |
46 | 296k | } |
47 | 2.43M | } |
48 | | |
49 | | void |
50 | | p_add_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data) |
51 | 1.04M | { |
52 | 1.04M | proto_data_t *p1; |
53 | 1.04M | wmem_list_t **proto_list; |
54 | | |
55 | 1.04M | if (scope == pinfo->pool) { |
56 | 834k | proto_list = &pinfo->proto_data; |
57 | 834k | } else if (scope == wmem_file_scope()) { |
58 | 214k | proto_list = &pinfo->fd->pfd; |
59 | 214k | } else { |
60 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
61 | 0 | } |
62 | | |
63 | 1.04M | if (*proto_list == NULL) { |
64 | 289k | *proto_list = wmem_list_new(scope); |
65 | 289k | } |
66 | | |
67 | 1.04M | p1 = wmem_new(scope, proto_data_t); |
68 | | |
69 | 1.04M | p1->proto = proto; |
70 | 1.04M | p1->key = key; |
71 | 1.04M | p1->proto_data = proto_data; |
72 | | |
73 | | /* Add it to the list */ |
74 | 1.04M | wmem_list_prepend(*proto_list, p1); |
75 | 1.04M | } |
76 | | |
77 | | void |
78 | | p_set_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data) |
79 | 187k | { |
80 | | /* Probably more dissectors should use this instead of p_add_proto_data. */ |
81 | 187k | proto_data_t temp; |
82 | 187k | wmem_list_t *proto_list; |
83 | 187k | wmem_list_frame_t *item; |
84 | | |
85 | 187k | temp.proto = proto; |
86 | 187k | temp.key = key; |
87 | 187k | temp.proto_data = NULL; |
88 | | |
89 | 187k | if (scope == pinfo->pool) { |
90 | 187k | proto_list = pinfo->proto_data; |
91 | 187k | } else if (scope == wmem_file_scope()) { |
92 | 17 | proto_list = pinfo->fd->pfd; |
93 | 17 | } else { |
94 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
95 | 0 | } |
96 | | |
97 | 187k | if (proto_list) { |
98 | 167k | item = wmem_list_find_custom(proto_list, &temp, p_compare); |
99 | 167k | if (item) { |
100 | 158k | proto_data_t *pd = (proto_data_t*)wmem_list_frame_data(item); |
101 | 158k | pd->proto_data = proto_data; |
102 | 158k | return; |
103 | 158k | } |
104 | 167k | } |
105 | | |
106 | 28.8k | p_add_proto_data(scope, pinfo, proto, key, proto_data); |
107 | 28.8k | } |
108 | | |
109 | | void * |
110 | | p_get_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key) |
111 | 1.51M | { |
112 | 1.51M | proto_data_t temp, *p1; |
113 | 1.51M | wmem_list_t *proto_list; |
114 | 1.51M | wmem_list_frame_t *item; |
115 | | |
116 | 1.51M | temp.proto = proto; |
117 | 1.51M | temp.key = key; |
118 | 1.51M | temp.proto_data = NULL; |
119 | | |
120 | 1.51M | if (scope == pinfo->pool) { |
121 | 670k | proto_list = pinfo->proto_data; |
122 | 848k | } else if (scope == wmem_file_scope()) { |
123 | 848k | proto_list = pinfo->fd->pfd; |
124 | 848k | } else { |
125 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
126 | 0 | } |
127 | | |
128 | 1.51M | if (!proto_list) |
129 | 398k | return NULL; |
130 | | |
131 | 1.12M | item = wmem_list_find_custom(proto_list, &temp, p_compare); |
132 | | |
133 | 1.12M | if (item) { |
134 | 862k | p1 = wmem_list_frame_data(item); |
135 | 862k | return p1->proto_data; |
136 | 862k | } |
137 | | |
138 | 257k | return NULL; |
139 | 1.12M | } |
140 | | |
141 | | void |
142 | | p_remove_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key) |
143 | 2.07k | { |
144 | 2.07k | proto_data_t temp; |
145 | 2.07k | wmem_list_t *proto_list; |
146 | 2.07k | wmem_list_frame_t *item; |
147 | | |
148 | 2.07k | temp.proto = proto; |
149 | 2.07k | temp.key = key; |
150 | 2.07k | temp.proto_data = NULL; |
151 | | |
152 | 2.07k | if (scope == pinfo->pool) { |
153 | 1.11k | proto_list = pinfo->proto_data; |
154 | 1.11k | } else if (scope == wmem_file_scope()) { |
155 | 959 | proto_list = pinfo->fd->pfd; |
156 | 959 | } else { |
157 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
158 | 0 | } |
159 | | |
160 | 2.07k | if (!proto_list) |
161 | 0 | return; |
162 | | |
163 | 2.07k | item = wmem_list_find_custom(proto_list, &temp, p_compare); |
164 | 2.07k | if (item) { |
165 | 678 | wmem_list_remove_frame(proto_list, item); |
166 | 678 | } |
167 | 2.07k | } |
168 | | |
169 | | GPtrArray * |
170 | 0 | p_get_proto_names_and_keys(wmem_allocator_t *scope, struct _packet_info* pinfo) { |
171 | 0 | wmem_list_t *proto_list; |
172 | 0 | proto_data_t *temp; |
173 | 0 | GPtrArray *ret; |
174 | |
|
175 | 0 | if (scope == pinfo->pool) { |
176 | 0 | proto_list = pinfo->proto_data; |
177 | 0 | } else if (scope == wmem_file_scope()) { |
178 | 0 | proto_list = pinfo->fd->pfd; |
179 | 0 | } else { |
180 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
181 | 0 | } |
182 | |
|
183 | 0 | if (!proto_list) |
184 | 0 | return NULL; |
185 | | |
186 | 0 | ret = g_ptr_array_new(); |
187 | |
|
188 | 0 | for (wmem_list_frame_t *frame = wmem_list_head(proto_list); |
189 | 0 | frame; frame = wmem_list_frame_next(frame)) { |
190 | |
|
191 | 0 | temp = wmem_list_frame_data(frame); |
192 | 0 | g_ptr_array_add(ret, wmem_strdup_printf(pinfo->pool, "[%s, key %u]",proto_get_protocol_name(temp->proto), temp->key)); |
193 | 0 | } |
194 | 0 | return ret; |
195 | 0 | } |
196 | | |
197 | 184k | #define PROTO_DEPTH_KEY 0x3c233fb5 // printf "0x%02x%02x\n" ${RANDOM} ${RANDOM} |
198 | | |
199 | 184k | void p_set_proto_depth(struct _packet_info *pinfo, int proto, unsigned depth) { |
200 | 184k | p_set_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY, GUINT_TO_POINTER(depth)); |
201 | 184k | } |
202 | | |
203 | 113k | unsigned p_get_proto_depth(struct _packet_info *pinfo, int proto) { |
204 | | return GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY)); |
205 | 113k | } |
206 | | |
207 | | /* |
208 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
209 | | * |
210 | | * Local variables: |
211 | | * c-basic-offset: 2 |
212 | | * tab-width: 8 |
213 | | * indent-tabs-mode: nil |
214 | | * End: |
215 | | * |
216 | | * vi: set shiftwidth=2 tabstop=8 expandtab: |
217 | | * :indentSize=2:tabSize=8:noTabs=true: |
218 | | */ |