/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 | 1.26M | { |
32 | 1.26M | const proto_data_t *ap = (const proto_data_t *)a; |
33 | 1.26M | const proto_data_t *bp = (const proto_data_t *)b; |
34 | | |
35 | 1.26M | if (ap -> proto > bp -> proto) { |
36 | 295k | return 1; |
37 | 969k | } else if (ap -> proto == bp -> proto) { |
38 | 827k | if (ap->key > bp->key){ |
39 | 252k | return 1; |
40 | 575k | } else if (ap -> key == bp -> key) { |
41 | 563k | return 0; |
42 | 563k | } |
43 | 11.4k | return -1; |
44 | 827k | } else { |
45 | 141k | return -1; |
46 | 141k | } |
47 | 1.26M | } |
48 | | |
49 | | void |
50 | | p_add_proto_data(wmem_allocator_t *tmp_scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data) |
51 | 547k | { |
52 | 547k | proto_data_t *p1; |
53 | 547k | GSList **proto_list; |
54 | 547k | wmem_allocator_t *scope; |
55 | | |
56 | 547k | if (tmp_scope == pinfo->pool) { |
57 | 416k | scope = tmp_scope; |
58 | 416k | proto_list = &pinfo->proto_data; |
59 | 416k | } else if (tmp_scope == wmem_file_scope()) { |
60 | 131k | scope = wmem_file_scope(); |
61 | 131k | proto_list = &pinfo->fd->pfd; |
62 | 131k | } else { |
63 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
64 | 0 | } |
65 | | |
66 | 547k | p1 = wmem_new(scope, proto_data_t); |
67 | | |
68 | 547k | p1->proto = proto; |
69 | 547k | p1->key = key; |
70 | 547k | p1->proto_data = proto_data; |
71 | | |
72 | | /* Add it to the GSLIST */ |
73 | 547k | *proto_list = g_slist_prepend(*proto_list, p1); |
74 | 547k | } |
75 | | |
76 | | void |
77 | | p_set_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data) |
78 | 81.8k | { |
79 | 81.8k | proto_data_t temp; |
80 | 81.8k | GSList *item; |
81 | | |
82 | 81.8k | temp.proto = proto; |
83 | 81.8k | temp.key = key; |
84 | 81.8k | temp.proto_data = NULL; |
85 | | |
86 | 81.8k | if (scope == pinfo->pool) { |
87 | 81.7k | item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare); |
88 | 81.7k | } else if (scope == wmem_file_scope()) { |
89 | 9 | item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare); |
90 | 9 | } else { |
91 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
92 | 0 | } |
93 | | |
94 | 81.8k | if (item) { |
95 | 78.7k | proto_data_t *pd = (proto_data_t *)item->data; |
96 | 78.7k | pd->proto_data = proto_data; |
97 | 78.7k | return; |
98 | 78.7k | } |
99 | | |
100 | 3.06k | p_add_proto_data(scope, pinfo, proto, key, proto_data); |
101 | 3.06k | } |
102 | | |
103 | | void * |
104 | | p_get_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key) |
105 | 847k | { |
106 | 847k | proto_data_t temp, *p1; |
107 | 847k | GSList *item; |
108 | | |
109 | 847k | temp.proto = proto; |
110 | 847k | temp.key = key; |
111 | 847k | temp.proto_data = NULL; |
112 | | |
113 | 847k | if (scope == pinfo->pool) { |
114 | 299k | item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare); |
115 | 547k | } else if (scope == wmem_file_scope()) { |
116 | 547k | item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare); |
117 | 547k | } else { |
118 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
119 | 0 | } |
120 | | |
121 | 847k | if (item) { |
122 | 484k | p1 = (proto_data_t *)item->data; |
123 | 484k | return p1->proto_data; |
124 | 484k | } |
125 | | |
126 | 362k | return NULL; |
127 | 847k | } |
128 | | |
129 | | void |
130 | | p_remove_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key) |
131 | 1.43k | { |
132 | 1.43k | proto_data_t temp; |
133 | 1.43k | GSList *item; |
134 | 1.43k | GSList **proto_list; |
135 | | |
136 | 1.43k | temp.proto = proto; |
137 | 1.43k | temp.key = key; |
138 | 1.43k | temp.proto_data = NULL; |
139 | | |
140 | 1.43k | if (scope == pinfo->pool) { |
141 | 610 | item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare); |
142 | 610 | proto_list = &pinfo->proto_data; |
143 | 821 | } else if (scope == wmem_file_scope()) { |
144 | 821 | item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare); |
145 | 821 | proto_list = &pinfo->fd->pfd; |
146 | 821 | } else { |
147 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
148 | 0 | } |
149 | | |
150 | 1.43k | if (item) { |
151 | 596 | *proto_list = g_slist_remove(*proto_list, item->data); |
152 | 596 | } |
153 | 1.43k | } |
154 | | |
155 | | char * |
156 | 0 | p_get_proto_name_and_key(wmem_allocator_t *scope, struct _packet_info* pinfo, unsigned pfd_index){ |
157 | 0 | proto_data_t *temp; |
158 | |
|
159 | 0 | if (scope == pinfo->pool) { |
160 | 0 | temp = (proto_data_t *)g_slist_nth_data(pinfo->proto_data, pfd_index); |
161 | 0 | } else if (scope == wmem_file_scope()) { |
162 | 0 | temp = (proto_data_t *)g_slist_nth_data(pinfo->fd->pfd, pfd_index); |
163 | 0 | } else { |
164 | 0 | DISSECTOR_ASSERT(!"invalid wmem scope"); |
165 | 0 | } |
166 | |
|
167 | 0 | return wmem_strdup_printf(pinfo->pool, "[%s, key %u]",proto_get_protocol_name(temp->proto), temp->key); |
168 | 0 | } |
169 | | |
170 | 80.3k | #define PROTO_DEPTH_KEY 0x3c233fb5 // printf "0x%02x%02x\n" ${RANDOM} ${RANDOM} |
171 | | |
172 | 80.3k | void p_set_proto_depth(struct _packet_info *pinfo, int proto, unsigned depth) { |
173 | 80.3k | p_set_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY, GUINT_TO_POINTER(depth)); |
174 | 80.3k | } |
175 | | |
176 | 46.0k | 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)); |
178 | 46.0k | } |
179 | | |
180 | | /* |
181 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
182 | | * |
183 | | * Local variables: |
184 | | * c-basic-offset: 2 |
185 | | * tab-width: 8 |
186 | | * indent-tabs-mode: nil |
187 | | * End: |
188 | | * |
189 | | * vi: set shiftwidth=2 tabstop=8 expandtab: |
190 | | * :indentSize=2:tabSize=8:noTabs=true: |
191 | | */ |