checkAPIs.pl: support for new-style dissectors in check_hf_entries
[metze/wireshark/wip.git] / epan / dissectors / packet-lbm.c
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 "packet-lbm.h"
16
17 void proto_register_lbm(void);
18
19 /*----------------------------------------------------------------------------*/
20 /* Value translation tables.                                                  */
21 /*----------------------------------------------------------------------------*/
22
23 const true_false_string lbm_ignore_flag =
24 {
25     "May be ignored",
26     "Must be processed"
27 };
28
29 #define LBM_WILDCARD_PATTERN_TYPE_PCRE 1
30 #define LBM_WILDCARD_PATTERN_TYPE_REGEX 2
31
32 const value_string lbm_wildcard_pattern_type[] =
33 {
34     { LBM_WILDCARD_PATTERN_TYPE_PCRE, "Perl Compatible Regular Expression (PCRE)" },
35     { LBM_WILDCARD_PATTERN_TYPE_REGEX, "POSIX Extended Regular Expression (REGEX)" },
36     { 0x0, NULL }
37 };
38
39 const value_string lbm_wildcard_pattern_type_short[] =
40 {
41     { LBM_WILDCARD_PATTERN_TYPE_PCRE, "PCRE" },
42     { LBM_WILDCARD_PATTERN_TYPE_REGEX, "REGEX" },
43     { 0x0, NULL }
44 };
45
46 /* Initialization function, called whenever Wireshark loads a new capture, etc. */
47 static void lbm_init(void)
48 {
49     lbm_channel_reset();
50 }
51
52 /* Register all the bits needed with the filtering engine */
53 void proto_register_lbm(void)
54 {
55     register_init_routine(lbm_init);
56 }
57
58 /*----------------------------------------------------------------------------*/
59 /* Channel interface.                                                         */
60 /*----------------------------------------------------------------------------*/
61 /*
62   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
63   stream or transport session. The actual channel value consists of:
64   - The lower 52 bits of the counter, shifted left 12 bits
65   - A 4-bit source/client classification (for unicast channels), shifted left 8 bits
66   - An 8-bit channel type
67
68    6                                                                                                     1 1     0 0             0
69    3                                                                                                     2 1     8 7             0
70   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71   |                                    Counter                                                            |  S/C  |     Type      |
72   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73
74   The counter wraps at 0x000ffffffffffffe, and is reset to 1 whenever Wireshark invokes any init routines registered via
75   register_init_routine() (the call to lbm_channel_reset() is in packet-lbm.c).
76
77   Special values are used as placeholders to indicate an as-yet-unknown transport or stream TCP channel.
78 */
79
80 static guint64 lbm_next_channel_value = 1;
81
82 #define LBM_CHANNEL_TYPE_MASK G_GUINT64_CONSTANT(0x00000000000000ff)
83 #define LBM_CHANNEL_VALUE_LIMIT_MASK G_GUINT64_CONSTANT(0x000ffffffffffffff)
84 #define LBM_CHANNEL_MAX_VALUE G_GUINT64_CONSTANT(0x000ffffffffffffe)
85
86 #define LBM_CHANNEL_VALUE_UNKNOWN G_GUINT64_CONSTANT(0xfffffffffffff000)
87 #define LBM_CHANNEL_VALUE_UNKNOWN_SOURCE G_GUINT64_CONSTANT(0xfffffffffffff100)
88 #define LBM_CHANNEL_VALUE_UNKNOWN_CLIENT G_GUINT64_CONSTANT(0xfffffffffffff200)
89 #define LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_SOURCE | LBM_CHANNEL_TRANSPORT_LBTTCP)
90 #define LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_CLIENT | LBM_CHANNEL_TRANSPORT_LBTTCP)
91 #define LBM_CHANNEL_UNKNOWN_STREAM_TCP (LBM_CHANNEL_VALUE_UNKNOWN | LBM_CHANNEL_STREAM_TCP)
92
93 #define LBM_CHANNEL_TYPE(ch) ((guint8)(ch & LBM_CHANNEL_TYPE_MASK))
94
95 void lbm_channel_reset(void)
96 {
97     lbm_next_channel_value = 1;
98 }
99
100 guint64 lbm_channel_assign(guint8 channel_type)
101 {
102     guint64 ch;
103     guint64 ch_counter = lbm_next_channel_value++;
104
105     if (lbm_next_channel_value == LBM_CHANNEL_MAX_VALUE)
106     {
107         lbm_next_channel_value = 1;
108     }
109     ch = ((guint64)((ch_counter & LBM_CHANNEL_VALUE_LIMIT_MASK) << LBM_CHANNEL_VALUE_SHIFT_COUNT)) | channel_type;
110     return (ch);
111 }
112
113 gboolean lbm_channel_is_transport(guint64 channel)
114 {
115     guint8 ch_type;
116
117     ch_type = LBM_CHANNEL_TYPE(channel);
118     switch (ch_type)
119     {
120         case LBM_CHANNEL_TRANSPORT_LBTTCP:
121         case LBM_CHANNEL_TRANSPORT_LBTRU:
122         case LBM_CHANNEL_TRANSPORT_LBTRM:
123         case LBM_CHANNEL_TRANSPORT_LBTIPC:
124         case LBM_CHANNEL_TRANSPORT_LBTRDMA:
125         case LBM_CHANNEL_TRANSPORT_LBTSMX:
126             return (TRUE);
127             break;
128         default:
129             break;
130     }
131     return (FALSE);
132 }
133
134 guint8 lbm_channel_type(guint64 channel)
135 {
136     guint8 ch_type;
137
138     ch_type = LBM_CHANNEL_TYPE(channel);
139     return (ch_type);
140 }
141
142 guint64 lbm_channel_assign_unknown_transport_source_lbttcp(void)
143 {
144     return (LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP);
145 }
146
147 guint64 lbm_channel_assign_unknown_transport_client_lbttcp(void)
148 {
149     return (LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP);
150 }
151
152 guint64 lbm_channel_assign_unknown_stream_tcp(void)
153 {
154     return (LBM_CHANNEL_UNKNOWN_STREAM_TCP);
155 }
156
157 gboolean lbm_channel_is_unknown_transport_lbttcp(guint64 channel)
158 {
159     return (lbm_channel_is_unknown_transport_source_lbttcp(channel) || lbm_channel_is_unknown_transport_client_lbttcp(channel));
160 }
161
162 gboolean lbm_channel_is_unknown_transport_source_lbttcp(guint64 channel)
163 {
164     if (channel == LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP)
165     {
166         return (TRUE);
167     }
168     return (FALSE);
169 }
170
171 gboolean lbm_channel_is_unknown_transport_client_lbttcp(guint64 channel)
172 {
173     if (channel == LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP)
174     {
175         return (TRUE);
176     }
177     return (FALSE);
178 }
179
180 gboolean lbm_channel_is_unknown_stream_tcp(guint64 channel)
181 {
182     if (channel == LBM_CHANNEL_UNKNOWN_STREAM_TCP)
183     {
184         return (TRUE);
185     }
186     return (FALSE);
187 }
188
189 gboolean lbm_channel_is_known(guint64 channel)
190 {
191     return (!lbm_channel_is_unknown_transport_lbttcp(channel) && !lbm_channel_is_unknown_stream_tcp(channel));
192 }
193
194 /*----------------------------------------------------------------------------*/
195 /* Frame/SQN interface.                                                       */
196 /*----------------------------------------------------------------------------*/
197 lbm_transport_frame_t * lbm_transport_frame_add(wmem_tree_t * list, guint8 type, guint32 frame, guint32 sqn, gboolean retransmission)
198 {
199     lbm_transport_frame_t * frame_entry = NULL;
200
201     /* Locate the frame. */
202     frame_entry = (lbm_transport_frame_t *) wmem_tree_lookup32(list, frame);
203     if (frame_entry != NULL)
204     {
205         return (frame_entry);
206     }
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);
221 }
222
223 lbm_transport_sqn_t * lbm_transport_sqn_add(wmem_tree_t * list, lbm_transport_frame_t * frame)
224 {
225     lbm_transport_sqn_t * sqn_entry = NULL;
226     lbm_transport_sqn_frame_t * frame_entry = NULL;
227
228     /* Locate the SQN. */
229     sqn_entry = (lbm_transport_sqn_t *) wmem_tree_lookup32(list, frame->sqn);
230     if (sqn_entry == NULL)
231     {
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);
237     }
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++;
244     return (sqn_entry);
245 }
246
247 /*----------------------------------------------------------------------------*/
248 /* Topic interface.                                                           */
249 /*----------------------------------------------------------------------------*/
250 static wmem_tree_t * lbm_topic_table = NULL;
251
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
256
257 struct lbm_topic_t_stct;
258 typedef struct lbm_topic_t_stct lbm_topic_t;
259
260 typedef struct
261 {
262     guint64 channel;
263     guint32 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 {
275     lbm_topic_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
276 }
277
278 static void lbm_topic_build_key(guint32 * key_value, wmem_tree_key_t * key, guint64 channel, guint32 topic_index)
279 {
280     key_value[LBM_TOPIC_KEY_ELEMENT_CHANNEL_HIGH] = (guint32) ((channel >> 32) & 0xffffffff);
281     key_value[LBM_TOPIC_KEY_ELEMENT_CHANNEL_LOW] = (guint32) (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;
285     key[1].length = 0;
286     key[1].key = NULL;
287 }
288
289 static lbm_topic_t * lbm_topic_locate(guint64 channel, guint32 topic_index)
290 {
291     lbm_topic_t * entry = NULL;
292     guint32 keyval[LBM_TOPIC_KEY_ELEMENT_COUNT];
293     wmem_tree_key_t tkey[2];
294
295     lbm_topic_build_key(keyval, tkey, channel, topic_index);
296     entry = (lbm_topic_t *) wmem_tree_lookup32_array(lbm_topic_table, tkey);
297     return (entry);
298 }
299
300 const char * lbm_topic_find(guint64 channel, guint32 topic_index)
301 {
302     lbm_topic_t * entry = NULL;
303     const char * topic = NULL;
304
305     entry = lbm_topic_locate(channel, topic_index);
306     if (entry != NULL)
307     {
308         topic = entry->topic;
309     }
310     return (topic);
311 }
312
313 void lbm_topic_add(guint64 channel, guint32 topic_index, const char * name)
314 {
315     lbm_topic_t * entry;
316     guint32 keyval[LBM_TOPIC_KEY_ELEMENT_COUNT];
317     wmem_tree_key_t tkey[2];
318
319     entry = lbm_topic_locate(channel, topic_index);
320     if (entry != NULL)
321     {
322         return;
323     }
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);
331 }
332
333 /*
334  * Editor modelines  -  http://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  */