From d11c069786bf57e38142e8628845304519cae270 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 7 Nov 2021 16:41:39 +0100 Subject: [PATCH] BBLog: Fix support of TCP window scaling Rcv.Wind.Shift and Snd.Wind.Shift were not displayed correctly by the BBLog dissector and the TCP dissector was not using the information about the shift values available in the BBLog file. --- epan/dissectors/packet-bblog.c | 8 +++---- epan/dissectors/packet-frame.c | 39 +++++++++++++++++++++++++++++++++- epan/dissectors/packet-tcp.c | 18 ++++++++-------- epan/packet.c | 2 ++ epan/packet_info.h | 3 +++ wiretap/wtap_opttypes.h | 8 +++++++ 6 files changed, 64 insertions(+), 14 deletions(-) diff --git a/epan/dissectors/packet-bblog.c b/epan/dissectors/packet-bblog.c index 68daad05f0..1125b743db 100644 --- a/epan/dissectors/packet-bblog.c +++ b/epan/dissectors/packet-bblog.c @@ -248,8 +248,8 @@ static const true_false_string event_flags_stack = { "Stack specific information not available" }; -#define SND_SCALE_MASK 0xf0 -#define RCV_SCALE_MASK 0x0f +#define SND_SCALE_MASK 0x0f +#define RCV_SCALE_MASK 0xf0 /* * The structures used here are defined in @@ -376,8 +376,8 @@ proto_register_bblog(void) { &hf_flex_2, { "Flex 2", "bblog.flex_2", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} }, { &hf_first_byte_in, { "Time of First Byte In", "bblog.first_byte_in", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} }, { &hf_first_byte_out, { "Time of First Byte Out", "bblog.first_byte_out", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} }, - { &hf_snd_scale, { "Shift Count for Send Window", "bblog.snd_shift", FT_UINT8, BASE_DEC, NULL, SND_SCALE_MASK, NULL, HFILL} }, - { &hf_rcv_scale, { "Shift Count for Receive Window", "bblog.rcv_shift", FT_UINT8, BASE_DEC, NULL, RCV_SCALE_MASK, NULL, HFILL} }, + { &hf_snd_scale, { "Snd.Wind.Shift", "bblog.snd_shift", FT_UINT8, BASE_DEC, NULL, SND_SCALE_MASK, NULL, HFILL} }, + { &hf_rcv_scale, { "Rcv.Wind.Shift", "bblog.rcv_shift", FT_UINT8, BASE_DEC, NULL, RCV_SCALE_MASK, NULL, HFILL} }, { &hf_pad_1, { "Padding", "bblog.pad_1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} }, { &hf_pad_2, { "Padding", "bblog.pad_2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} }, { &hf_pad_3, { "Padding", "bblog.pad_3", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} }, diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c index ac63ba34a1..83a53f7e79 100644 --- a/epan/dissectors/packet-frame.c +++ b/epan/dissectors/packet-frame.c @@ -357,6 +357,7 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* dissector_handle_t dissector_handle; fr_foreach_t fr_user_data; struct nflx_tcpinfo tcpinfo; + gboolean tcpinfo_filled; tree=parent_tree; @@ -439,6 +440,42 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* break; } } + + if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nflx_custom_option(fr_data->pkt_block, + NFLX_OPT_TYPE_TCPINFO, + (char *)&tcpinfo, + sizeof(struct nflx_tcpinfo))) { + tcpinfo_filled = true; + if ((tcpinfo.tlb_flags & NFLX_TLB_TF_REQ_SCALE) && + (tcpinfo.tlb_flags & NFLX_TLB_TF_RCVD_SCALE)) { + /* TCP WS option has been sent and received. */ + switch (pinfo->p2p_dir) { + case P2P_DIR_RECV: + pinfo->src_win_scale = tcpinfo.tlb_snd_scale; + pinfo->dst_win_scale = tcpinfo.tlb_rcv_scale; + break; + case P2P_DIR_SENT: + pinfo->src_win_scale = tcpinfo.tlb_rcv_scale; + pinfo->dst_win_scale = tcpinfo.tlb_snd_scale; + break; + case P2P_DIR_UNKNOWN: + pinfo->src_win_scale = -1; /* unknown */ + pinfo->dst_win_scale = -1; /* unknown */ + break; + default: + DISSECTOR_ASSERT_NOT_REACHED(); + } + } else if (NFLX_TLB_IS_SYNCHRONIZED(tcpinfo.tlb_state)) { + /* TCP connection is in a synchronized state. */ + pinfo->src_win_scale = -2; /* window scaling disabled */ + pinfo->dst_win_scale = -2; /* window scaling disabled */ + } else { + pinfo->src_win_scale = -1; /* unknown */ + pinfo->dst_win_scale = -1; /* unknown */ + } + } else { + tcpinfo_filled = false; + } break; case REC_TYPE_FT_SPECIFIC_EVENT: @@ -787,7 +824,7 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* proto_tree_add_uint(fh_tree, hf_link_number, tvb, 0, 0, pinfo->link_number); } - if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nflx_custom_option(fr_data->pkt_block, NFLX_OPT_TYPE_TCPINFO, (char *)&tcpinfo, sizeof(struct nflx_tcpinfo))) { + if (tcpinfo_filled) { proto_tree *bblog_tree; proto_item *bblog_item; diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index 2012af1e69..666fec559c 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -1540,18 +1540,18 @@ process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo, static struct tcp_analysis * -init_tcp_conversation_data(packet_info *pinfo) +init_tcp_conversation_data(packet_info *pinfo, int direction) { struct tcp_analysis *tcpd; /* Initialize the tcp protocol data structure to add to the tcp conversation */ tcpd=wmem_new0(wmem_file_scope(), struct tcp_analysis); - tcpd->flow1.win_scale=-1; + tcpd->flow1.win_scale = (direction >= 0) ? pinfo->src_win_scale : pinfo->dst_win_scale; tcpd->flow1.window = G_MAXUINT32; tcpd->flow1.multisegment_pdus=wmem_tree_new(wmem_file_scope()); tcpd->flow2.window = G_MAXUINT32; - tcpd->flow2.win_scale=-1; + tcpd->flow2.win_scale = (direction >= 0) ? pinfo->dst_win_scale : pinfo->src_win_scale; tcpd->flow2.multisegment_pdus=wmem_tree_new(wmem_file_scope()); /* Only allocate the data if its actually going to be analyzed */ @@ -1632,13 +1632,18 @@ get_tcp_conversation_data(conversation_t *conv, packet_info *pinfo) /* Get the data for this conversation */ tcpd=(struct tcp_analysis *)conversation_get_proto_data(conv, proto_tcp); + direction = cmp_address(&pinfo->src, &pinfo->dst); + /* if the addresses are equal, match the ports instead */ + if (direction == 0) { + direction = (pinfo->srcport > pinfo->destport) ? 1 : -1; + } /* If the conversation was just created or it matched a * conversation with template options, tcpd will not * have been initialized. So, initialize * a new tcpd structure for the conversation. */ if (!tcpd) { - tcpd = init_tcp_conversation_data(pinfo); + tcpd = init_tcp_conversation_data(pinfo, direction); conversation_add_proto_data(conv, proto_tcp, tcpd); } @@ -1647,11 +1652,6 @@ get_tcp_conversation_data(conversation_t *conv, packet_info *pinfo) } /* check direction and get ua lists */ - direction=cmp_address(&pinfo->src, &pinfo->dst); - /* if the addresses are equal, match the ports instead */ - if(direction==0) { - direction= (pinfo->srcport > pinfo->destport) ? 1 : -1; - } if(direction>=0) { tcpd->fwd=&(tcpd->flow1); tcpd->rev=&(tcpd->flow2); diff --git a/epan/packet.c b/epan/packet.c index 611bccdc49..33174b72b7 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -593,6 +593,8 @@ dissect_record(epan_dissect_t *edt, int file_type_subtype, edt->pi.conv_endpoint = NULL; edt->pi.p2p_dir = P2P_DIR_UNKNOWN; edt->pi.link_dir = LINK_DIR_UNKNOWN; + edt->pi.src_win_scale = -1; /* unknown Rcv.Wind.Shift */ + edt->pi.dst_win_scale = -1; /* unknown Rcv.Wind.Shift */ edt->pi.layers = wmem_list_new(edt->pi.pool); edt->tvb = tvb; diff --git a/epan/packet_info.h b/epan/packet_info.h index 0c71af8ede..439c5880c1 100644 --- a/epan/packet_info.h +++ b/epan/packet_info.h @@ -141,6 +141,9 @@ typedef struct _packet_info { int link_dir; /**< 3GPP messages are sometime different UP link(UL) or Downlink(DL) */ + gint16 src_win_scale; /**< Rcv.Wind.Shift src applies when sending segments; -1 unknown; -2 disabled */ + gint16 dst_win_scale; /**< Rcv.Wind.Shift dst applies when sending segments; -1 unknown; -2 disabled */ + GSList* proto_data; /**< Per packet proto data */ GSList* dependent_frames; /**< A list of frames which this one depends on */ diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h index 1b242adb7c..1d0bb7ab8f 100644 --- a/wiretap/wtap_opttypes.h +++ b/wiretap/wtap_opttypes.h @@ -432,6 +432,14 @@ struct nflx_dumpinfo { #define NFLX_TLB_FLAG_VERBOSE 0x0008 /* Includes function/line numbers */ #define NFLX_TLB_FLAG_STACKINFO 0x0010 /* Includes stack-specific info */ +/* Flags used in tlb_flags */ +#define NFLX_TLB_TF_REQ_SCALE 0x00000020 /* Sent WS option */ +#define NFLX_TLB_TF_RCVD_SCALE 0x00000040 /* Received WS option */ + +/* Values of tlb_state */ +#define NFLX_TLB_TCPS_ESTABLISHED 4 +#define NFLX_TLB_IS_SYNCHRONIZED(state) (state >= NFLX_TLB_TCPS_ESTABLISHED) + struct nflx_tcpinfo { guint64 tlb_tv_sec; guint64 tlb_tv_usec;