forked from osmocom/wireshark
Update: Primarily to suggest calling conversation_set_dissector()
once a packet has been identified as being part of a particular protocol. svn path=/trunk/; revision=47621
This commit is contained in:
parent
2f156d0edc
commit
32834b7881
|
@ -64,10 +64,15 @@ SCTP, TCP, TIPC and UDP dissectors all provide this capability via their
|
|||
"Try heuristic sub-dissectors first" preference, but none of them have this
|
||||
option enabled by default.
|
||||
|
||||
Once a packet for a particular "connection" has been identified as belonging
|
||||
to a particular protocol, wireshark should then be set up to always directly
|
||||
call the dissector for that protocol. This removes the overhead of having
|
||||
to identify each packet of the connection heuristically.
|
||||
|
||||
|
||||
How do these heuristics work?
|
||||
-----------------------------
|
||||
Difficult to give a general answer here. The usual heuristic works as follows:
|
||||
It's difficult to give a general answer here. The usual heuristic works as follows:
|
||||
|
||||
A HD looks into the first few packet bytes and searches for common patterns that
|
||||
are specific to the protocol in question. Most protocols starts with a
|
||||
|
@ -96,7 +101,7 @@ Heuristic Code Example
|
|||
----------------------
|
||||
You can find a lot of code examples in the wireshark sources, e.g.:
|
||||
grep -l heur_dissector_add epan/dissectors/*.c
|
||||
returns (currently) 68 files.
|
||||
returns 132 files (Feb 2013).
|
||||
|
||||
For the above example criteria, the following code example might do the work
|
||||
(combine this with the dissector skeleton in README.developer):
|
||||
|
@ -104,45 +109,68 @@ For the above example criteria, the following code example might do the work
|
|||
XXX - please note: The following code examples were not tried in reality,
|
||||
please report problems to the dev-list!
|
||||
|
||||
static gboolean dissect_PROTOABBREV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
--------------------------------------------------------------------------------------------
|
||||
static dissector_handle_t PROTOABBREV_handle;
|
||||
|
||||
static void
|
||||
dissect_PROTOABBREV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
{
|
||||
/* Dissection ... */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
dissect_PROTOABBREV_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
{
|
||||
...
|
||||
|
||||
/* 1) first byte must be 0x42 */
|
||||
if ( tvb_get_guint8(tvb, 0) != 0x42 )
|
||||
return (FALSE);
|
||||
/* 1) first byte must be 0x42 */
|
||||
if ( tvb_get_guint8(tvb, 0) != 0x42 )
|
||||
return (FALSE);
|
||||
|
||||
/* 2) second byte is a type field and only can contain values between 0x20-0x33 */
|
||||
if ( tvb_get_guint8(tvb, 1) < 0x20 || tvb_get_guint8(tvb, 1) > 0x33 )
|
||||
return (FALSE);
|
||||
/* 2) second byte is a type field and only can contain values between 0x20-0x33 */
|
||||
if ( tvb_get_guint8(tvb, 1) < 0x20 || tvb_get_guint8(tvb, 1) > 0x33 )
|
||||
return (FALSE);
|
||||
|
||||
/* 3) third byte is a flag field, where the lower 4 bits always contain the value 0 */
|
||||
if ( tvb_get_guint8(tvb, 2) & 0x0f )
|
||||
return (FALSE);
|
||||
/* 3) third byte is a flag field, where the lower 4 bits always contain the value 0 */
|
||||
if ( tvb_get_guint8(tvb, 2) & 0x0f )
|
||||
return (FALSE);
|
||||
|
||||
/* 4) fourth and fifth bytes contains a 16 bit length field, where the value can't be longer than 10000 bytes */
|
||||
/* Assumes network byte order */
|
||||
if ( tvb_get_ntohs(tvb, 3) > 10000 )
|
||||
return (FALSE);
|
||||
/* 4) fourth and fifth bytes contains a 16 bit length field, where the value can't be longer than 10000 bytes */
|
||||
/* Assumes network byte order */
|
||||
if ( tvb_get_ntohs(tvb, 3) > 10000 )
|
||||
return (FALSE);
|
||||
|
||||
/* Assume it's your packet and do dissection */
|
||||
...
|
||||
/* Assume it's your packet ... */
|
||||
|
||||
return (TRUE);
|
||||
/* specify that dissect_PROTOABBREV is to be called directly from now on for packets for this "connection" ... */
|
||||
conversation = find_or_create_conversation(pinfo);
|
||||
conversation_set_dissector(conversation, PROTOABBREV_handle);
|
||||
|
||||
/* and do the dissection 8/
|
||||
dissect_PROTOABBREV(tvb, pinfo, tree, data);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
proto_reg_handoff_PROTOABBREV(void)
|
||||
{
|
||||
static int PROTOABBREV_inited = FALSE;
|
||||
PROABBREV_handle = create_dissector_handle(dissect_PROTOABBREV,
|
||||
proto_PROTOABBREV);
|
||||
|
||||
if ( !PROTOABBREV_inited )
|
||||
{
|
||||
/* register as heuristic dissector for both TCP and UDP */
|
||||
heur_dissector_add("tcp", dissect_PROTOABBREV, proto_PROTOABBREV);
|
||||
heur_dissector_add("udp", dissect_PROTOABBREV, proto_PROTOABBREV);
|
||||
}
|
||||
/* register as heuristic dissector for both TCP and UDP */
|
||||
heur_dissector_add("tcp", dissect_PROTOABBREV, proto_PROTOABBREV);
|
||||
heur_dissector_add("udp", dissect_PROTOABBREV, proto_PROTOABBREV);
|
||||
|
||||
#ifdef OPTIONAL
|
||||
/* It's possible to write a dissector to be a dual heuristic/normal dissector */
|
||||
/* by also registering the dissector "normally". */
|
||||
dissector_add_uint("ip.proto", IP_PROTO_PROTOABBREV, PROTOABBREV_handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,58 +183,5 @@ tendency to reuse known port numbers for new protocols. But TCP and UDP are
|
|||
not the only dissectors that provide support for HDs. You can find more
|
||||
examples by searching the Wireshark sources as follows:
|
||||
grep -l register_heur_dissector_list epan/dissectors/packet-*.c
|
||||
returns (currently) 25 files.
|
||||
|
||||
It's possible to write a dissector to be a dual heuristic/normal dissector.
|
||||
In that the case, dissect_PROTOABBREV should return an int with the number of
|
||||
bytes dissected by your protocol rather than simply returning TRUE. If
|
||||
heuristics fail, still just return 0.
|
||||
|
||||
|
||||
static int dissect_PROTOABBREV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
...
|
||||
|
||||
/* 1) first byte must be 0x42 */
|
||||
if ( tvb_get_guint8(tvb, 0) != 0x42 )
|
||||
return 0;
|
||||
|
||||
/* 2) second byte is a type field and only can contain values between 0x20-0x33 */
|
||||
if ( tvb_get_guint8(tvb, 1) < 0x20 || tvb_get_guint8(tvb, 1) > 0x33 )
|
||||
return 0;
|
||||
|
||||
/* 3) third byte is a flag field, where the lower 4 bits always contain the value 0 */
|
||||
if ( tvb_get_guint8(tvb, 2) & 0x0f )
|
||||
return 0;
|
||||
|
||||
/* 4) fourth and fifth bytes contains a 16 bit length field, where the value can't be longer than 10000 bytes */
|
||||
/* Assumes network byte order */
|
||||
if ( tvb_get_ntohs(tvb, 3) > 10000 )
|
||||
return 0;
|
||||
|
||||
/* Assume it's your packet and do dissection */
|
||||
...
|
||||
|
||||
return number_of_bytes_dissected;
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_PROTOABBREV(void)
|
||||
{
|
||||
static int PROTOABBREV_inited = FALSE;
|
||||
dissector_handle_t PROTOABBREV_handle;
|
||||
|
||||
if ( !PROTOABBREV_inited )
|
||||
{
|
||||
/* register as heuristic dissector for both TCP and UDP */
|
||||
heur_dissector_add("tcp", dissect_PROTOABBREV, proto_PROTOABBREV);
|
||||
heur_dissector_add("udp", dissect_PROTOABBREV, proto_PROTOABBREV);
|
||||
|
||||
/* register as normal dissector for IP as well */
|
||||
PROTOABBREV_handle = new_create_dissector_handle(dissect_PROTOABBREV,
|
||||
proto_PROTOABBREV);
|
||||
dissector_add_uint("ip.proto", IP_PROTO_PROTOABBREV, PROTOABBREV_handle);
|
||||
PROTOABBREV_inited = TRUE;
|
||||
}
|
||||
}
|
||||
returns 38 files (Feb 2013).
|
||||
|
||||
|
|
Loading…
Reference in New Issue