whois, finger: Dissect at FIN (or after) on first pass

The WHOIS and finger dissectors wait to dissect at FIN, but they
need to actually dissect at FIN (or at reassembled out of order
segments after FIN) on the first pass instead of returning without
dissecting.

Only add data reassembled at FIN to the tree if it was actually
reassembled at the FIN frame; if it was reassembled in the first pass
at a later frame due to out of order segments, it will be added there.

In addition to fixing first pass dissection, this also fixes the
case where the FIN segment is the first segment with data. Fix #18037.
This commit is contained in:
John Thacker 2022-04-12 08:29:48 -04:00
parent 3aee6ce9d6
commit 4c7865c81b
3 changed files with 19 additions and 5 deletions

View File

@ -14,6 +14,8 @@
#include <epan/conversation.h>
#include <epan/expert.h>
#include "packet-tcp.h"
void proto_register_finger(void);
void proto_reg_handoff_finger(void);
@ -38,7 +40,7 @@ typedef struct _finger_transaction_t {
static int
dissect_finger(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
void *data _U_)
void *data)
{
proto_item *ti, *expert_ti;
proto_tree *finger_tree;
@ -46,6 +48,7 @@ dissect_finger(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
finger_transaction_t *finger_trans;
gboolean is_query;
guint len;
struct tcpinfo *tcpinfo = (struct tcpinfo*)data;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "FINGER");
@ -76,7 +79,11 @@ dissect_finger(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
finger_trans->req_frame = pinfo->num;
finger_trans->req_time = pinfo->abs_ts;
}
} else {
} else if (!(tcpinfo && (IS_TH_FIN(tcpinfo->flags) || tcpinfo->is_reassembled))) {
/* If this is the FIN (or already desegmented, as with an out
* of order segment received after FIN) go ahead and dissect
* on the first pass.
*/
pinfo->desegment_len = DESEGMENT_UNTIL_FIN;
pinfo->desegment_offset = 0;
return -1;

View File

@ -7728,7 +7728,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
tcph->th_seq - msp->seq,
tcph->th_seglen,
FALSE );
if(ipfd_head) {
if(ipfd_head && ipfd_head->reassembled_in == pinfo->num && ipfd_head->reas_in_layer_num == pinfo->curr_layer_num) {
tvbuff_t *next_tvb;
/* create a new TVB structure for desegmented data

View File

@ -14,6 +14,8 @@
#include <epan/conversation.h>
#include <epan/expert.h>
#include "packet-tcp.h"
#define WHOIS_PORT 43 /* This is the registered IANA port (nicname) */
void proto_register_whois(void);
@ -39,7 +41,7 @@ typedef struct _whois_transaction_t {
static int
dissect_whois(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
void *data _U_)
void *data)
{
proto_item *ti, *expert_ti;
proto_tree *whois_tree;
@ -47,6 +49,7 @@ dissect_whois(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
whois_transaction_t *whois_trans;
gboolean is_query;
guint len;
struct tcpinfo *tcpinfo = (struct tcpinfo*)data;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "WHOIS");
@ -90,7 +93,11 @@ dissect_whois(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
whois_trans->req_frame = pinfo->num;
whois_trans->req_time = pinfo->abs_ts;
}
} else {
} else if (!(tcpinfo && (IS_TH_FIN(tcpinfo->flags) || tcpinfo->is_reassembled))) {
/* If this is the FIN (or already desegmented, as with an out
* of order segment received after FIN) go ahead and dissect
* on the first pass.
*/
pinfo->desegment_len = DESEGMENT_UNTIL_FIN;
pinfo->desegment_offset = 0;
return -1;