Add ability to create endpoints through conversations

Add endpoint information to the packet_info structure for dissectors
to potentially use as their data to create conversations.

This patch includes a simple "example" of using conversation_create_endpoint
with TDMoP.  The assignment of the PT_TDMOP "port type" has been replaced by
setting ENDPOINT_TDMOP within the endpoint structure.  Then when subdissectors
of TDMoP call find_or_create_conversation(), it implicitly picks up the
conversation information set by TDMoP

Change-Id: I11dc29989cccd3b0f0349ee901babb455ca02d19
Reviewed-on: https://code.wireshark.org/review/24190
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Andrew Chernyh <andrew.chernyh@gmail.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Michael Mann 2017-10-30 15:57:34 -04:00
parent d518f28b39
commit 66b441f3d6
8 changed files with 67 additions and 25 deletions

View File

@ -369,8 +369,7 @@ typedef enum {
PT_USB, /* USB endpoint 0xffff means the host */
PT_I2C,
PT_IBQP, /* Infiniband QP number */
PT_BLUETOOTH,
PT_TDMOP
PT_BLUETOOTH
} port_type;
/* Types of circuit IDs Wireshark knows about. */

View File

@ -36,6 +36,15 @@
int _debug_conversation_indent = 0;
#endif
struct endpoint {
address addr1;
address addr2;
endpoint_type etype;
guint32 port1;
guint32 port2;
guint options;
};
struct conversation_key {
struct conversation_key *next;
address addr1;
@ -1254,13 +1263,26 @@ find_conversation_pinfo(packet_info *pinfo, const guint options)
DINDENT();
/* Have we seen this conversation before? */
if((conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
conversation_pt_to_endpoint_type(pinfo->ptype), pinfo->srcport,
pinfo->destport, options)) != NULL) {
DPRINT(("found previous conversation for frame #%d (last_frame=%d)",
pinfo->num, conv->last_frame));
if (pinfo->num > conv->last_frame) {
conv->last_frame = pinfo->num;
if (pinfo->use_endpoint) {
DISSECTOR_ASSERT(pinfo->conv_endpoint);
if((conv = find_conversation(pinfo->num, &pinfo->conv_endpoint->addr1, &pinfo->conv_endpoint->addr2,
pinfo->conv_endpoint->etype, pinfo->conv_endpoint->port1,
pinfo->conv_endpoint->port2, options)) != NULL) {
DPRINT(("found previous conversation for frame #%d (last_frame=%d)",
pinfo->num, conv->last_frame));
if (pinfo->num > conv->last_frame) {
conv->last_frame = pinfo->num;
}
}
} else {
if((conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
conversation_pt_to_endpoint_type(pinfo->ptype), pinfo->srcport,
pinfo->destport, options)) != NULL) {
DPRINT(("found previous conversation for frame #%d (last_frame=%d)",
pinfo->num, conv->last_frame));
if (pinfo->num > conv->last_frame) {
conv->last_frame = pinfo->num;
}
}
}
@ -1295,6 +1317,24 @@ find_or_create_conversation(packet_info *pinfo)
return conv;
}
void conversation_create_endpoint(struct _packet_info *pinfo, address* addr1, address* addr2,
endpoint_type etype, guint32 port1, guint32 port2, const guint options)
{
pinfo->conv_endpoint = wmem_new0(pinfo->pool, struct endpoint);
pinfo->use_endpoint = TRUE;
if (addr1 != NULL)
copy_address_wmem(pinfo->pool, &pinfo->conv_endpoint->addr1, addr1);
if (addr2 != NULL)
copy_address_wmem(pinfo->pool, &pinfo->conv_endpoint->addr2, addr2);
pinfo->conv_endpoint->etype = etype;
pinfo->conv_endpoint->port1 = port1;
pinfo->conv_endpoint->port2 = port2;
pinfo->conv_endpoint->options = options;
}
wmem_map_t *
get_conversation_hashtable_exact(void)
{
@ -1376,8 +1416,6 @@ endpoint_type conversation_pt_to_endpoint_type(port_type pt)
return ENDPOINT_IBQP;
case PT_BLUETOOTH:
return ENDPOINT_BLUETOOTH;
case PT_TDMOP:
return ENDPOINT_TDMOP;
}
DISSECTOR_ASSERT(FALSE);

View File

@ -101,6 +101,9 @@ typedef struct conversation {
} conversation_t;
struct endpoint;
typedef struct endpoint* endpoint_t;
WS_DLL_PUBLIC address* conversation_key_addr1(const conversation_key_t key);
WS_DLL_PUBLIC address* conversation_key_addr2(const conversation_key_t key);
WS_DLL_PUBLIC guint32 conversation_key_port1(const conversation_key_t key);
@ -193,6 +196,9 @@ WS_DLL_PUBLIC void conversation_set_dissector_from_frame_number(conversation_t *
WS_DLL_PUBLIC dissector_handle_t conversation_get_dissector(conversation_t *conversation,
const guint32 frame_num);
WS_DLL_PUBLIC void conversation_create_endpoint(struct _packet_info *pinfo, address* addr1, address* addr2,
endpoint_type etype, guint32 port1, guint32 port2, const guint options);
/**
* Given two address/port pairs for a packet, search for a matching
* conversation and, if found and it has a conversation dissector,

View File

@ -165,7 +165,6 @@ static port_type exp_pdu_old_to_new_port_type(guint type)
case OLD_PT_BLUETOOTH:
return PT_BLUETOOTH;
case OLD_PT_TDMOP:
return PT_TDMOP;
case OLD_PT_NCP:
case OLD_PT_SBCCS:
//no longer supported

View File

@ -25,6 +25,7 @@
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/conversation.h>
#include <epan/prefs.h>
/*Using of ethertype 0x0808(assigned to Frame Realy ARP) was implemented in hardware, when ethertype was not assigned*/
@ -94,8 +95,7 @@ static int dissect_tdmop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
gint offset;
proto_item *ti;
proto_tree *tdmop_tree;
guint32 dstch;
guint32 srcch;
guint32 dstch, srcch;
flags = tvb_get_guint8(tvb, 4);
offset = 0;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TDMoP");
@ -104,21 +104,20 @@ static int dissect_tdmop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
{
col_add_fstr(pinfo->cinfo, COL_INFO, "Lost Request");
}
/*conversation*/
dstch = tvb_get_guint8(tvb, offset + 2);
srcch = tvb_get_guint8(tvb, offset + 3);
pinfo->destport = dstch;
pinfo->srcport = srcch;
pinfo->ptype = PT_TDMOP;
ti = proto_tree_add_item(tree, proto_tdmop, tvb, 0, -1, ENC_NA);
tdmop_tree = proto_item_add_subtree(ti, ett_tdmop);
/*path info*/
proto_tree_add_item(tdmop_tree, hf_tdmop_TransferID, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 2;
proto_tree_add_item(tdmop_tree, hf_tdmop_DstCh, tvb, offset, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item_ret_uint(tdmop_tree, hf_tdmop_DstCh, tvb, offset, 1, ENC_LITTLE_ENDIAN, &dstch);
offset += 1;
proto_tree_add_item(tdmop_tree, hf_tdmop_SrcCh, tvb, offset, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item_ret_uint(tdmop_tree, hf_tdmop_SrcCh, tvb, offset, 1, ENC_LITTLE_ENDIAN, &srcch);
offset += 1;
/*conversation*/
conversation_create_endpoint(pinfo, &pinfo->src, &pinfo->dst, ENDPOINT_TDMOP, srcch, dstch, 0);
/*flags*/
proto_tree_add_item(tdmop_tree, hf_tdmop_Flags, tvb, offset, 1, ENC_NA);
proto_tree_add_item(tdmop_tree, hf_tdmop_Flags_no_data, tvb, offset, 1, ENC_NA);

View File

@ -132,8 +132,6 @@ static guint exp_pdu_new_to_old_port_type(port_type pt)
return OLD_PT_IBQP;
case PT_BLUETOOTH:
return OLD_PT_BLUETOOTH;
case PT_TDMOP:
return OLD_PT_TDMOP;
}
DISSECTOR_ASSERT(FALSE);

View File

@ -27,6 +27,8 @@
#include "tvbuff.h"
#include "address.h"
struct endpoint;
/** @file
* Dissected packet data and metadata.
*/
@ -83,6 +85,8 @@ typedef struct _packet_info {
guint32 destport; /**< destination port */
guint32 match_uint; /**< matched uint for calling subdissector from table */
const char *match_string; /**< matched string for calling subdissector from table */
gboolean use_endpoint; /**< TRUE if endpoint member should be used for conversations */
struct endpoint* conv_endpoint; /**< Data that can be used for conversations */
guint16 can_desegment; /**< >0 if this segment could be desegmented.
A dissector that can offer this API (e.g.
TCP) sets can_desegment=2, then

View File

@ -1145,7 +1145,6 @@ port_type_to_str (port_type type)
case PT_I2C: return "I2C";
case PT_IBQP: return "IBQP";
case PT_BLUETOOTH: return "BLUETOOTH";
case PT_TDMOP: return "TDMOP";
default: return "[Unknown]";
}
}