/src/wireshark/epan/dissectors/packet-lbttcp.c
Line | Count | Source |
1 | | /* packet-lbttcp.c |
2 | | * Routines for LBM TCP 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 | | |
15 | | #include <epan/packet.h> |
16 | | #include <epan/prefs.h> |
17 | | #include <epan/uat.h> |
18 | | #include <epan/to_str.h> |
19 | | #include "packet-tcp.h" |
20 | | #include "packet-lbm.h" |
21 | | #include "packet-lbttcp.h" |
22 | | |
23 | | void proto_register_lbttcp(void); |
24 | | void proto_reg_handoff_lbttcp(void); |
25 | | |
26 | | /* Protocol handle */ |
27 | | static int proto_lbttcp; |
28 | | |
29 | | /* Dissector handle */ |
30 | | static dissector_handle_t lbttcp_dissector_handle; |
31 | | |
32 | | /*----------------------------------------------------------------------------*/ |
33 | | /* LBT-TCP protocol management. */ |
34 | | /*----------------------------------------------------------------------------*/ |
35 | | |
36 | | typedef struct |
37 | | { |
38 | | wmem_tree_t * frame_tree; |
39 | | wmem_tree_t * session_tree; |
40 | | } lbttcp_transport_conv_data_t; |
41 | | |
42 | | static const address lbttcp_null_address = ADDRESS_INIT_NONE; |
43 | | |
44 | | lbttcp_transport_t * lbttcp_transport_find(const address * source_address, uint16_t source_port, uint32_t session_id, uint32_t frame) |
45 | 28 | { |
46 | 28 | lbttcp_transport_t * entry = NULL; |
47 | 28 | conversation_t * conv = NULL; |
48 | 28 | lbttcp_transport_conv_data_t * conv_data = NULL; |
49 | | |
50 | 28 | conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0); |
51 | 28 | if (conv != NULL) |
52 | 0 | { |
53 | 0 | conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); |
54 | 0 | if (conv_data != NULL) |
55 | 0 | { |
56 | 0 | entry = (lbttcp_transport_t *) wmem_tree_lookup32(conv_data->session_tree, session_id); |
57 | 0 | } |
58 | 0 | } |
59 | 28 | return (entry); |
60 | 28 | } |
61 | | |
62 | | static lbttcp_transport_t * lbttcp_transport_create(const address * source_address, uint16_t source_port, uint32_t session_id) |
63 | 0 | { |
64 | 0 | lbttcp_transport_t * transport = NULL; |
65 | |
|
66 | 0 | transport = wmem_new(wmem_file_scope(), lbttcp_transport_t); |
67 | 0 | copy_address_wmem(wmem_file_scope(), &(transport->source_address), source_address); |
68 | 0 | transport->source_port = source_port; |
69 | 0 | transport->session_id = session_id; |
70 | 0 | transport->channel = lbm_channel_assign(LBM_CHANNEL_TRANSPORT_LBTTCP); |
71 | 0 | transport->next_client_id = 1; |
72 | 0 | transport->client_list = wmem_list_new(wmem_file_scope()); |
73 | 0 | return (transport); |
74 | 0 | } |
75 | | |
76 | | lbttcp_transport_t * lbttcp_transport_add(const address * source_address, uint16_t source_port, uint32_t session_id, uint32_t frame) |
77 | 0 | { |
78 | 0 | lbttcp_transport_t * entry = NULL; |
79 | 0 | conversation_t * conv = NULL; |
80 | 0 | lbttcp_transport_conv_data_t * conv_data = NULL; |
81 | |
|
82 | 0 | conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0); |
83 | 0 | if (conv == NULL) |
84 | 0 | { |
85 | 0 | conv = conversation_new(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0); |
86 | 0 | } |
87 | 0 | conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); |
88 | 0 | if (conv_data == NULL) |
89 | 0 | { |
90 | 0 | conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t); |
91 | 0 | conv_data->frame_tree = wmem_tree_new(wmem_file_scope()); |
92 | 0 | conv_data->session_tree = wmem_tree_new(wmem_file_scope()); |
93 | 0 | conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data); |
94 | 0 | } |
95 | 0 | entry = (lbttcp_transport_t *) wmem_tree_lookup32(conv_data->session_tree, session_id); |
96 | 0 | if (entry != NULL) |
97 | 0 | { |
98 | 0 | return (entry); |
99 | 0 | } |
100 | 0 | entry = lbttcp_transport_create(source_address, source_port, session_id); |
101 | 0 | wmem_tree_insert32(conv_data->session_tree, session_id, (void *) entry); |
102 | 0 | wmem_tree_insert32(conv_data->frame_tree, frame, (void *) entry); |
103 | 0 | return (entry); |
104 | 0 | } |
105 | | |
106 | | static lbttcp_client_transport_t * lbttcp_client_transport_find(lbttcp_transport_t * transport, const address * receiver_address, uint16_t receiver_port, uint32_t frame) |
107 | 0 | { |
108 | 0 | lbttcp_client_transport_t * entry = NULL; |
109 | 0 | conversation_t * client_conv = NULL; |
110 | |
|
111 | 0 | if (transport == NULL) |
112 | 0 | { |
113 | 0 | return (NULL); |
114 | 0 | } |
115 | 0 | client_conv = find_conversation(frame, &(transport->source_address), receiver_address, CONVERSATION_TCP, transport->source_port, receiver_port, 0); |
116 | 0 | if (client_conv != NULL) |
117 | 0 | { |
118 | 0 | wmem_tree_t * session_tree = NULL; |
119 | |
|
120 | 0 | session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbttcp); |
121 | 0 | if (session_tree != NULL) |
122 | 0 | { |
123 | 0 | entry = (lbttcp_client_transport_t *) wmem_tree_lookup32(session_tree, transport->session_id); |
124 | 0 | } |
125 | 0 | } |
126 | 0 | return (entry); |
127 | 0 | } |
128 | | |
129 | | static lbttcp_client_transport_t * lbttcp_client_transport_add(lbttcp_transport_t * transport, const address * receiver_address, uint16_t receiver_port, uint32_t frame) |
130 | 0 | { |
131 | 0 | lbttcp_client_transport_t * entry; |
132 | 0 | conversation_t * client_conv = NULL; |
133 | 0 | wmem_tree_t * session_tree = NULL; |
134 | |
|
135 | 0 | if (transport == NULL) |
136 | 0 | { |
137 | 0 | return (NULL); |
138 | 0 | } |
139 | 0 | entry = lbttcp_client_transport_find(transport, receiver_address, receiver_port, frame); |
140 | 0 | if (entry != NULL) |
141 | 0 | { |
142 | 0 | return (entry); |
143 | 0 | } |
144 | 0 | entry = wmem_new(wmem_file_scope(), lbttcp_client_transport_t); |
145 | 0 | copy_address_wmem(wmem_file_scope(), &(entry->receiver_address), receiver_address); |
146 | 0 | entry->receiver_port = receiver_port; |
147 | 0 | entry->id = transport->next_client_id++; |
148 | | |
149 | | /* See if a conversation for this address/port pair exists. */ |
150 | 0 | client_conv = find_conversation(frame, &(transport->source_address), receiver_address, CONVERSATION_TCP, transport->source_port, receiver_port, 0); |
151 | 0 | if (client_conv == NULL) |
152 | 0 | { |
153 | 0 | client_conv = conversation_new(frame, &(transport->source_address), receiver_address, CONVERSATION_TCP, transport->source_port, receiver_port, 0); |
154 | 0 | session_tree = wmem_tree_new(wmem_file_scope()); |
155 | 0 | conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree); |
156 | 0 | } |
157 | 0 | session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbttcp); |
158 | 0 | if (session_tree == NULL) |
159 | 0 | { |
160 | 0 | session_tree = wmem_tree_new(wmem_file_scope()); |
161 | 0 | conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree); |
162 | 0 | } |
163 | 0 | wmem_tree_insert32(session_tree, transport->session_id, (void *) entry); |
164 | | |
165 | | /* Add this client to the transport. */ |
166 | 0 | wmem_list_append(transport->client_list, (void *) entry); |
167 | 0 | return (entry); |
168 | 0 | } |
169 | | |
170 | | char * lbttcp_transport_source_string(wmem_allocator_t* allocator, const address * source_address, uint16_t source_port, uint32_t session_id) |
171 | 0 | { |
172 | 0 | char * bufptr = NULL; |
173 | |
|
174 | 0 | if (session_id == 0) |
175 | 0 | { |
176 | 0 | bufptr = wmem_strdup_printf(allocator, "TCP:%s:%" PRIu16, address_to_str(allocator, source_address), source_port); |
177 | 0 | } |
178 | 0 | else |
179 | 0 | { |
180 | 0 | bufptr = wmem_strdup_printf(allocator, "TCP:%s:%" PRIu16 ":%08x", address_to_str(allocator, source_address), source_port, session_id); |
181 | 0 | } |
182 | 0 | return (bufptr); |
183 | 0 | } |
184 | | |
185 | | bool lbttcp_transport_sid_find(const address * source_address, uint16_t source_port, uint32_t frame, uint32_t * session_id) |
186 | 49 | { |
187 | 49 | conversation_t * conv = NULL; |
188 | 49 | lbttcp_transport_conv_data_t * conv_data = NULL; |
189 | 49 | lbttcp_transport_t * transport = NULL; |
190 | | |
191 | 49 | conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0); |
192 | 49 | if (conv == NULL) |
193 | 49 | { |
194 | 49 | return false; |
195 | 49 | } |
196 | 0 | conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); |
197 | 0 | if (conv_data == NULL) |
198 | 0 | { |
199 | 0 | return false; |
200 | 0 | } |
201 | 0 | if (conv_data->frame_tree == NULL) |
202 | 0 | { |
203 | 0 | return false; |
204 | 0 | } |
205 | 0 | transport = (lbttcp_transport_t *)wmem_tree_lookup32_le(conv_data->frame_tree, frame); |
206 | 0 | if (transport == NULL) |
207 | 0 | { |
208 | 0 | return false; |
209 | 0 | } |
210 | 0 | *session_id = transport->session_id; |
211 | 0 | return true; |
212 | 0 | } |
213 | | |
214 | | void lbttcp_transport_sid_add(const address * source_address, uint16_t source_port, uint32_t frame, uint32_t session_id) |
215 | 0 | { |
216 | 0 | conversation_t * conv = NULL; |
217 | 0 | lbttcp_transport_conv_data_t * conv_data = NULL; |
218 | 0 | lbttcp_transport_t * transport = NULL; |
219 | |
|
220 | 0 | conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0); |
221 | 0 | if (conv == NULL) |
222 | 0 | { |
223 | 0 | conv = conversation_new(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0); |
224 | 0 | } |
225 | 0 | conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp); |
226 | 0 | if (conv_data == NULL) |
227 | 0 | { |
228 | 0 | conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t); |
229 | 0 | conv_data->frame_tree = wmem_tree_new(wmem_file_scope()); |
230 | 0 | conv_data->session_tree = wmem_tree_new(wmem_file_scope()); |
231 | 0 | conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data); |
232 | 0 | } |
233 | | /* Lookup by frame */ |
234 | 0 | transport = (lbttcp_transport_t *) wmem_tree_lookup32_le(conv_data->frame_tree, frame); |
235 | 0 | if (transport != NULL) |
236 | 0 | { |
237 | 0 | if (transport->session_id != session_id) |
238 | 0 | { |
239 | 0 | transport = NULL; |
240 | 0 | } |
241 | 0 | } |
242 | 0 | if (transport == NULL) |
243 | 0 | { |
244 | 0 | transport = lbttcp_transport_create(source_address, source_port, session_id); |
245 | 0 | wmem_tree_insert32(conv_data->session_tree, session_id, (void *) transport); |
246 | 0 | wmem_tree_insert32(conv_data->frame_tree, frame, (void *) transport); |
247 | 0 | } |
248 | 0 | } |
249 | | |
250 | | /*----------------------------------------------------------------------------*/ |
251 | | /* Preferences. */ |
252 | | /*----------------------------------------------------------------------------*/ |
253 | | |
254 | | /* Preferences default values. */ |
255 | | #define LBTTCP_DEFAULT_SOURCE_PORT_LOW 14371 |
256 | | #define LBTTCP_DEFAULT_SOURCE_PORT_HIGH 14390 |
257 | | #define LBTTCP_DEFAULT_REQUEST_PORT_LOW 14391 |
258 | | #define LBTTCP_DEFAULT_REQUEST_PORT_HIGH 14395 |
259 | | #define LBTTCP_DEFAULT_STORE_PORT_LOW 0 |
260 | | #define LBTTCP_DEFAULT_STORE_PORT_HIGH 0 |
261 | | |
262 | | /* Global preferences variables (altered by the preferences dialog). */ |
263 | | static uint32_t global_lbttcp_source_port_low = LBTTCP_DEFAULT_SOURCE_PORT_LOW; |
264 | | static uint32_t global_lbttcp_source_port_high = LBTTCP_DEFAULT_SOURCE_PORT_HIGH; |
265 | | static uint32_t global_lbttcp_request_port_low = LBTTCP_DEFAULT_REQUEST_PORT_LOW; |
266 | | static uint32_t global_lbttcp_request_port_high = LBTTCP_DEFAULT_REQUEST_PORT_HIGH; |
267 | | static uint32_t global_lbttcp_store_port_low = LBTTCP_DEFAULT_STORE_PORT_LOW; |
268 | | static uint32_t global_lbttcp_store_port_high = LBTTCP_DEFAULT_STORE_PORT_HIGH; |
269 | | static bool global_lbttcp_use_tag; |
270 | | |
271 | | /* Local preferences variables (used by the dissector). */ |
272 | | static uint32_t lbttcp_source_port_low = LBTTCP_DEFAULT_SOURCE_PORT_LOW; |
273 | | static uint32_t lbttcp_source_port_high = LBTTCP_DEFAULT_SOURCE_PORT_HIGH; |
274 | | static uint32_t lbttcp_request_port_low = LBTTCP_DEFAULT_REQUEST_PORT_LOW; |
275 | | static uint32_t lbttcp_request_port_high = LBTTCP_DEFAULT_REQUEST_PORT_HIGH; |
276 | | static uint32_t lbttcp_store_port_low = LBTTCP_DEFAULT_STORE_PORT_LOW; |
277 | | static uint32_t lbttcp_store_port_high = LBTTCP_DEFAULT_STORE_PORT_HIGH; |
278 | | static bool lbttcp_use_tag; |
279 | | |
280 | | /* Tag definitions. */ |
281 | | typedef struct |
282 | | { |
283 | | char * name; |
284 | | uint32_t source_port_low; |
285 | | uint32_t source_port_high; |
286 | | uint32_t request_port_low; |
287 | | uint32_t request_port_high; |
288 | | uint32_t store_port_low; |
289 | | uint32_t store_port_high; |
290 | | } lbttcp_tag_entry_t; |
291 | | |
292 | | static lbttcp_tag_entry_t * lbttcp_tag_entry; |
293 | | static unsigned lbttcp_tag_count; |
294 | | |
295 | 0 | UAT_CSTRING_CB_DEF(lbttcp_tag, name, lbttcp_tag_entry_t) |
296 | 0 | UAT_DEC_CB_DEF(lbttcp_tag, source_port_low, lbttcp_tag_entry_t) Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_low_set_cb Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_low_tostr_cb |
297 | 0 | UAT_DEC_CB_DEF(lbttcp_tag, source_port_high, lbttcp_tag_entry_t) Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_high_set_cb Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_high_tostr_cb |
298 | 0 | UAT_DEC_CB_DEF(lbttcp_tag, request_port_low, lbttcp_tag_entry_t) Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_low_set_cb Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_low_tostr_cb |
299 | 0 | UAT_DEC_CB_DEF(lbttcp_tag, request_port_high, lbttcp_tag_entry_t) Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_high_set_cb Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_high_tostr_cb |
300 | 0 | UAT_DEC_CB_DEF(lbttcp_tag, store_port_low, lbttcp_tag_entry_t) Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_low_set_cb Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_low_tostr_cb |
301 | 0 | UAT_DEC_CB_DEF(lbttcp_tag, store_port_high, lbttcp_tag_entry_t) Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_high_set_cb Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_high_tostr_cb |
302 | | static uat_field_t lbttcp_tag_array[] = |
303 | | { |
304 | | UAT_FLD_CSTRING(lbttcp_tag, name, "Tag name", "Tag name"), |
305 | | UAT_FLD_DEC(lbttcp_tag, source_port_low, "Source port low", "Source port low"), |
306 | | UAT_FLD_DEC(lbttcp_tag, source_port_high, "Source port high", "Source port high"), |
307 | | UAT_FLD_DEC(lbttcp_tag, request_port_low, "Request port low", "Request port low"), |
308 | | UAT_FLD_DEC(lbttcp_tag, request_port_high, "Request port high", "Request port high"), |
309 | | UAT_FLD_DEC(lbttcp_tag, store_port_low, "Store port low", "Store port low"), |
310 | | UAT_FLD_DEC(lbttcp_tag, store_port_high, "Store port high", "Store port high"), |
311 | | UAT_END_FIELDS |
312 | | }; |
313 | | |
314 | | /*----------------------------------------------------------------------------*/ |
315 | | /* UAT callback functions. */ |
316 | | /*----------------------------------------------------------------------------*/ |
317 | | static bool lbttcp_tag_update_cb(void * record, char * * error_string) |
318 | 0 | { |
319 | 0 | lbttcp_tag_entry_t * tag = (lbttcp_tag_entry_t *)record; |
320 | |
|
321 | 0 | if (tag->name == NULL) |
322 | 0 | { |
323 | 0 | *error_string = g_strdup("Tag name can't be empty"); |
324 | 0 | return false; |
325 | 0 | } |
326 | 0 | else |
327 | 0 | { |
328 | 0 | g_strstrip(tag->name); |
329 | 0 | if (tag->name[0] == 0) |
330 | 0 | { |
331 | 0 | *error_string = g_strdup("Tag name can't be empty"); |
332 | 0 | return false; |
333 | 0 | } |
334 | 0 | } |
335 | 0 | return true; |
336 | 0 | } |
337 | | |
338 | | static void * lbttcp_tag_copy_cb(void * destination, const void * source, size_t length _U_) |
339 | 0 | { |
340 | 0 | const lbttcp_tag_entry_t * src = (const lbttcp_tag_entry_t *)source; |
341 | 0 | lbttcp_tag_entry_t * dest = (lbttcp_tag_entry_t *)destination; |
342 | |
|
343 | 0 | dest->name = g_strdup(src->name); |
344 | 0 | dest->source_port_low = src->source_port_low; |
345 | 0 | dest->source_port_high = src->source_port_high; |
346 | 0 | dest->request_port_low = src->request_port_low; |
347 | 0 | dest->request_port_high = src->request_port_high; |
348 | 0 | dest->store_port_low = src->store_port_low; |
349 | 0 | dest->store_port_high = src->store_port_high; |
350 | 0 | return (dest); |
351 | 0 | } |
352 | | |
353 | | static void lbttcp_tag_free_cb(void * record) |
354 | 0 | { |
355 | 0 | lbttcp_tag_entry_t * tag = (lbttcp_tag_entry_t *)record; |
356 | |
|
357 | 0 | if (tag->name != NULL) |
358 | 0 | { |
359 | 0 | g_free(tag->name); |
360 | 0 | tag->name = NULL; |
361 | 0 | } |
362 | 0 | } |
363 | | |
364 | | static const lbttcp_tag_entry_t * lbttcp_tag_locate(packet_info * pinfo) |
365 | 0 | { |
366 | 0 | unsigned idx; |
367 | 0 | const lbttcp_tag_entry_t * tag = NULL; |
368 | |
|
369 | 0 | if (!lbttcp_use_tag) |
370 | 0 | { |
371 | 0 | return (NULL); |
372 | 0 | } |
373 | | |
374 | 0 | for (idx = 0; idx < lbttcp_tag_count; ++idx) |
375 | 0 | { |
376 | 0 | tag = &(lbttcp_tag_entry[idx]); |
377 | 0 | if (((pinfo->srcport >= tag->source_port_low) && (pinfo->srcport <= tag->source_port_high)) |
378 | 0 | || ((pinfo->destport >= tag->source_port_low) && (pinfo->destport <= tag->source_port_high)) |
379 | 0 | || ((pinfo->srcport >= tag->request_port_low) && (pinfo->srcport <= tag->request_port_high)) |
380 | 0 | || ((pinfo->destport >= tag->request_port_low) && (pinfo->destport <= tag->request_port_high)) |
381 | 0 | || ((pinfo->srcport >= tag->store_port_low) && (pinfo->srcport <= tag->store_port_high)) |
382 | 0 | || ((pinfo->destport >= tag->store_port_low) && (pinfo->destport <= tag->store_port_high))) |
383 | 0 | { |
384 | 0 | return (tag); |
385 | 0 | } |
386 | 0 | } |
387 | 0 | return (NULL); |
388 | 0 | } |
389 | | |
390 | | static char * lbttcp_tag_find(packet_info * pinfo) |
391 | 0 | { |
392 | 0 | const lbttcp_tag_entry_t * tag = NULL; |
393 | |
|
394 | 0 | if (!lbttcp_use_tag) |
395 | 0 | { |
396 | 0 | return (NULL); |
397 | 0 | } |
398 | | |
399 | 0 | tag = lbttcp_tag_locate(pinfo); |
400 | 0 | if (tag != NULL) |
401 | 0 | { |
402 | 0 | return tag->name; |
403 | 0 | } |
404 | 0 | return (NULL); |
405 | 0 | } |
406 | | |
407 | | /*----------------------------------------------------------------------------*/ |
408 | | /* Handles of all types. */ |
409 | | /*----------------------------------------------------------------------------*/ |
410 | | |
411 | | /* Dissector tree handles */ |
412 | | static int ett_lbttcp; |
413 | | static int ett_lbttcp_channel; |
414 | | |
415 | | /* Dissector field handles */ |
416 | | static int hf_lbttcp_tag; |
417 | | static int hf_lbttcp_channel; |
418 | | static int hf_lbttcp_channel_id; |
419 | | static int hf_lbttcp_channel_client; |
420 | | |
421 | | static bool lbttcp_packet_is_transport_source(packet_info * pinfo, const lbttcp_tag_entry_t * tag) |
422 | 798 | { |
423 | 798 | bool is_transport_source_packet = false; |
424 | | |
425 | 798 | if (tag == NULL) |
426 | 798 | { |
427 | 798 | if ((pinfo->srcport >= lbttcp_source_port_low) && (pinfo->srcport <= lbttcp_source_port_high)) |
428 | 14 | { |
429 | 14 | is_transport_source_packet = true; |
430 | 14 | } |
431 | 798 | } |
432 | 0 | else |
433 | 0 | { |
434 | 0 | if ((pinfo->srcport >= tag->source_port_low) && (pinfo->srcport <= tag->source_port_high)) |
435 | 0 | { |
436 | 0 | is_transport_source_packet = true; |
437 | 0 | } |
438 | 0 | } |
439 | 798 | return (is_transport_source_packet); |
440 | 798 | } |
441 | | |
442 | | static bool lbttcp_packet_is_transport_client(packet_info * pinfo, const lbttcp_tag_entry_t * tag) |
443 | 784 | { |
444 | 784 | bool is_transport_client_packet = false; |
445 | | |
446 | 784 | if (tag == NULL) |
447 | 784 | { |
448 | 784 | if ((pinfo->destport >= lbttcp_source_port_low) && (pinfo->destport <= lbttcp_source_port_high)) |
449 | 14 | { |
450 | 14 | is_transport_client_packet = true; |
451 | 14 | } |
452 | 784 | } |
453 | 0 | else |
454 | 0 | { |
455 | 0 | if ((pinfo->destport >= tag->source_port_low) && (pinfo->destport <= tag->source_port_high)) |
456 | 0 | { |
457 | 0 | is_transport_client_packet = true; |
458 | 0 | } |
459 | 0 | } |
460 | 784 | return (is_transport_client_packet); |
461 | 784 | } |
462 | | |
463 | | static unsigned get_lbttcp_pdu_length(packet_info * pinfo _U_, tvbuff_t * tvb, |
464 | | int offset, void *data _U_) |
465 | 808 | { |
466 | 808 | return lbmc_get_message_length(tvb, offset); |
467 | 808 | } |
468 | | |
469 | | static int dissect_lbttcp_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * dissector_data _U_) |
470 | 798 | { |
471 | 798 | proto_tree * lbttcp_tree = NULL; |
472 | 798 | proto_item * ti = NULL; |
473 | 798 | char * tag_name = NULL; |
474 | 798 | int len_dissected; |
475 | 798 | const lbttcp_tag_entry_t * tag = NULL; |
476 | 798 | uint64_t channel = LBM_CHANNEL_NO_CHANNEL; |
477 | 798 | uint32_t client_id = 0; |
478 | 798 | bool from_source = false; |
479 | 798 | bool transport_packet = false; |
480 | | |
481 | 798 | if (lbttcp_use_tag) |
482 | 0 | { |
483 | 0 | tag = lbttcp_tag_locate(pinfo); |
484 | 0 | tag_name = lbttcp_tag_find(pinfo); |
485 | 0 | } |
486 | 798 | if (tag_name != NULL) |
487 | 0 | { |
488 | 0 | ti = proto_tree_add_protocol_format(tree, proto_lbttcp, tvb, 0, -1, "LBT-TCP Protocol (Tag: %s)", tag_name); |
489 | 0 | } |
490 | 798 | else |
491 | 798 | { |
492 | 798 | ti = proto_tree_add_protocol_format(tree, proto_lbttcp, tvb, 0, -1, "LBT-TCP Protocol"); |
493 | 798 | } |
494 | 798 | lbttcp_tree = proto_item_add_subtree(ti, ett_lbttcp); |
495 | 798 | if (tag_name != NULL) |
496 | 0 | { |
497 | 0 | proto_item * item = NULL; |
498 | |
|
499 | 0 | item = proto_tree_add_string(lbttcp_tree, hf_lbttcp_tag, tvb, 0, 0, tag_name); |
500 | 0 | proto_item_set_generated(item); |
501 | 0 | } |
502 | 798 | if (lbttcp_packet_is_transport_source(pinfo, tag)) |
503 | 14 | { |
504 | 14 | from_source = true; |
505 | 14 | transport_packet = true; |
506 | 14 | } |
507 | 784 | else if (lbttcp_packet_is_transport_client(pinfo, tag)) |
508 | 14 | { |
509 | 14 | from_source = false; |
510 | 14 | transport_packet = true; |
511 | 14 | } |
512 | 798 | if (transport_packet) |
513 | 28 | { |
514 | 28 | address source_address; |
515 | 28 | address client_address; |
516 | 28 | uint16_t srcport; |
517 | 28 | uint16_t clntport; |
518 | 28 | uint32_t sid = 0; |
519 | 28 | lbttcp_transport_t * transport = NULL; |
520 | 28 | lbttcp_client_transport_t * client = NULL; |
521 | | |
522 | 28 | if (from_source) |
523 | 14 | { |
524 | 14 | copy_address_shallow(&source_address, &(pinfo->src)); |
525 | 14 | srcport = pinfo->srcport; |
526 | 14 | copy_address_shallow(&client_address, &(pinfo->dst)); |
527 | 14 | clntport = pinfo->destport; |
528 | 14 | } |
529 | 14 | else |
530 | 14 | { |
531 | 14 | copy_address_shallow(&source_address, &(pinfo->dst)); |
532 | 14 | srcport = pinfo->destport; |
533 | 14 | copy_address_shallow(&client_address, &(pinfo->src)); |
534 | 14 | clntport = pinfo->srcport; |
535 | 14 | } |
536 | | /* See if we have a matching transport with no session ID. */ |
537 | 28 | transport = lbttcp_transport_find(&source_address, srcport, sid, pinfo->num); |
538 | 28 | if (transport == NULL) |
539 | 28 | { |
540 | | /* See if we know about a SID */ |
541 | 28 | if (lbttcp_transport_sid_find(&source_address, srcport, pinfo->num, &sid)) |
542 | 0 | { |
543 | 0 | transport = lbttcp_transport_find(&source_address, srcport, sid, pinfo->num); |
544 | 0 | } |
545 | 28 | } |
546 | 28 | if (transport != NULL) |
547 | 0 | { |
548 | 0 | channel = transport->channel; |
549 | | /* See if we already know about this client */ |
550 | 0 | client = lbttcp_client_transport_find(transport, &client_address, clntport, pinfo->num); |
551 | 0 | if (client == NULL) |
552 | 0 | { |
553 | | /* No - add it. */ |
554 | 0 | client = lbttcp_client_transport_add(transport, &client_address, clntport, pinfo->num); |
555 | 0 | } |
556 | 0 | if (client != NULL) |
557 | 0 | { |
558 | 0 | client_id = client->id; |
559 | 0 | } |
560 | 0 | } |
561 | 28 | else |
562 | 28 | { |
563 | 28 | if (PINFO_FD_VISITED(pinfo)) |
564 | 0 | { |
565 | | /* No TIR and no session ID seen, so create the transport */ |
566 | 0 | transport = lbttcp_transport_add(&source_address, srcport, 0, pinfo->num); |
567 | 0 | if (transport != NULL) |
568 | 0 | { |
569 | 0 | channel = transport->channel; |
570 | 0 | client = lbttcp_client_transport_add(transport, &client_address, clntport, pinfo->num); |
571 | 0 | if (client != NULL) |
572 | 0 | { |
573 | 0 | client_id = client->id; |
574 | 0 | } |
575 | 0 | } |
576 | 0 | } |
577 | 28 | else |
578 | 28 | { |
579 | | /* Defer determining the channel. */ |
580 | 28 | if (from_source) |
581 | 14 | { |
582 | 14 | channel = lbm_channel_assign_unknown_transport_source_lbttcp(); |
583 | 14 | } |
584 | 14 | else |
585 | 14 | { |
586 | 14 | channel = lbm_channel_assign_unknown_transport_client_lbttcp(); |
587 | 14 | } |
588 | 28 | } |
589 | 28 | } |
590 | 28 | } |
591 | 770 | else |
592 | 770 | { |
593 | 770 | channel = lbm_channel_assign_unknown_stream_tcp(); |
594 | 770 | } |
595 | 798 | if (lbm_channel_is_known(channel)) |
596 | 0 | { |
597 | 0 | proto_item * channel_item = NULL; |
598 | 0 | proto_tree * channel_tree = NULL; |
599 | |
|
600 | 0 | channel_item = proto_tree_add_item(lbttcp_tree, hf_lbttcp_channel, tvb, 0, 0, ENC_NA); |
601 | 0 | proto_item_set_generated(channel_item); |
602 | 0 | channel_tree = proto_item_add_subtree(channel_item, ett_lbttcp_channel); |
603 | 0 | channel_item = proto_tree_add_uint64(channel_tree, hf_lbttcp_channel_id, tvb, 0, 0, channel); |
604 | 0 | proto_item_set_generated(channel_item); |
605 | 0 | channel_item = proto_tree_add_uint(channel_tree, hf_lbttcp_channel_client, tvb, 0, 0, client_id); |
606 | 0 | proto_item_set_generated(channel_item); |
607 | 0 | } |
608 | 798 | len_dissected = lbmc_dissect_lbmc_packet(tvb, 0, pinfo, tree, tag_name, channel); |
609 | 798 | return (len_dissected); |
610 | 798 | } |
611 | | |
612 | | /* |
613 | | * dissect_lbttcp_real - The "common" dissection for LBT-TCP |
614 | | */ |
615 | | static int dissect_lbttcp_real(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_) |
616 | 622 | { |
617 | 622 | char * tag_name = NULL; |
618 | | |
619 | 622 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "LBT-TCP"); |
620 | 622 | col_clear(pinfo->cinfo, COL_INFO); |
621 | 622 | if (lbttcp_use_tag) |
622 | 0 | { |
623 | 0 | tag_name = lbttcp_tag_find(pinfo); |
624 | 0 | } |
625 | 622 | if (tag_name != NULL) |
626 | 0 | { |
627 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "[Tag: %s]", tag_name); |
628 | 0 | } |
629 | 622 | col_set_fence(pinfo->cinfo, COL_INFO); |
630 | 622 | tcp_dissect_pdus(tvb, pinfo, tree, true, lbmc_get_minimum_length(), /* Need at least the msglen */ |
631 | 622 | get_lbttcp_pdu_length, dissect_lbttcp_pdu, NULL); |
632 | | |
633 | 622 | return tvb_captured_length(tvb); |
634 | 622 | } |
635 | | |
636 | | /* |
637 | | * dissect_lbttcp - The dissector for LBT-TCP |
638 | | */ |
639 | | static int dissect_lbttcp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data) |
640 | 0 | { |
641 | 0 | if (!lbmc_test_lbmc_header(tvb, 0)) |
642 | 0 | return 0; |
643 | | |
644 | 0 | return dissect_lbttcp_real(tvb, pinfo, tree, data); |
645 | 0 | } |
646 | | |
647 | | static bool test_lbttcp_packet(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data) |
648 | 5.99k | { |
649 | | /* Destination address must be IPV4 and 4 bytes in length. */ |
650 | 5.99k | if ((pinfo->dst.type != AT_IPv4) || (pinfo->dst.len != 4)) |
651 | 1.10k | { |
652 | 1.10k | return false; |
653 | 1.10k | } |
654 | | |
655 | 4.88k | if (lbttcp_use_tag) |
656 | 0 | { |
657 | 0 | if (lbttcp_tag_find(pinfo) != NULL) |
658 | 0 | { |
659 | 0 | dissect_lbttcp_real(tvb, pinfo, tree, data); |
660 | 0 | return true; |
661 | 0 | } |
662 | 0 | else |
663 | 0 | { |
664 | 0 | return false; |
665 | 0 | } |
666 | 0 | } |
667 | | |
668 | | /* |
669 | | Source port or destination port must be in the source port range, or destination port must be in |
670 | | the request port range, or either port in the UME store port range. |
671 | | */ |
672 | 4.88k | if (!(((pinfo->srcport >= lbttcp_source_port_low) && (pinfo->srcport <= lbttcp_source_port_high)) |
673 | 4.87k | || ((pinfo->destport >= lbttcp_source_port_low) && (pinfo->destport <= lbttcp_source_port_high)) |
674 | 4.85k | || ((pinfo->srcport >= lbttcp_request_port_low) && (pinfo->srcport <= lbttcp_request_port_high)) |
675 | 4.85k | || ((pinfo->destport >= lbttcp_request_port_low) && (pinfo->destport <= lbttcp_request_port_high)) |
676 | 4.85k | || ((pinfo->srcport >= lbttcp_store_port_low) && (pinfo->srcport <= lbttcp_store_port_high)) |
677 | 3.91k | || ((pinfo->destport >= lbttcp_store_port_low) && (pinfo->destport <= lbttcp_store_port_high)))) |
678 | 3.35k | { |
679 | 3.35k | return false; |
680 | 3.35k | } |
681 | | |
682 | 1.53k | if (!lbmc_test_lbmc_header(tvb, 0)) |
683 | 911 | return false; |
684 | | |
685 | | /* One of ours. Probably. */ |
686 | 622 | dissect_lbttcp_real(tvb, pinfo, tree, data); |
687 | 622 | return true; |
688 | 1.53k | } |
689 | | |
690 | | /* Register all the bits needed with the filtering engine */ |
691 | | void proto_register_lbttcp(void) |
692 | 16 | { |
693 | 16 | static hf_register_info hf[] = |
694 | 16 | { |
695 | 16 | { &hf_lbttcp_tag, |
696 | 16 | { "Tag", "lbttcp.tag", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
697 | 16 | { &hf_lbttcp_channel, |
698 | 16 | { "Channel", "lbttcp.channel", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
699 | 16 | { &hf_lbttcp_channel_id, |
700 | 16 | { "Channel ID", "lbttcp.channel.channel", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } }, |
701 | 16 | { &hf_lbttcp_channel_client, |
702 | 16 | { "Channel Client", "lbttcp.channel.client", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
703 | 16 | }; |
704 | 16 | static int * ett[] = |
705 | 16 | { |
706 | 16 | &ett_lbttcp, |
707 | 16 | &ett_lbttcp_channel |
708 | 16 | }; |
709 | 16 | module_t * lbttcp_module; |
710 | 16 | uat_t * tag_uat; |
711 | | |
712 | 16 | proto_lbttcp = proto_register_protocol("LBT TCP Protocol", "LBT-TCP", "lbttcp"); |
713 | | |
714 | 16 | proto_register_field_array(proto_lbttcp, hf, array_length(hf)); |
715 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
716 | | |
717 | 16 | lbttcp_dissector_handle = register_dissector("lbttcp", dissect_lbttcp, proto_lbttcp); |
718 | | |
719 | 16 | lbttcp_module = prefs_register_protocol_subtree("29West", proto_lbttcp, proto_reg_handoff_lbttcp); |
720 | 16 | prefs_register_uint_preference(lbttcp_module, |
721 | 16 | "source_port_low", |
722 | 16 | "Source port range low (default " MAKESTRING(LBTTCP_DEFAULT_SOURCE_PORT_LOW)")", |
723 | 16 | "Set the low end of the LBT-TCP source TCP port range (context transport_tcp_port_low)", |
724 | 16 | 10, |
725 | 16 | &global_lbttcp_source_port_low); |
726 | | |
727 | 16 | prefs_register_uint_preference(lbttcp_module, |
728 | 16 | "source_port_high", |
729 | 16 | "Source port range high (default " MAKESTRING(LBTTCP_DEFAULT_SOURCE_PORT_HIGH)")", |
730 | 16 | "Set the high end of the LBT-TCP source TCP port range (context transport_tcp_port_high)", |
731 | 16 | 10, |
732 | 16 | &global_lbttcp_source_port_high); |
733 | | |
734 | 16 | prefs_register_uint_preference(lbttcp_module, |
735 | 16 | "request_port_low", |
736 | 16 | "Request port range low (default " MAKESTRING(LBTTCP_DEFAULT_REQUEST_PORT_LOW)")", |
737 | 16 | "Set the low end of the LBT-TCP request TCP port range (context request_tcp_port_low)", |
738 | 16 | 10, |
739 | 16 | &global_lbttcp_request_port_low); |
740 | | |
741 | 16 | prefs_register_uint_preference(lbttcp_module, |
742 | 16 | "request_port_high", |
743 | 16 | "Request port range high (default " MAKESTRING(LBTTCP_DEFAULT_REQUEST_PORT_HIGH)")", |
744 | 16 | "Set the high end of the LBT-TCP request TCP port range (context request_tcp_port_high)", |
745 | 16 | 10, |
746 | 16 | &global_lbttcp_request_port_high); |
747 | | |
748 | 16 | prefs_register_uint_preference(lbttcp_module, |
749 | 16 | "store_port_low", |
750 | 16 | "UME Store port range low (default " MAKESTRING(LBTTCP_DEFAULT_STORE_PORT_LOW)")", |
751 | 16 | "Set the low end of the LBT-TCP UME Store TCP port range", |
752 | 16 | 10, |
753 | 16 | &global_lbttcp_store_port_low); |
754 | | |
755 | 16 | prefs_register_uint_preference(lbttcp_module, |
756 | 16 | "store_port_high", |
757 | 16 | "UME Store port range high (default " MAKESTRING(LBTTCP_DEFAULT_STORE_PORT_HIGH)")", |
758 | 16 | "Set the high end of the LBT-TCP UME Store TCP port range", |
759 | 16 | 10, |
760 | 16 | &global_lbttcp_store_port_high); |
761 | | |
762 | 16 | prefs_register_bool_preference(lbttcp_module, |
763 | 16 | "use_lbttcp_domain", |
764 | 16 | "Use LBT-TCP tag table", |
765 | 16 | "Use table of LBT-TCP tags to decode the packet instead of above values", |
766 | 16 | &global_lbttcp_use_tag); |
767 | 16 | tag_uat = uat_new("LBT-TCP tag definitions", |
768 | 16 | sizeof(lbttcp_tag_entry_t), |
769 | 16 | "lbttcp_domains", |
770 | 16 | true, |
771 | 16 | (void * *)&lbttcp_tag_entry, |
772 | 16 | &lbttcp_tag_count, |
773 | 16 | UAT_AFFECTS_DISSECTION, |
774 | 16 | NULL, |
775 | 16 | lbttcp_tag_copy_cb, |
776 | 16 | lbttcp_tag_update_cb, |
777 | 16 | lbttcp_tag_free_cb, |
778 | 16 | NULL, |
779 | 16 | NULL, |
780 | 16 | lbttcp_tag_array); |
781 | 16 | prefs_register_uat_preference(lbttcp_module, |
782 | 16 | "tnw_lbttcp_tags", |
783 | 16 | "LBT-TCP Tags", |
784 | 16 | "A table to define LBT-TCP tags", |
785 | 16 | tag_uat); |
786 | 16 | } |
787 | | |
788 | | /* The registration hand-off routine */ |
789 | | void proto_reg_handoff_lbttcp(void) |
790 | 16 | { |
791 | 16 | static bool already_registered = false; |
792 | | |
793 | 16 | if (!already_registered) |
794 | 16 | { |
795 | 16 | dissector_add_for_decode_as_with_preference("tcp.port", lbttcp_dissector_handle); |
796 | 16 | heur_dissector_add("tcp", test_lbttcp_packet, "LBT over TCP", "lbttcp_tcp", proto_lbttcp, HEURISTIC_ENABLE); |
797 | 16 | } |
798 | | |
799 | | /* Make sure the source port low is <= the source port high. If not, don't change them. */ |
800 | 16 | if (global_lbttcp_source_port_low <= global_lbttcp_source_port_high) |
801 | 16 | { |
802 | 16 | lbttcp_source_port_low = global_lbttcp_source_port_low; |
803 | 16 | lbttcp_source_port_high = global_lbttcp_source_port_high; |
804 | 16 | } |
805 | | |
806 | | /* Make sure the request port low is <= the request port high. If not, don't change them. */ |
807 | 16 | if (global_lbttcp_request_port_low <= global_lbttcp_request_port_high) |
808 | 16 | { |
809 | 16 | lbttcp_request_port_low = global_lbttcp_request_port_low; |
810 | 16 | lbttcp_request_port_high = global_lbttcp_request_port_high; |
811 | 16 | } |
812 | | |
813 | | /* Make sure the store port low is <= the store port high. If not, don't change them. */ |
814 | 16 | if (global_lbttcp_store_port_low <= global_lbttcp_store_port_high) |
815 | 16 | { |
816 | 16 | lbttcp_store_port_low = global_lbttcp_store_port_low; |
817 | 16 | lbttcp_store_port_high = global_lbttcp_store_port_high; |
818 | 16 | } |
819 | | |
820 | 16 | lbttcp_use_tag = global_lbttcp_use_tag; |
821 | | |
822 | | already_registered = true; |
823 | 16 | } |
824 | | |
825 | | /* |
826 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
827 | | * |
828 | | * Local variables: |
829 | | * c-basic-offset: 4 |
830 | | * tab-width: 8 |
831 | | * indent-tabs-mode: nil |
832 | | * End: |
833 | | * |
834 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
835 | | * :indentSize=4:tabSize=8:noTabs=true: |
836 | | */ |