diff options
-rw-r--r-- | doc/README.dissector | 9 | ||||
-rw-r--r-- | docbook/wsdg_src/WSDG_chapter_dissection.asciidoc | 27 | ||||
-rw-r--r-- | epan/dissectors/packet-tcp.c | 28 | ||||
-rw-r--r-- | epan/dissectors/packet-tcp.h | 3 |
4 files changed, 34 insertions, 33 deletions
diff --git a/doc/README.dissector b/doc/README.dissector index 10ba4e6b3f..8eefc8b06f 100644 --- a/doc/README.dissector +++ b/doc/README.dissector @@ -2972,16 +2972,17 @@ The arguments to tcp_dissect_pdus are: a routine that takes as arguments a packet_info pointer, a tvbuff pointer and an offset value representing the offset into the tvbuff at which a PDU begins, and a void pointer for user data, and should - return - *without* throwing an exception (it is guaranteed that the + return the total length of the PDU in bytes (or 0 if more bytes are + needed to determine the message length). + The routine must not throw exceptions (it is guaranteed that the number of bytes specified by the previous argument to tcp_dissect_pdus is available, but more data might not be available, - so don't refer to any data past that) - the total length of the PDU, - in bytes; + so don't refer to any data past that); a new_dissector_t routine to dissect the pdu that's passed a tvbuff pointer, packet_info pointer, proto_tree pointer and a void pointer for user data, with the tvbuff containing a possibly-reassembled PDU. (The - "reported_length" of the tvbuff will be the length of the PDU). + "reported_length" of the tvbuff will be the length of the PDU); a void pointer to user data that is passed to the length-determining routine, and the dissector routine referenced in the previous parameter. diff --git a/docbook/wsdg_src/WSDG_chapter_dissection.asciidoc b/docbook/wsdg_src/WSDG_chapter_dissection.asciidoc index 30d239294f..bd7253aeb3 100644 --- a/docbook/wsdg_src/WSDG_chapter_dissection.asciidoc +++ b/docbook/wsdg_src/WSDG_chapter_dissection.asciidoc @@ -594,7 +594,7 @@ effect. guchar *decompressed_buffer = (guchar*)g_malloc(orig_size); offset += 2; decompress_packet(tvb_get_ptr(tvb, offset, -1), - tvb_length_remaining(tvb, offset), + tvb_captured_length_remaining(tvb, offset), decompressed_buffer, orig_size); /* Now re-setup the tvb buffer to have the new data */ next_tvb = tvb_new_child_real_data(tvb, decompressed_buffer, orig_size, orig_size); @@ -618,7 +618,7 @@ So armed with the size, a buffer is allocated to receive the uncompressed data using +g_malloc()+, and the packet is decompressed into it. The +tvb_get_ptr()+ function is useful to get a pointer to the raw data of the packet from the offset onwards. In this case the decompression routine also needs to know the -length, which is given by the +tvb_length_remaining()+ function. +length, which is given by the +tvb_captured_length_remaining()+ function. Next we build a new tvb buffer from this data, using the +tvb_new_child_real_data()+ call. This data is a child of our original data, so @@ -700,7 +700,7 @@ if (flags & FL_FRAGMENT) { /* fragmented */ msg_fragment_table, /* list of message fragments */ msg_reassembled_table, /* list of reassembled messages */ msg_num, /* fragment sequence number */ - tvb_length_remaining(tvb, offset), /* fragment length - to the end */ + tvb_captured_length_remaining(tvb, offset), /* fragment length - to the end */ flags & FL_FRAG_LAST); /* More fragments? */ ---- ==== @@ -922,25 +922,28 @@ This function is implemented in 'epan/dissectors/packet-tcp.h'. #define FRAME_HEADER_LEN 8 /* This method dissects fully reassembled messages */ -static int dissect_foo_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +static int +dissect_foo_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { /* TODO: implement your dissecting code */ - return tvb_length(tvb); + return tvb_captured_length(tvb); } /* determine PDU length of protocol foo */ -static guint get_foo_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset) +static guint +get_foo_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) { /* TODO: change this to your needs */ return (guint)tvb_get_ntohl(tvb, offset+4); /* e.g. length is at offset 4 */ } /* The main dissecting routine */ -static int dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) +static int +dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN, get_foo_message_len, dissect_foo_message, data); - return tvb_length(tvb); + return tvb_captured_length(tvb); } ... @@ -951,16 +954,20 @@ As you can see this is really simple. Just call +tcp_dissect_pdus()+ in your main dissection routine and move you message parsing code into another function. This function gets called whenever a message has been reassembled. -The parameters tvb, pinfo, treeand dataare just handed over to +The parameters tvb, pinfo, tree and data are just handed over to +tcp_dissect_pdus()+. The 4th parameter is a flag to indicate if the data should be reassembled or not. This could be set according to a dissector preference as well. Parameter 5 indicates how much data has at least to be available to be able to determine the length of the foo message. Parameter 6 is a function pointer to a method that returns this length. It gets called when at least the number of bytes given in the previous parameter is available. Parameter 7 is a -function pointer to your real message dissector. Parameter 8 is a the data +function pointer to your real message dissector. Parameter 8 is the data passed in from parent dissector. +Protocols which need more data before the message length can be determined can +return zero. Other values smaller than the fixed length will result in an +exception. + [[ChDissectTap]] === How to tap protocols diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index 037a7f262f..1b8fbc51fe 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -2306,24 +2306,6 @@ again: } } -/* - * Loop for dissecting PDUs within a TCP stream; assumes that a PDU - * consists of a fixed-length chunk of data that contains enough information - * to determine the length of the PDU, followed by rest of the PDU. - * - * The first three arguments are the arguments passed to the dissector - * that calls this routine. - * - * "proto_desegment" is the dissector's flag controlling whether it should - * desegment PDUs that cross TCP segment boundaries. - * - * "fixed_len" is the length of the fixed-length part of the PDU. - * - * "get_pdu_len()" is a routine called to get the length of the PDU from - * the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset". - * - * "dissect_pdu()" is the routine to dissect a PDU. - */ void tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean proto_desegment, guint fixed_len, @@ -2379,6 +2361,16 @@ tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, * Get the length of the PDU. */ plen = (*get_pdu_len)(pinfo, tvb, offset, dissector_data); + if (plen == 0) { + /* + * Support protocols which have a variable length which cannot + * always be determined within the given fixed_len. + */ + DISSECTOR_ASSERT(proto_desegment && pinfo->can_desegment); + pinfo->desegment_offset = offset; + pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; + return; + } if (plen < fixed_len) { /* * Either: diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h index 26a95da85b..e071919db1 100644 --- a/epan/dissectors/packet-tcp.h +++ b/epan/dissectors/packet-tcp.h @@ -99,7 +99,8 @@ struct tcpinfo { * "fixed_len" is the length of the fixed-length part of the PDU. * * "get_pdu_len()" is a routine called to get the length of the PDU from - * the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset". + * the fixed-length part of the PDU; it's passed "pinfo", "tvb", "offset" and + * "dissector_data". * * "dissect_pdu()" is the routine to dissect a PDU. */ |