aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-tcp.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2004-08-26 10:03:40 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2004-08-26 10:03:40 +0000
commit58b6e2f49f2b44441211a512c537f7c28962aa96 (patch)
tree544caf05a5e385730124e828c5b47e46655022c4 /epan/dissectors/packet-tcp.c
parent5d1de30923e73ef647c0f4445a961944624d1cbb (diff)
fix to that long outstanding bug with windowscaling
If window scaling is NOT offered in the SYN+ACK then window scaling will not be used at all, so clear it if we saw it offered previously in the SYN packet. If the window is scaled in a packet, make ethereal display that by appendign the string " (scaled)" to the end of the tcp.window line in the decode pane. svn path=/trunk/; revision=11837
Diffstat (limited to 'epan/dissectors/packet-tcp.c')
-rw-r--r--epan/dissectors/packet-tcp.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index a4f56445eb..fbf1e3d070 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -487,6 +487,26 @@ pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nx
*/
}
+/* This is called for SYN+ACK packets and the purpose is to verify that we
+ * have seen window scaling in both directions.
+ * If we cant find window scaling being set in both directions
+ * that means it was present in the SYN but not in the SYN+ACK
+ * (or the SYN was missing) and then we disable the window scaling
+ * for this tcp session.
+ */
+static void verify_tcp_window_scaling(packet_info *pinfo)
+{
+ struct tcp_analysis *tcpd=NULL;
+
+ /* find(or create if needed) the conversation for this tcp session */
+ tcpd=get_tcp_conversation_data(pinfo);
+
+ if( (tcpd->win_scale1==-1) || (tcpd->win_scale2==-1) ){
+ tcpd->win_scale1=-1;
+ tcpd->win_scale2=-1;
+ }
+}
+
/* if we saw a window scaling option, store it for future reference
*/
static void pdu_store_window_scale_option(packet_info *pinfo, guint8 ws)
@@ -2530,6 +2550,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
vec_t cksum_vec[4];
guint32 phdr[2];
guint16 computed_cksum;
+ guint16 real_window;
guint length_remaining;
gboolean desegment_ok;
struct tcpinfo tcpinfo;
@@ -2588,6 +2609,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
th_off_x2 = tvb_get_guint8(tvb, offset + 12);
tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
+ real_window = tcph->th_win;
tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
/*
@@ -2724,7 +2746,11 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
- proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
+ if(tcp_relative_seq && (tcph->th_win!=real_window)){
+ proto_tree_add_uint_format(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win, "Window size: %d (scaled)", tcph->th_win);
+ } else {
+ proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
+ }
}
/* Supply the sequence number of the first byte and of the first byte
@@ -2863,6 +2889,15 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
}
+ /* If there was window scaling in the SYN packet byt none in the SYN+ACK
+ * then we should just forget about the windowscaling completely.
+ */
+ if(!pinfo->fd->flags.visited){
+ if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
+ verify_tcp_window_scaling(pinfo);
+ }
+ }
+
/* Skip over header + options */
offset += tcph->th_hlen;