2 * Routines for LBM Packet dissection
4 * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
16 #include "packet-lbm.h"
18 void proto_register_lbm(void);
20 /*----------------------------------------------------------------------------*/
21 /* Value translation tables. */
22 /*----------------------------------------------------------------------------*/
24 const true_false_string lbm_ignore_flag
=
30 #define LBM_WILDCARD_PATTERN_TYPE_PCRE 1
31 #define LBM_WILDCARD_PATTERN_TYPE_REGEX 2
33 const value_string lbm_wildcard_pattern_type
[] =
35 { LBM_WILDCARD_PATTERN_TYPE_PCRE
, "Perl Compatible Regular Expression (PCRE)" },
36 { LBM_WILDCARD_PATTERN_TYPE_REGEX
, "POSIX Extended Regular Expression (REGEX)" },
40 const value_string lbm_wildcard_pattern_type_short
[] =
42 { LBM_WILDCARD_PATTERN_TYPE_PCRE
, "PCRE" },
43 { LBM_WILDCARD_PATTERN_TYPE_REGEX
, "REGEX" },
47 /* Initialization function, called whenever Wireshark loads a new capture, etc. */
48 static void lbm_init(void)
53 /* Register all the bits needed with the filtering engine */
54 void proto_register_lbm(void)
56 register_init_routine(lbm_init
);
59 /*----------------------------------------------------------------------------*/
60 /* Channel interface. */
61 /*----------------------------------------------------------------------------*/
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
71 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 | Counter | S/C | Type |
73 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
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).
78 Special values are used as placeholders to indicate an as-yet-unknown transport or stream TCP channel.
81 static uint64_t lbm_next_channel_value
= 1;
83 #define LBM_CHANNEL_TYPE_MASK UINT64_C(0x00000000000000ff)
84 #define LBM_CHANNEL_VALUE_LIMIT_MASK UINT64_C(0x000ffffffffffffff)
85 #define LBM_CHANNEL_MAX_VALUE UINT64_C(0x000ffffffffffffe)
87 #define LBM_CHANNEL_VALUE_UNKNOWN UINT64_C(0xfffffffffffff000)
88 #define LBM_CHANNEL_VALUE_UNKNOWN_SOURCE UINT64_C(0xfffffffffffff100)
89 #define LBM_CHANNEL_VALUE_UNKNOWN_CLIENT UINT64_C(0xfffffffffffff200)
90 #define LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_SOURCE | LBM_CHANNEL_TRANSPORT_LBTTCP)
91 #define LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_CLIENT | LBM_CHANNEL_TRANSPORT_LBTTCP)
92 #define LBM_CHANNEL_UNKNOWN_STREAM_TCP (LBM_CHANNEL_VALUE_UNKNOWN | LBM_CHANNEL_STREAM_TCP)
94 #define LBM_CHANNEL_TYPE(ch) ((uint8_t)(ch & LBM_CHANNEL_TYPE_MASK))
96 void lbm_channel_reset(void)
98 lbm_next_channel_value
= 1;
101 uint64_t lbm_channel_assign(uint8_t channel_type
)
104 uint64_t ch_counter
= lbm_next_channel_value
++;
106 if (lbm_next_channel_value
== LBM_CHANNEL_MAX_VALUE
)
108 lbm_next_channel_value
= 1;
110 ch
= ((uint64_t)((ch_counter
& LBM_CHANNEL_VALUE_LIMIT_MASK
) << LBM_CHANNEL_VALUE_SHIFT_COUNT
)) | channel_type
;
114 bool lbm_channel_is_transport(uint64_t channel
)
118 ch_type
= LBM_CHANNEL_TYPE(channel
);
121 case LBM_CHANNEL_TRANSPORT_LBTTCP
:
122 case LBM_CHANNEL_TRANSPORT_LBTRU
:
123 case LBM_CHANNEL_TRANSPORT_LBTRM
:
124 case LBM_CHANNEL_TRANSPORT_LBTIPC
:
125 case LBM_CHANNEL_TRANSPORT_LBTRDMA
:
126 case LBM_CHANNEL_TRANSPORT_LBTSMX
:
134 uint8_t lbm_channel_type(uint64_t channel
)
138 ch_type
= LBM_CHANNEL_TYPE(channel
);
142 uint64_t lbm_channel_assign_unknown_transport_source_lbttcp(void)
144 return (LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP
);
147 uint64_t lbm_channel_assign_unknown_transport_client_lbttcp(void)
149 return (LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP
);
152 uint64_t lbm_channel_assign_unknown_stream_tcp(void)
154 return (LBM_CHANNEL_UNKNOWN_STREAM_TCP
);
157 bool lbm_channel_is_unknown_transport_lbttcp(uint64_t channel
)
159 return (lbm_channel_is_unknown_transport_source_lbttcp(channel
) || lbm_channel_is_unknown_transport_client_lbttcp(channel
));
162 bool lbm_channel_is_unknown_transport_source_lbttcp(uint64_t channel
)
164 if (channel
== LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP
)
171 bool lbm_channel_is_unknown_transport_client_lbttcp(uint64_t channel
)
173 if (channel
== LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP
)
180 bool lbm_channel_is_unknown_stream_tcp(uint64_t channel
)
182 if (channel
== LBM_CHANNEL_UNKNOWN_STREAM_TCP
)
189 bool lbm_channel_is_known(uint64_t channel
)
191 return (!lbm_channel_is_unknown_transport_lbttcp(channel
) && !lbm_channel_is_unknown_stream_tcp(channel
));
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
)
199 lbm_transport_frame_t
* frame_entry
= NULL
;
201 /* Locate the frame. */
202 frame_entry
= (lbm_transport_frame_t
*) wmem_tree_lookup32(list
, frame
);
203 if (frame_entry
!= NULL
)
205 return (frame_entry
);
207 frame_entry
= wmem_new(wmem_file_scope(), lbm_transport_frame_t
);
208 frame_entry
->frame
= frame
;
209 frame_entry
->type
= type
;
210 frame_entry
->sqn
= sqn
;
211 frame_entry
->previous_frame
= 0;
212 frame_entry
->previous_type_frame
= 0;
213 frame_entry
->next_frame
= 0;
214 frame_entry
->next_type_frame
= 0;
215 frame_entry
->retransmission
= retransmission
;
216 frame_entry
->sqn_gap
= 0;
217 frame_entry
->ooo_gap
= 0;
218 frame_entry
->duplicate
= false;
219 wmem_tree_insert32(list
, frame
, (void *) frame_entry
);
220 return (frame_entry
);
223 lbm_transport_sqn_t
* lbm_transport_sqn_add(wmem_tree_t
* list
, lbm_transport_frame_t
* frame
)
225 lbm_transport_sqn_t
* sqn_entry
= NULL
;
226 lbm_transport_sqn_frame_t
* frame_entry
= NULL
;
228 /* Locate the SQN. */
229 sqn_entry
= (lbm_transport_sqn_t
*) wmem_tree_lookup32(list
, frame
->sqn
);
230 if (sqn_entry
== NULL
)
232 sqn_entry
= wmem_new(wmem_file_scope(), lbm_transport_sqn_t
);
233 sqn_entry
->sqn
= frame
->sqn
;
234 sqn_entry
->frame_count
= 0;
235 sqn_entry
->frame
= wmem_tree_new(wmem_file_scope());
236 wmem_tree_insert32(list
, frame
->sqn
, (void *) sqn_entry
);
238 /* Add this frame to the list of frames this SQN appears in. */
239 frame_entry
= wmem_new(wmem_file_scope(), lbm_transport_sqn_frame_t
);
240 frame_entry
->frame
= frame
->frame
;
241 frame_entry
->retransmission
= frame
->retransmission
;
242 wmem_tree_insert32(sqn_entry
->frame
, frame
->frame
, (void *) frame_entry
);
243 sqn_entry
->frame_count
++;
247 /*----------------------------------------------------------------------------*/
248 /* Topic interface. */
249 /*----------------------------------------------------------------------------*/
250 static wmem_tree_t
* lbm_topic_table
;
252 #define LBM_TOPIC_KEY_ELEMENT_COUNT 3
253 #define LBM_TOPIC_KEY_ELEMENT_CHANNEL_HIGH 0
254 #define LBM_TOPIC_KEY_ELEMENT_CHANNEL_LOW 1
255 #define LBM_TOPIC_KEY_ELEMENT_TOPIC_INDEX 2
257 struct lbm_topic_t_stct
;
258 typedef struct lbm_topic_t_stct lbm_topic_t
;
267 struct lbm_topic_t_stct
273 void lbm_topic_init(void)
275 lbm_topic_table
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
278 static void lbm_topic_build_key(uint32_t * key_value
, wmem_tree_key_t
* key
, uint64_t channel
, uint32_t topic_index
)
280 key_value
[LBM_TOPIC_KEY_ELEMENT_CHANNEL_HIGH
] = (uint32_t) ((channel
>> 32) & 0xffffffff);
281 key_value
[LBM_TOPIC_KEY_ELEMENT_CHANNEL_LOW
] = (uint32_t) (channel
& 0xffffffff);
282 key_value
[LBM_TOPIC_KEY_ELEMENT_TOPIC_INDEX
] = topic_index
;
283 key
[0].length
= LBM_TOPIC_KEY_ELEMENT_COUNT
;
284 key
[0].key
= key_value
;
289 static lbm_topic_t
* lbm_topic_locate(uint64_t channel
, uint32_t topic_index
)
291 lbm_topic_t
* entry
= NULL
;
292 uint32_t keyval
[LBM_TOPIC_KEY_ELEMENT_COUNT
];
293 wmem_tree_key_t tkey
[2];
295 lbm_topic_build_key(keyval
, tkey
, channel
, topic_index
);
296 entry
= (lbm_topic_t
*) wmem_tree_lookup32_array(lbm_topic_table
, tkey
);
300 const char * lbm_topic_find(uint64_t channel
, uint32_t topic_index
)
302 lbm_topic_t
* entry
= NULL
;
303 const char * topic
= NULL
;
305 entry
= lbm_topic_locate(channel
, topic_index
);
308 topic
= entry
->topic
;
313 void lbm_topic_add(uint64_t channel
, uint32_t topic_index
, const char * name
)
316 uint32_t keyval
[LBM_TOPIC_KEY_ELEMENT_COUNT
];
317 wmem_tree_key_t tkey
[2];
319 entry
= lbm_topic_locate(channel
, topic_index
);
324 entry
= wmem_new(wmem_file_scope(), lbm_topic_t
);
325 entry
->key
.channel
= channel
;
326 entry
->key
.topic_idx
= topic_index
;
327 entry
->key
.topic
= entry
;
328 entry
->topic
= wmem_strdup(wmem_file_scope(), name
);
329 lbm_topic_build_key(keyval
, tkey
, channel
, topic_index
);
330 wmem_tree_insert32_array(lbm_topic_table
, tkey
, (void *) entry
);
334 * Editor modelines - https://www.wireshark.org/tools/modelines.html
339 * indent-tabs-mode: nil
342 * vi: set shiftwidth=4 tabstop=8 expandtab:
343 * :indentSize=4:tabSize=8:noTabs=true: