/src/wireshark/epan/dissectors/packet-lbm.c
Line | Count | Source |
1 | | /* packet-lbm.c |
2 | | * Routines for LBM Packet dissection |
3 | | * |
4 | | * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved. |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | */ |
12 | | |
13 | | #include "config.h" |
14 | | #include <epan/packet.h> |
15 | | #include <epan/tfs.h> |
16 | | #include "packet-lbm.h" |
17 | | |
18 | | void proto_register_lbm(void); |
19 | | |
20 | | /*----------------------------------------------------------------------------*/ |
21 | | /* Value translation tables. */ |
22 | | /*----------------------------------------------------------------------------*/ |
23 | | |
24 | | const true_false_string lbm_ignore_flag = |
25 | | { |
26 | | "May be ignored", |
27 | | "Must be processed" |
28 | | }; |
29 | | |
30 | | #define LBM_WILDCARD_PATTERN_TYPE_PCRE 1 |
31 | | #define LBM_WILDCARD_PATTERN_TYPE_REGEX 2 |
32 | | |
33 | | const value_string lbm_wildcard_pattern_type[] = |
34 | | { |
35 | | { LBM_WILDCARD_PATTERN_TYPE_PCRE, "Perl Compatible Regular Expression (PCRE)" }, |
36 | | { LBM_WILDCARD_PATTERN_TYPE_REGEX, "POSIX Extended Regular Expression (REGEX)" }, |
37 | | { 0x0, NULL } |
38 | | }; |
39 | | |
40 | | const value_string lbm_wildcard_pattern_type_short[] = |
41 | | { |
42 | | { LBM_WILDCARD_PATTERN_TYPE_PCRE, "PCRE" }, |
43 | | { LBM_WILDCARD_PATTERN_TYPE_REGEX, "REGEX" }, |
44 | | { 0x0, NULL } |
45 | | }; |
46 | | |
47 | | /* Initialization function, called whenever Wireshark loads a new capture, etc. */ |
48 | | static void lbm_init(void) |
49 | 14 | { |
50 | 14 | lbm_channel_reset(); |
51 | 14 | } |
52 | | |
53 | | /* Register all the bits needed with the filtering engine */ |
54 | | void proto_register_lbm(void) |
55 | 14 | { |
56 | 14 | register_init_routine(lbm_init); |
57 | 14 | } |
58 | | |
59 | | /*----------------------------------------------------------------------------*/ |
60 | | /* Channel interface. */ |
61 | | /*----------------------------------------------------------------------------*/ |
62 | | /* |
63 | | lbm_next_channel_value is a counter (akin to tcp_stream_count in packet-tcp.c) used to assign a unique index to an LBM communication |
64 | | stream or transport session. The actual channel value consists of: |
65 | | - The lower 52 bits of the counter, shifted left 12 bits |
66 | | - A 4-bit source/client classification (for unicast channels), shifted left 8 bits |
67 | | - An 8-bit channel type |
68 | | |
69 | | 6 1 1 0 0 0 |
70 | | 3 2 1 8 7 0 |
71 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
72 | | | Counter | S/C | Type | |
73 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
74 | | |
75 | | The counter wraps at 0x000ffffffffffffe, and is reset to 1 whenever Wireshark invokes any init routines registered via |
76 | | register_init_routine() (the call to lbm_channel_reset() is in packet-lbm.c). |
77 | | |
78 | | Special values are used as placeholders to indicate an as-yet-unknown transport or stream TCP channel. |
79 | | */ |
80 | | |
81 | | static uint64_t lbm_next_channel_value = 1; |
82 | | |
83 | 1.16k | #define LBM_CHANNEL_TYPE_MASK UINT64_C(0x00000000000000ff) |
84 | 7 | #define LBM_CHANNEL_VALUE_LIMIT_MASK UINT64_C(0x000ffffffffffffff) |
85 | 7 | #define LBM_CHANNEL_MAX_VALUE UINT64_C(0x000ffffffffffffe) |
86 | | |
87 | 1.62k | #define LBM_CHANNEL_VALUE_UNKNOWN UINT64_C(0xfffffffffffff000) |
88 | 1.35k | #define LBM_CHANNEL_VALUE_UNKNOWN_SOURCE UINT64_C(0xfffffffffffff100) |
89 | 1.31k | #define LBM_CHANNEL_VALUE_UNKNOWN_CLIENT UINT64_C(0xfffffffffffff200) |
90 | 1.35k | #define LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_SOURCE | LBM_CHANNEL_TRANSPORT_LBTTCP) |
91 | 1.31k | #define LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_CLIENT | LBM_CHANNEL_TRANSPORT_LBTTCP) |
92 | 1.62k | #define LBM_CHANNEL_UNKNOWN_STREAM_TCP (LBM_CHANNEL_VALUE_UNKNOWN | LBM_CHANNEL_STREAM_TCP) |
93 | | |
94 | 1.16k | #define LBM_CHANNEL_TYPE(ch) ((uint8_t)(ch & LBM_CHANNEL_TYPE_MASK)) |
95 | | |
96 | | void lbm_channel_reset(void) |
97 | 14 | { |
98 | 14 | lbm_next_channel_value = 1; |
99 | 14 | } |
100 | | |
101 | | uint64_t lbm_channel_assign(uint8_t channel_type) |
102 | 7 | { |
103 | 7 | uint64_t ch; |
104 | 7 | uint64_t ch_counter = lbm_next_channel_value++; |
105 | | |
106 | 7 | if (lbm_next_channel_value == LBM_CHANNEL_MAX_VALUE) |
107 | 0 | { |
108 | 0 | lbm_next_channel_value = 1; |
109 | 0 | } |
110 | 7 | ch = ((uint64_t)((ch_counter & LBM_CHANNEL_VALUE_LIMIT_MASK) << LBM_CHANNEL_VALUE_SHIFT_COUNT)) | channel_type; |
111 | 7 | return (ch); |
112 | 7 | } |
113 | | |
114 | | bool lbm_channel_is_transport(uint64_t channel) |
115 | 732 | { |
116 | 732 | uint8_t ch_type; |
117 | | |
118 | 732 | ch_type = LBM_CHANNEL_TYPE(channel); |
119 | 732 | switch (ch_type) |
120 | 732 | { |
121 | 43 | case LBM_CHANNEL_TRANSPORT_LBTTCP: |
122 | 43 | case LBM_CHANNEL_TRANSPORT_LBTRU: |
123 | 43 | case LBM_CHANNEL_TRANSPORT_LBTRM: |
124 | 43 | case LBM_CHANNEL_TRANSPORT_LBTIPC: |
125 | 43 | case LBM_CHANNEL_TRANSPORT_LBTRDMA: |
126 | 43 | case LBM_CHANNEL_TRANSPORT_LBTSMX: |
127 | 43 | return true; |
128 | 689 | default: |
129 | 689 | break; |
130 | 732 | } |
131 | 689 | return false; |
132 | 732 | } |
133 | | |
134 | | uint8_t lbm_channel_type(uint64_t channel) |
135 | 437 | { |
136 | 437 | uint8_t ch_type; |
137 | | |
138 | 437 | ch_type = LBM_CHANNEL_TYPE(channel); |
139 | 437 | return (ch_type); |
140 | 437 | } |
141 | | |
142 | | uint64_t lbm_channel_assign_unknown_transport_source_lbttcp(void) |
143 | 14 | { |
144 | 14 | return (LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP); |
145 | 14 | } |
146 | | |
147 | | uint64_t lbm_channel_assign_unknown_transport_client_lbttcp(void) |
148 | 20 | { |
149 | 20 | return (LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP); |
150 | 20 | } |
151 | | |
152 | | uint64_t lbm_channel_assign_unknown_stream_tcp(void) |
153 | 810 | { |
154 | 810 | return (LBM_CHANNEL_UNKNOWN_STREAM_TCP); |
155 | 810 | } |
156 | | |
157 | | bool lbm_channel_is_unknown_transport_lbttcp(uint64_t channel) |
158 | 899 | { |
159 | 899 | return (lbm_channel_is_unknown_transport_source_lbttcp(channel) || lbm_channel_is_unknown_transport_client_lbttcp(channel)); |
160 | 899 | } |
161 | | |
162 | | bool lbm_channel_is_unknown_transport_source_lbttcp(uint64_t channel) |
163 | 1.33k | { |
164 | 1.33k | if (channel == LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP) |
165 | 44 | { |
166 | 44 | return true; |
167 | 44 | } |
168 | 1.29k | return false; |
169 | 1.33k | } |
170 | | |
171 | | bool lbm_channel_is_unknown_transport_client_lbttcp(uint64_t channel) |
172 | 1.29k | { |
173 | 1.29k | if (channel == LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP) |
174 | 65 | { |
175 | 65 | return true; |
176 | 65 | } |
177 | 1.22k | return false; |
178 | 1.29k | } |
179 | | |
180 | | bool lbm_channel_is_unknown_stream_tcp(uint64_t channel) |
181 | 810 | { |
182 | 810 | if (channel == LBM_CHANNEL_UNKNOWN_STREAM_TCP) |
183 | 810 | { |
184 | 810 | return true; |
185 | 810 | } |
186 | 0 | return false; |
187 | 810 | } |
188 | | |
189 | | bool lbm_channel_is_known(uint64_t channel) |
190 | 895 | { |
191 | 895 | return (!lbm_channel_is_unknown_transport_lbttcp(channel) && !lbm_channel_is_unknown_stream_tcp(channel)); |
192 | 895 | } |
193 | | |
194 | | /*----------------------------------------------------------------------------*/ |
195 | | /* Frame/SQN interface. */ |
196 | | /*----------------------------------------------------------------------------*/ |
197 | | lbm_transport_frame_t * lbm_transport_frame_add(wmem_tree_t * list, uint8_t type, uint32_t frame, uint32_t sqn, bool retransmission) |
198 | 0 | { |
199 | 0 | lbm_transport_frame_t * frame_entry = NULL; |
200 | | |
201 | | /* Locate the frame. */ |
202 | 0 | frame_entry = (lbm_transport_frame_t *) wmem_tree_lookup32(list, frame); |
203 | 0 | if (frame_entry != NULL) |
204 | 0 | { |
205 | 0 | return (frame_entry); |
206 | 0 | } |
207 | 0 | frame_entry = wmem_new(wmem_file_scope(), lbm_transport_frame_t); |
208 | 0 | frame_entry->frame = frame; |
209 | 0 | frame_entry->type = type; |
210 | 0 | frame_entry->sqn = sqn; |
211 | 0 | frame_entry->previous_frame = 0; |
212 | 0 | frame_entry->previous_type_frame = 0; |
213 | 0 | frame_entry->next_frame = 0; |
214 | 0 | frame_entry->next_type_frame = 0; |
215 | 0 | frame_entry->retransmission = retransmission; |
216 | 0 | frame_entry->sqn_gap = 0; |
217 | 0 | frame_entry->ooo_gap = 0; |
218 | 0 | frame_entry->duplicate = false; |
219 | 0 | wmem_tree_insert32(list, frame, (void *) frame_entry); |
220 | 0 | return (frame_entry); |
221 | 0 | } |
222 | | |
223 | | lbm_transport_sqn_t * lbm_transport_sqn_add(wmem_tree_t * list, lbm_transport_frame_t * frame) |
224 | 0 | { |
225 | 0 | lbm_transport_sqn_t * sqn_entry = NULL; |
226 | 0 | lbm_transport_sqn_frame_t * frame_entry = NULL; |
227 | | |
228 | | /* Locate the SQN. */ |
229 | 0 | sqn_entry = (lbm_transport_sqn_t *) wmem_tree_lookup32(list, frame->sqn); |
230 | 0 | if (sqn_entry == NULL) |
231 | 0 | { |
232 | 0 | sqn_entry = wmem_new(wmem_file_scope(), lbm_transport_sqn_t); |
233 | 0 | sqn_entry->sqn = frame->sqn; |
234 | 0 | sqn_entry->frame_count = 0; |
235 | 0 | sqn_entry->frame = wmem_tree_new(wmem_file_scope()); |
236 | 0 | wmem_tree_insert32(list, frame->sqn, (void *) sqn_entry); |
237 | 0 | } |
238 | | /* Add this frame to the list of frames this SQN appears in. */ |
239 | 0 | frame_entry = wmem_new(wmem_file_scope(), lbm_transport_sqn_frame_t); |
240 | 0 | frame_entry->frame = frame->frame; |
241 | 0 | frame_entry->retransmission = frame->retransmission; |
242 | 0 | wmem_tree_insert32(sqn_entry->frame, frame->frame, (void *) frame_entry); |
243 | 0 | sqn_entry->frame_count++; |
244 | 0 | return (sqn_entry); |
245 | 0 | } |
246 | | |
247 | | /*----------------------------------------------------------------------------*/ |
248 | | /* Topic interface. */ |
249 | | /*----------------------------------------------------------------------------*/ |
250 | | static wmem_tree_t * lbm_topic_table; |
251 | | |
252 | 0 | #define LBM_TOPIC_KEY_ELEMENT_COUNT 3 |
253 | 0 | #define LBM_TOPIC_KEY_ELEMENT_CHANNEL_HIGH 0 |
254 | 0 | #define LBM_TOPIC_KEY_ELEMENT_CHANNEL_LOW 1 |
255 | 0 | #define LBM_TOPIC_KEY_ELEMENT_TOPIC_INDEX 2 |
256 | | |
257 | | struct lbm_topic_t_stct; |
258 | | typedef struct lbm_topic_t_stct lbm_topic_t; |
259 | | |
260 | | typedef struct |
261 | | { |
262 | | uint64_t channel; |
263 | | uint32_t topic_idx; |
264 | | lbm_topic_t * topic; |
265 | | } lbm_topic_key_t; |
266 | | |
267 | | struct lbm_topic_t_stct |
268 | | { |
269 | | lbm_topic_key_t key; |
270 | | char * topic; |
271 | | }; |
272 | | |
273 | | void lbm_topic_init(void) |
274 | 14 | { |
275 | 14 | lbm_topic_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
276 | 14 | } |
277 | | |
278 | | static void lbm_topic_build_key(uint32_t * key_value, wmem_tree_key_t * key, uint64_t channel, uint32_t topic_index) |
279 | 0 | { |
280 | 0 | key_value[LBM_TOPIC_KEY_ELEMENT_CHANNEL_HIGH] = (uint32_t) ((channel >> 32) & 0xffffffff); |
281 | 0 | key_value[LBM_TOPIC_KEY_ELEMENT_CHANNEL_LOW] = (uint32_t) (channel & 0xffffffff); |
282 | 0 | key_value[LBM_TOPIC_KEY_ELEMENT_TOPIC_INDEX] = topic_index; |
283 | 0 | key[0].length = LBM_TOPIC_KEY_ELEMENT_COUNT; |
284 | 0 | key[0].key = key_value; |
285 | 0 | key[1].length = 0; |
286 | 0 | key[1].key = NULL; |
287 | 0 | } |
288 | | |
289 | | static lbm_topic_t * lbm_topic_locate(uint64_t channel, uint32_t topic_index) |
290 | 0 | { |
291 | 0 | lbm_topic_t * entry = NULL; |
292 | 0 | uint32_t keyval[LBM_TOPIC_KEY_ELEMENT_COUNT]; |
293 | 0 | wmem_tree_key_t tkey[2]; |
294 | |
|
295 | 0 | lbm_topic_build_key(keyval, tkey, channel, topic_index); |
296 | 0 | entry = (lbm_topic_t *) wmem_tree_lookup32_array(lbm_topic_table, tkey); |
297 | 0 | return (entry); |
298 | 0 | } |
299 | | |
300 | | const char * lbm_topic_find(uint64_t channel, uint32_t topic_index) |
301 | 0 | { |
302 | 0 | lbm_topic_t * entry = NULL; |
303 | 0 | const char * topic = NULL; |
304 | |
|
305 | 0 | entry = lbm_topic_locate(channel, topic_index); |
306 | 0 | if (entry != NULL) |
307 | 0 | { |
308 | 0 | topic = entry->topic; |
309 | 0 | } |
310 | 0 | return (topic); |
311 | 0 | } |
312 | | |
313 | | void lbm_topic_add(uint64_t channel, uint32_t topic_index, const char * name) |
314 | 0 | { |
315 | 0 | lbm_topic_t * entry; |
316 | 0 | uint32_t keyval[LBM_TOPIC_KEY_ELEMENT_COUNT]; |
317 | 0 | wmem_tree_key_t tkey[2]; |
318 | |
|
319 | 0 | entry = lbm_topic_locate(channel, topic_index); |
320 | 0 | if (entry != NULL) |
321 | 0 | { |
322 | 0 | return; |
323 | 0 | } |
324 | 0 | entry = wmem_new(wmem_file_scope(), lbm_topic_t); |
325 | 0 | entry->key.channel = channel; |
326 | 0 | entry->key.topic_idx = topic_index; |
327 | 0 | entry->key.topic = entry; |
328 | 0 | entry->topic = wmem_strdup(wmem_file_scope(), name); |
329 | 0 | lbm_topic_build_key(keyval, tkey, channel, topic_index); |
330 | 0 | wmem_tree_insert32_array(lbm_topic_table, tkey, (void *) entry); |
331 | 0 | } |
332 | | |
333 | | /* |
334 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
335 | | * |
336 | | * Local variables: |
337 | | * c-basic-offset: 4 |
338 | | * tab-width: 8 |
339 | | * indent-tabs-mode: nil |
340 | | * End: |
341 | | * |
342 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
343 | | * :indentSize=4:tabSize=8:noTabs=true: |
344 | | */ |