From 9bc67cc293cfcb130fa02543960a909c21391a92 Mon Sep 17 00:00:00 2001 From: ajeecai Date: Thu, 4 Aug 2016 17:33:18 +0800 Subject: [PATCH] Fix that ParseTcpOption doesn't work correctly Suppose there is a TCP SYN or SYN-ACK packet taking options as: 02 04 05 b4 01 01 04 02 01 03 03 04 which is Options: (12 bytes) >Maximum segment size: 1460 bytes >No-Operation (NOP) >No-Operation (NOP) >TCP SACK Permitted Option: True >No-Operation (NOP) >Window scale: 4 (multiply by 16) Then the original parse function only returns MSS 1460 while WSS is 0. --- src/Cedar/Virtual.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Cedar/Virtual.c b/src/Cedar/Virtual.c index 2ce41b02..e2d06723 100644 --- a/src/Cedar/Virtual.c +++ b/src/Cedar/Virtual.c @@ -5429,7 +5429,7 @@ SCAN_FIRST: void ParseTcpOption(TCP_OPTION *o, void *data, UINT size) { UCHAR *buf = (UCHAR *)data; - UINT i; + UINT i = 0; UINT value_size = 0; UINT value_id = 0; UCHAR value[128]; @@ -5441,13 +5441,18 @@ void ParseTcpOption(TCP_OPTION *o, void *data, UINT size) Zero(o, sizeof(TCP_OPTION)); - for (i = 0;i < size;i++) + while(i < size) { if (buf[i] == 0) { return; } - if (buf[i] != 1) + else if (buf[i] == 1) + { + i++; + continue; + } + else { value_id = buf[i]; i++; @@ -5466,12 +5471,14 @@ void ParseTcpOption(TCP_OPTION *o, void *data, UINT size) return; } value_size -= 2; + Copy(value, &buf[i], value_size); i += value_size; - if (i >= size) + if (i > size) { return; } + switch (value_id) { case 2: // MSS @@ -5486,14 +5493,13 @@ void ParseTcpOption(TCP_OPTION *o, void *data, UINT size) if (value_size == 1) { UCHAR *wss = (UCHAR *)value; - o->WindowScaling = Endian16(*wss); + o->WindowScaling = *wss; } break; } } } - } // Create a new NAT TCP session