Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-lbmpdmtcp.c
blob73cd47789ee3bcbf676b184089ec73f2e5c93d87
1 /* packet-lbmpdmtcp.c
2 * Routines for LBM PDM-over-TCP 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
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/uat.h>
18 #include "packet-tcp.h"
19 #include "packet-lbm.h"
21 void proto_register_lbmpdm_tcp(void);
22 void proto_reg_handoff_lbmpdm_tcp(void);
24 /* Protocol handle */
25 static int lbmpdm_tcp_protocol_handle = -1;
27 /* Dissector handle */
28 static dissector_handle_t lbmpdm_tcp_dissector_handle;
30 /*----------------------------------------------------------------------------*/
31 /* LBM-TCP transport management. */
32 /*----------------------------------------------------------------------------*/
34 typedef struct
36 address addr1;
37 uint16_t port1;
38 address addr2;
39 uint16_t port2;
40 uint64_t channel;
41 } lbmtcp_transport_t;
43 static void lbmtcp_order_key(lbmtcp_transport_t * transport)
45 bool swap = false;
46 int compare;
48 /* Order the key so that addr1:port1 <= addr2:port2 */
49 compare = cmp_address(&(transport->addr1), &(transport->addr2));
50 if (compare > 0)
52 swap = true;
54 else if (compare == 0)
56 if (transport->port1 > transport->port2)
58 swap = true;
61 if (swap)
63 address addr;
64 uint16_t port;
66 copy_address_shallow(&addr, &(transport->addr1));
67 copy_address_shallow(&(transport->addr2), &(transport->addr1));
68 copy_address_shallow(&(transport->addr1), &addr);
69 port = transport->port2;
70 transport->port2 = transport->port1;
71 transport->port1 = port;
75 static lbmtcp_transport_t * lbmtcp_transport_add(const address * address1, uint16_t port1, const address * address2, uint16_t port2, uint32_t frame)
77 lbmtcp_transport_t * entry;
78 conversation_t * conv = NULL;
80 conv = find_conversation(frame, address1, address2, CONVERSATION_TCP, port1, port2, 0);
81 if (conv == NULL)
83 conv = conversation_new(frame, address1, address2, CONVERSATION_TCP, port1, port2, 0);
85 entry = (lbmtcp_transport_t *) conversation_get_proto_data(conv, lbmpdm_tcp_protocol_handle);
86 if (entry != NULL)
88 return (entry);
90 entry = wmem_new(wmem_file_scope(), lbmtcp_transport_t);
91 copy_address_wmem(wmem_file_scope(), &(entry->addr1), address1);
92 entry->port1 = port1;
93 copy_address_wmem(wmem_file_scope(), &(entry->addr2), address2);
94 entry->port2 = port2;
95 lbmtcp_order_key(entry);
96 entry->channel = lbm_channel_assign(LBM_CHANNEL_TCP);
97 conversation_add_proto_data(conv, lbmpdm_tcp_protocol_handle, (void *) entry);
98 return (entry);
101 /*----------------------------------------------------------------------------*/
102 /* Preferences. */
103 /*----------------------------------------------------------------------------*/
105 /* Preferences default values. */
106 #define LBMPDM_TCP_DEFAULT_PORT_LOW 14371
107 #define LBMPDM_TCP_DEFAULT_PORT_HIGH 14390
109 /* Global preferences variables (altered by the preferences dialog). */
110 static uint32_t global_lbmpdm_tcp_port_low = LBMPDM_TCP_DEFAULT_PORT_LOW;
111 static uint32_t global_lbmpdm_tcp_port_high = LBMPDM_TCP_DEFAULT_PORT_HIGH;
112 static bool global_lbmpdm_tcp_use_tag;
114 /* Local preferences variables (used by the dissector). */
115 static uint32_t lbmpdm_tcp_port_low = LBMPDM_TCP_DEFAULT_PORT_LOW;
116 static uint32_t lbmpdm_tcp_port_high = LBMPDM_TCP_DEFAULT_PORT_HIGH;
117 static bool lbmpdm_tcp_use_tag;
119 /* Tag definitions. */
120 typedef struct
122 char * name;
123 uint32_t port_low;
124 uint32_t port_high;
125 } lbmpdm_tcp_tag_entry_t;
127 static lbmpdm_tcp_tag_entry_t * lbmpdm_tcp_tag_entry;
128 static unsigned lbmpdm_tcp_tag_count;
130 UAT_CSTRING_CB_DEF(lbmpdm_tcp_tag, name, lbmpdm_tcp_tag_entry_t)
131 UAT_DEC_CB_DEF(lbmpdm_tcp_tag, port_low, lbmpdm_tcp_tag_entry_t)
132 UAT_DEC_CB_DEF(lbmpdm_tcp_tag, port_high, lbmpdm_tcp_tag_entry_t)
133 static uat_field_t lbmpdm_tcp_tag_array[] =
135 UAT_FLD_CSTRING(lbmpdm_tcp_tag, name, "Tag name", "Tag name"),
136 UAT_FLD_DEC(lbmpdm_tcp_tag, port_low, "Port low", "Port low"),
137 UAT_FLD_DEC(lbmpdm_tcp_tag, port_high, "Port high", "Port high"),
138 UAT_END_FIELDS
141 /*----------------------------------------------------------------------------*/
142 /* UAT callback functions. */
143 /*----------------------------------------------------------------------------*/
144 static bool lbmpdm_tcp_tag_update_cb(void * record, char * * error_string)
146 lbmpdm_tcp_tag_entry_t * tag = (lbmpdm_tcp_tag_entry_t *)record;
148 if (tag->name == NULL)
150 *error_string = g_strdup("Tag name can't be empty");
151 return false;
153 else
155 g_strstrip(tag->name);
156 if (tag->name[0] == 0)
158 *error_string = g_strdup("Tag name can't be empty");
159 return false;
162 return true;
165 static void * lbmpdm_tcp_tag_copy_cb(void * destination, const void * source, size_t length _U_)
167 const lbmpdm_tcp_tag_entry_t * src = (const lbmpdm_tcp_tag_entry_t *)source;
168 lbmpdm_tcp_tag_entry_t * dest = (lbmpdm_tcp_tag_entry_t *)destination;
170 dest->name = g_strdup(src->name);
171 dest->port_low = src->port_low;
172 dest->port_high = src->port_high;
173 return (dest);
176 static void lbmpdm_tcp_tag_free_cb(void * record)
178 lbmpdm_tcp_tag_entry_t * tag = (lbmpdm_tcp_tag_entry_t *)record;
180 if (tag->name != NULL)
182 g_free(tag->name);
183 tag->name = NULL;
187 static const lbmpdm_tcp_tag_entry_t * lbmpdm_tcp_tag_locate(packet_info * pinfo)
189 unsigned idx;
190 const lbmpdm_tcp_tag_entry_t * tag = NULL;
192 if (!lbmpdm_tcp_use_tag)
194 return (NULL);
197 for (idx = 0; idx < lbmpdm_tcp_tag_count; ++idx)
199 tag = &(lbmpdm_tcp_tag_entry[idx]);
200 if (((pinfo->srcport >= tag->port_low) && (pinfo->srcport <= tag->port_high))
201 || ((pinfo->destport >= tag->port_low) && (pinfo->destport <= tag->port_high)))
203 return (tag);
206 return (NULL);
209 static char * lbmpdm_tcp_tag_find(packet_info * pinfo)
211 const lbmpdm_tcp_tag_entry_t * tag = NULL;
213 if (!lbmpdm_tcp_use_tag)
215 return (NULL);
218 tag = lbmpdm_tcp_tag_locate(pinfo);
219 if (tag != NULL)
221 return tag->name;
223 return (NULL);
226 /*----------------------------------------------------------------------------*/
227 /* Handles of all types. */
228 /*----------------------------------------------------------------------------*/
230 /* Dissector tree handles */
231 static int ett_lbmpdm_tcp;
233 /* Dissector field handles */
234 static int hf_lbmpdm_tcp_tag;
235 static int hf_lbmpdm_tcp_channel;
237 static unsigned get_lbmpdm_tcp_pdu_length(packet_info * pinfo _U_, tvbuff_t * tvb,
238 int offset, void *data _U_)
240 int encoding;
241 int packet_len = 0;
242 packet_len = 0;
244 if (!lbmpdm_verify_payload(tvb, offset, &encoding, &packet_len))
246 packet_len = 0;
248 return (packet_len);
251 static int dissect_lbmpdm_tcp_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * dissector_data _U_)
253 proto_tree * lbmpdm_tcp_tree = NULL;
254 proto_item * ti = NULL;
255 lbmtcp_transport_t * transport = NULL;
256 char * tag_name = NULL;
257 uint64_t channel = LBM_CHANNEL_NO_CHANNEL;
259 if (lbmpdm_tcp_use_tag)
261 tag_name = lbmpdm_tcp_tag_find(pinfo);
263 if (tag_name != NULL)
265 ti = proto_tree_add_protocol_format(tree, lbmpdm_tcp_protocol_handle, tvb, 0, -1, "LBMPDM-TCP Protocol (Tag: %s)", tag_name);
267 else
269 ti = proto_tree_add_protocol_format(tree, lbmpdm_tcp_protocol_handle, tvb, 0, -1, "LBMPDM-TCP Protocol");
271 lbmpdm_tcp_tree = proto_item_add_subtree(ti, ett_lbmpdm_tcp);
273 transport = lbmtcp_transport_add(&(pinfo->src), pinfo->srcport, &(pinfo->dst), pinfo->destport, pinfo->num);
274 if (transport != NULL)
276 channel = transport->channel;
278 if (tag_name != NULL)
280 proto_item * item = NULL;
282 item = proto_tree_add_string(lbmpdm_tcp_tree, hf_lbmpdm_tcp_tag, tvb, 0, 0, tag_name);
283 proto_item_set_generated(item);
285 if (channel != LBM_CHANNEL_NO_CHANNEL)
287 proto_item * item = NULL;
289 item = proto_tree_add_uint64(lbmpdm_tcp_tree, hf_lbmpdm_tcp_channel, tvb, 0, 0, channel);
290 proto_item_set_generated(item);
292 return (lbmpdm_dissect_lbmpdm_payload(tvb, 0, pinfo, tree, channel));
296 * dissect_lbmpdm_tcp - The dissector for LBMPDM over TCP
298 static int dissect_lbmpdm_tcp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_)
300 char * tag_name = NULL;
302 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LBMPDM-TCP");
303 col_clear(pinfo->cinfo, COL_INFO);
304 if (lbmpdm_tcp_use_tag)
306 tag_name = lbmpdm_tcp_tag_find(pinfo);
308 if (tag_name != NULL)
310 col_add_fstr(pinfo->cinfo, COL_INFO, "[Tag: %s]", tag_name);
312 col_set_fence(pinfo->cinfo, COL_INFO);
313 tcp_dissect_pdus(tvb, pinfo, tree, true, lbmpdm_get_minimum_length(), /* Need at least the msglen */
314 get_lbmpdm_tcp_pdu_length, dissect_lbmpdm_tcp_pdu, NULL);
315 return tvb_captured_length(tvb);
318 static bool test_lbmpdm_tcp_packet(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * user_data _U_)
320 int encoding = 0;
321 int packet_len = 0;
323 /* Must be a TCP packet. */
324 if (pinfo->ptype != PT_TCP)
326 return false;
328 /* Destination address must be IPV4 and 4 bytes in length. */
329 if ((pinfo->dst.type != AT_IPv4) || (pinfo->dst.len != 4))
331 return false;
333 if (!lbmpdm_verify_payload(tvb, 0, &encoding, &packet_len))
335 return false;
337 if (lbmpdm_tcp_use_tag)
339 if (lbmpdm_tcp_tag_find(pinfo) != NULL)
341 dissect_lbmpdm_tcp(tvb, pinfo, tree, user_data);
342 return true;
344 else
346 return false;
350 /* Source port or destination port must be in the specified range. */
351 if (!(((pinfo->srcport >= lbmpdm_tcp_port_low) && (pinfo->srcport <= lbmpdm_tcp_port_high))
352 || ((pinfo->destport >= lbmpdm_tcp_port_low) && (pinfo->destport <= lbmpdm_tcp_port_high))))
354 return false;
356 /* One of ours. Probably. */
357 dissect_lbmpdm_tcp(tvb, pinfo, tree, user_data);
358 return true;
361 /* Register all the bits needed with the filtering engine */
362 void proto_register_lbmpdm_tcp(void)
364 static hf_register_info hf[] =
366 { &hf_lbmpdm_tcp_tag,
367 { "Tag", "lbmpdm_tcp.tag", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
368 { &hf_lbmpdm_tcp_channel,
369 { "Channel ID", "lbmpdm_tcp.channel", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
371 static int * ett[] =
373 &ett_lbmpdm_tcp,
375 module_t * lbmpdm_tcp_module;
376 uat_t * tag_uat;
378 lbmpdm_tcp_protocol_handle = proto_register_protocol("LBMPDM over TCP Protocol", "LBMPDM-TCP", "lbmpdm_tcp");
380 proto_register_field_array(lbmpdm_tcp_protocol_handle, hf, array_length(hf));
381 proto_register_subtree_array(ett, array_length(ett));
383 lbmpdm_tcp_module = prefs_register_protocol_subtree("29West", lbmpdm_tcp_protocol_handle, proto_reg_handoff_lbmpdm_tcp);
384 prefs_register_uint_preference(lbmpdm_tcp_module,
385 "port_low",
386 "Port range low (default " MAKESTRING(LBMPDM_TCP_DEFAULT_PORT_LOW)")",
387 "Set the low end of the TCP port range",
389 &global_lbmpdm_tcp_port_low);
391 prefs_register_uint_preference(lbmpdm_tcp_module,
392 "port_high",
393 "Port range high (default " MAKESTRING(LBMPDM_TCP_DEFAULT_PORT_HIGH)")",
394 "Set the high end of the port range",
396 &global_lbmpdm_tcp_port_high);
398 prefs_register_bool_preference(lbmpdm_tcp_module,
399 "use_lbmpdm_tcp_domain",
400 "Use LBMPDM-TCP tag table",
401 "Use table of LBMPDM-TCP tags to decode the packet instead of above values",
402 &global_lbmpdm_tcp_use_tag);
403 tag_uat = uat_new("LBMPDM-TCP tag definitions",
404 sizeof(lbmpdm_tcp_tag_entry_t),
405 "lbmpdm_tcp_domains",
406 true,
407 (void * *)&lbmpdm_tcp_tag_entry,
408 &lbmpdm_tcp_tag_count,
409 UAT_AFFECTS_DISSECTION,
410 NULL,
411 lbmpdm_tcp_tag_copy_cb,
412 lbmpdm_tcp_tag_update_cb,
413 lbmpdm_tcp_tag_free_cb,
414 NULL,
415 NULL,
416 lbmpdm_tcp_tag_array);
417 prefs_register_uat_preference(lbmpdm_tcp_module,
418 "tnw_lbmpdm_tcp_tags",
419 "LBMPDM-TCP Tags",
420 "A table to define LBMPDM-TCP tags",
421 tag_uat);
423 lbmpdm_tcp_dissector_handle = register_dissector("lbmpdm_tcp", dissect_lbmpdm_tcp, lbmpdm_tcp_protocol_handle);
426 /* The registration hand-off routine */
427 void proto_reg_handoff_lbmpdm_tcp(void)
429 static bool already_registered = false;
431 if (!already_registered)
433 dissector_add_for_decode_as_with_preference("tcp.port", lbmpdm_tcp_dissector_handle);
434 heur_dissector_add("tcp", test_lbmpdm_tcp_packet, "LBMPDM over TCP", "lbmpdm_tcp", lbmpdm_tcp_protocol_handle, HEURISTIC_ENABLE);
437 /* Make sure the port low is <= the port high. If not, don't change them. */
438 if (global_lbmpdm_tcp_port_low <= global_lbmpdm_tcp_port_high)
440 lbmpdm_tcp_port_low = global_lbmpdm_tcp_port_low;
441 lbmpdm_tcp_port_high = global_lbmpdm_tcp_port_high;
444 lbmpdm_tcp_use_tag = global_lbmpdm_tcp_use_tag;
446 already_registered = true;
450 * Editor modelines - https://www.wireshark.org/tools/modelines.html
452 * Local variables:
453 * c-basic-offset: 4
454 * tab-width: 8
455 * indent-tabs-mode: nil
456 * End:
458 * vi: set shiftwidth=4 tabstop=8 expandtab:
459 * :indentSize=4:tabSize=8:noTabs=true: