forked from osmocom/wireshark
Update the "Following Conversations" section to use se_alloc() instead of GMemChunks.
Also: add information about the conversation_set_dissector() function. svn path=/trunk/; revision=35185
This commit is contained in:
parent
9da77c4716
commit
2798debd90
|
@ -2937,25 +2937,29 @@ address:port combinations. A conversation is not sensitive to the direction of
|
||||||
the packet. The same conversation will be returned for a packet bound from
|
the packet. The same conversation will be returned for a packet bound from
|
||||||
ServerA:1000 to ClientA:2000 and the packet from ClientA:2000 to ServerA:1000.
|
ServerA:1000 to ClientA:2000 and the packet from ClientA:2000 to ServerA:1000.
|
||||||
|
|
||||||
There are five routines that you will use to work with a conversation:
|
2.2.1 Conversation Routines
|
||||||
|
|
||||||
|
There are six routines that you will use to work with a conversation:
|
||||||
conversation_new, find_conversation, conversation_add_proto_data,
|
conversation_new, find_conversation, conversation_add_proto_data,
|
||||||
conversation_get_proto_data, and conversation_delete_proto_data.
|
conversation_get_proto_data, conversation_delete_proto_data,
|
||||||
|
and conversation_set_dissector.
|
||||||
|
|
||||||
|
|
||||||
2.2.1 The conversation_init function.
|
2.2.1.1 The conversation_init function.
|
||||||
|
|
||||||
This is an internal routine for the conversation code. As such you
|
This is an internal routine for the conversation code. As such you
|
||||||
will not have to call this routine. Just be aware that this routine is
|
will not have to call this routine. Just be aware that this routine is
|
||||||
called at the start of each capture and before the packets are filtered
|
called at the start of each capture and before the packets are filtered
|
||||||
with a display filter. The routine will destroy all stored
|
with a display filter. The routine will destroy all stored
|
||||||
conversations. This routine does NOT clean up any data pointers that are
|
conversations. This routine does NOT clean up any data pointers that are
|
||||||
passed in the conversation_new 'data' variable. You are responsible for
|
passed in the conversation_add_proto_data 'data' variable. You are
|
||||||
this clean up if you pass a malloc'ed pointer in this variable.
|
responsible for this clean up if you pass a malloc'ed pointer
|
||||||
|
in this variable.
|
||||||
|
|
||||||
See item 2.2.8 for more information about the 'data' pointer.
|
See item 2.2.1.5 for more information about use of the 'data' pointer.
|
||||||
|
|
||||||
|
|
||||||
2.2.2 The conversation_new function.
|
2.2.1.2 The conversation_new function.
|
||||||
|
|
||||||
This routine will create a new conversation based upon two address/port
|
This routine will create a new conversation based upon two address/port
|
||||||
pairs. If you want to associate with the conversation a pointer to a
|
pairs. If you want to associate with the conversation a pointer to a
|
||||||
|
@ -3001,7 +3005,7 @@ packet indicates that, later in the capture, a conversation will be
|
||||||
created using certain addresses and ports, in the case where the packet
|
created using certain addresses and ports, in the case where the packet
|
||||||
doesn't specify the addresses and ports of both sides.
|
doesn't specify the addresses and ports of both sides.
|
||||||
|
|
||||||
2.2.3 The find_conversation function.
|
2.2.1.3 The find_conversation function.
|
||||||
|
|
||||||
Call this routine to look up a conversation. If no conversation is found,
|
Call this routine to look up a conversation. If no conversation is found,
|
||||||
the routine will return a NULL value.
|
the routine will return a NULL value.
|
||||||
|
@ -3051,7 +3055,7 @@ any "wildcarded" address and the "port_b" port will be treated as
|
||||||
matching any "wildcarded" port.
|
matching any "wildcarded" port.
|
||||||
|
|
||||||
|
|
||||||
2.2.4 The find_or_create_conversation function.
|
2.2.1.4 The find_or_create_conversation function.
|
||||||
|
|
||||||
This convenience function will create find an existing conversation (by calling
|
This convenience function will create find an existing conversation (by calling
|
||||||
find_conversation()) and, if a conversation does not already exist, create a
|
find_conversation()) and, if a conversation does not already exist, create a
|
||||||
|
@ -3069,7 +3073,7 @@ conversation_new() are taken from the pinfo structure (as is commonly done)
|
||||||
and no 'options' are used.
|
and no 'options' are used.
|
||||||
|
|
||||||
|
|
||||||
2.2.5 The conversation_add_proto_data function.
|
2.2.1.5 The conversation_add_proto_data function.
|
||||||
|
|
||||||
Once you have created a conversation with conversation_new, you can
|
Once you have created a conversation with conversation_new, you can
|
||||||
associate data with it using this function.
|
associate data with it using this function.
|
||||||
|
@ -3088,11 +3092,14 @@ Where:
|
||||||
unique protocol number created with proto_register_protocol. Protocols
|
unique protocol number created with proto_register_protocol. Protocols
|
||||||
are typically registered in the proto_register_XXXX section of your
|
are typically registered in the proto_register_XXXX section of your
|
||||||
dissector. "data" is a pointer to the data you wish to associate with the
|
dissector. "data" is a pointer to the data you wish to associate with the
|
||||||
conversation. Using the protocol number allows several dissectors to
|
conversation. "data" usually points to "se_alloc'd" memory; the
|
||||||
|
memory will be automatically freed each time a new dissection begins
|
||||||
|
and thus need not be managed (freed) by the dissector.
|
||||||
|
Using the protocol number allows several dissectors to
|
||||||
associate data with a given conversation.
|
associate data with a given conversation.
|
||||||
|
|
||||||
|
|
||||||
2.2.6 The conversation_get_proto_data function.
|
2.2.1.6 The conversation_get_proto_data function.
|
||||||
|
|
||||||
After you have located a conversation with find_conversation, you can use
|
After you have located a conversation with find_conversation, you can use
|
||||||
this function to retrieve any data associated with it.
|
this function to retrieve any data associated with it.
|
||||||
|
@ -3111,12 +3118,12 @@ typically in the proto_register_XXXX portion of a dissector. The function
|
||||||
returns a pointer to the data requested, or NULL if no data was found.
|
returns a pointer to the data requested, or NULL if no data was found.
|
||||||
|
|
||||||
|
|
||||||
2.2.7 The conversation_delete_proto_data function.
|
2.2.1.7 The conversation_delete_proto_data function.
|
||||||
|
|
||||||
After you are finished with a conversation, you can remove your association
|
After you are finished with a conversation, you can remove your association
|
||||||
with this function. Please note that ONLY the conversation entry is
|
with this function. Please note that ONLY the conversation entry is
|
||||||
removed. If you have allocated any memory for your data, you must free it
|
removed. If you have allocated any memory for your data (other than with se_alloc),
|
||||||
as well.
|
you must free it as well.
|
||||||
|
|
||||||
The conversation_delete_proto_data prototype:
|
The conversation_delete_proto_data prototype:
|
||||||
|
|
||||||
|
@ -3130,8 +3137,22 @@ Where:
|
||||||
is a unique protocol number created with proto_register_protocol,
|
is a unique protocol number created with proto_register_protocol,
|
||||||
typically in the proto_register_XXXX portion of a dissector.
|
typically in the proto_register_XXXX portion of a dissector.
|
||||||
|
|
||||||
|
2.2.1.8 The conversation_set_dissector function
|
||||||
|
|
||||||
2.2.8 Using timestamps relative to the conversation
|
This function sets the protocol dissector to be invoked whenever
|
||||||
|
conversation parameters (addresses, port_types, ports, etc) are matched
|
||||||
|
during the dissection of a packet.
|
||||||
|
|
||||||
|
The conversation_set_dissector prototype:
|
||||||
|
|
||||||
|
void conversation_set_dissector(conversation_t *conversation, const dissector_handle_t handle);
|
||||||
|
|
||||||
|
Where:
|
||||||
|
conversation_t *conv = the conversation in question
|
||||||
|
const dissector_handle_t handle = the dissector handle.
|
||||||
|
|
||||||
|
|
||||||
|
2.2.2 Using timestamps relative to the conversation
|
||||||
|
|
||||||
There is a framework to calculate timestamps relative to the start of the
|
There is a framework to calculate timestamps relative to the start of the
|
||||||
conversation. First of all the timestamp of the first packet that has been
|
conversation. First of all the timestamp of the first packet that has been
|
||||||
|
@ -3178,33 +3199,22 @@ SVN 23058 to see the implementation of conversation timestamps for
|
||||||
the tcp-dissector.
|
the tcp-dissector.
|
||||||
|
|
||||||
|
|
||||||
2.2.9 The example conversation code with GMemChunk's.
|
2.2.3 The example conversation code using se_alloc'd memory.
|
||||||
|
|
||||||
For a conversation between two IP addresses and ports you can use this as an
|
For a conversation between two IP addresses and ports you can use this as an
|
||||||
example. This example uses the GMemChunk to allocate memory and stores the data
|
example. This example uses se_alloc() to allocate memory and stores the data
|
||||||
pointer in the conversation 'data' variable.
|
pointer in the conversation 'data' variable.
|
||||||
|
|
||||||
NOTE: Remember to register the init routine (my_dissector_init) in the
|
|
||||||
protocol_register routine.
|
|
||||||
|
|
||||||
|
|
||||||
/************************ Global values ************************/
|
/************************ Global values ************************/
|
||||||
|
|
||||||
/* the number of entries in the memory chunk array */
|
|
||||||
#define my_init_count 10
|
|
||||||
|
|
||||||
/* define your structure here */
|
/* define your structure here */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
} my_entry_t;
|
} my_entry_t;
|
||||||
|
|
||||||
/* the GMemChunk base structure */
|
|
||||||
static GMemChunk *my_vals = NULL;
|
|
||||||
|
|
||||||
/* Registered protocol number */
|
/* Registered protocol number */
|
||||||
static int my_proto = -1;
|
static int my_proto = -1;
|
||||||
|
|
||||||
|
|
||||||
/********************* in the dissector routine *********************/
|
/********************* in the dissector routine *********************/
|
||||||
|
|
||||||
/* the local variables in the dissector */
|
/* the local variables in the dissector */
|
||||||
|
@ -3225,7 +3235,7 @@ else {
|
||||||
|
|
||||||
/* new conversation create local data structure */
|
/* new conversation create local data structure */
|
||||||
|
|
||||||
data_ptr = g_mem_chunk_alloc(my_vals);
|
data_ptr = se_alloc(sizeof(my_entry_t));
|
||||||
|
|
||||||
/*** add your code here to setup the new data structure ***/
|
/*** add your code here to setup the new data structure ***/
|
||||||
|
|
||||||
|
@ -3238,38 +3248,12 @@ else {
|
||||||
|
|
||||||
/* at this point the conversation data is ready */
|
/* at this point the conversation data is ready */
|
||||||
|
|
||||||
|
|
||||||
/******************* in the dissector init routine *******************/
|
|
||||||
|
|
||||||
#define my_init_count 20
|
|
||||||
|
|
||||||
static void
|
|
||||||
my_dissector_init(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* destroy memory chunks if needed */
|
|
||||||
|
|
||||||
if (my_vals)
|
|
||||||
g_mem_chunk_destroy(my_vals);
|
|
||||||
|
|
||||||
/* now create memory chunks */
|
|
||||||
|
|
||||||
my_vals = g_mem_chunk_new("my_proto_vals",
|
|
||||||
sizeof(my_entry_t),
|
|
||||||
my_init_count * sizeof(my_entry_t),
|
|
||||||
G_ALLOC_AND_FREE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************** in the protocol register routine *****************/
|
/***************** in the protocol register routine *****************/
|
||||||
|
|
||||||
/* register re-init routine */
|
|
||||||
|
|
||||||
register_init_routine(&my_dissector_init);
|
|
||||||
|
|
||||||
my_proto = proto_register_protocol("My Protocol", "My Protocol", "my_proto");
|
my_proto = proto_register_protocol("My Protocol", "My Protocol", "my_proto");
|
||||||
|
|
||||||
|
|
||||||
2.2.10 An example conversation code that starts at a specific frame number.
|
2.2.4 An example conversation code that starts at a specific frame number.
|
||||||
|
|
||||||
Sometimes a dissector has determined that a new conversation is needed that
|
Sometimes a dissector has determined that a new conversation is needed that
|
||||||
starts at a specific frame number, when a capture session encompasses multiple
|
starts at a specific frame number, when a capture session encompasses multiple
|
||||||
|
@ -3293,7 +3277,7 @@ that starts at the specific frame number.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
2.2.11 The example conversation code using conversation index field.
|
2.2.5 The example conversation code using conversation index field.
|
||||||
|
|
||||||
Sometimes the conversation isn't enough to define a unique data storage
|
Sometimes the conversation isn't enough to define a unique data storage
|
||||||
value for the network traffic. For example if you are storing information
|
value for the network traffic. For example if you are storing information
|
||||||
|
@ -3328,10 +3312,10 @@ upon the conversation index and values inside the request packets.
|
||||||
opcode = 0;
|
opcode = 0;
|
||||||
if (!request_val && !reply)
|
if (!request_val && !reply)
|
||||||
{
|
{
|
||||||
new_request_key = g_mem_chunk_alloc(afs_request_keys);
|
new_request_key = se_alloc(sizeof(struct afs_request_key));
|
||||||
*new_request_key = request_key;
|
*new_request_key = request_key;
|
||||||
|
|
||||||
request_val = g_mem_chunk_alloc(afs_request_vals);
|
request_val = se_alloc(sizeof(struct afs_request_val));
|
||||||
request_val -> opcode = pntohl(&afsh->opcode);
|
request_val -> opcode = pntohl(&afsh->opcode);
|
||||||
opcode = request_val->opcode;
|
opcode = request_val->opcode;
|
||||||
|
|
||||||
|
@ -3394,7 +3378,7 @@ static void sub_dissector(tvbuff_t *tvb, packet_info *pinfo,
|
||||||
*/
|
*/
|
||||||
conversation = find_conversation(pinfo->fd->num,
|
conversation = find_conversation(pinfo->fd->num,
|
||||||
&pinfo->src, &pinfo->dst, protocol,
|
&pinfo->src, &pinfo->dst, protocol,
|
||||||
src_port, dst_port, new_conv_info, 0);
|
src_port, dst_port, 0);
|
||||||
|
|
||||||
/* If there is no such conversation, or if there is one but for
|
/* If there is no such conversation, or if there is one but for
|
||||||
someone else's protocol then we just create a new conversation
|
someone else's protocol then we just create a new conversation
|
||||||
|
@ -3402,7 +3386,7 @@ static void sub_dissector(tvbuff_t *tvb, packet_info *pinfo,
|
||||||
*/
|
*/
|
||||||
if ( (conversation == NULL) ||
|
if ( (conversation == NULL) ||
|
||||||
(conversation->dissector_handle != sub_dissector_handle) ) {
|
(conversation->dissector_handle != sub_dissector_handle) ) {
|
||||||
new_conv_info = g_mem_chunk_alloc(new_conv_vals);
|
new_conv_info = se_alloc(sizeof(struct _new_conv_info));
|
||||||
new_conv_info->data1 = value1;
|
new_conv_info->data1 = value1;
|
||||||
|
|
||||||
/* create the conversation for the dynamic port */
|
/* create the conversation for the dynamic port */
|
||||||
|
@ -3476,7 +3460,7 @@ static dissector_handle_t sub_dissector_handle;
|
||||||
|
|
||||||
/* if conversation has a data field, create it and load structure */
|
/* if conversation has a data field, create it and load structure */
|
||||||
|
|
||||||
new_conv_info = g_mem_chunk_alloc(new_conv_vals);
|
new_conv_info = se_alloc(sizeof(struct _new_conv_info));
|
||||||
new_conv_info->data1 = value1;
|
new_conv_info->data1 = value1;
|
||||||
|
|
||||||
/* create the conversation for the dynamic server address and port */
|
/* create the conversation for the dynamic server address and port */
|
||||||
|
|
Loading…
Reference in New Issue