From bf9893dbf309cd5cf1c2102f45565fc0b17c2815 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 10 Sep 2014 16:58:31 -0700 Subject: [PATCH] add processing for unknown TCP options --- src/internet/model/tcp-header.cc | 41 ++++++++++++++++++-------------- src/internet/model/tcp-option.cc | 4 +++- src/internet/model/tcp-option.h | 3 ++- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/internet/model/tcp-header.cc b/src/internet/model/tcp-header.cc index 2c70b82ca..3ddaee5ea 100644 --- a/src/internet/model/tcp-header.cc +++ b/src/internet/model/tcp-header.cc @@ -22,6 +22,7 @@ #include #include "tcp-header.h" #include "tcp-option.h" +#include "tcp-option-rfc793.h" #include "ns3/buffer.h" #include "ns3/address-utils.h" #include "ns3/log.h" @@ -367,30 +368,34 @@ TcpHeader::Deserialize (Buffer::Iterator start) // Deserialize options if they exist m_options.clear (); uint32_t optionLen = (m_length - 5) * 4; + NS_ASSERT_MSG (optionLen <= 40, "Illegal TCP option length"); while (optionLen) { uint8_t kind = i.PeekU8 (); - Ptr op = TcpOption::CreateOption (kind); - + Ptr op; uint32_t optionSize; - optionSize = op->Deserialize (i); - - NS_ASSERT_MSG (optionSize, "Unable to Deserialize an Option of Kind " << int (kind) << ", sorry."); - optionLen -= optionSize; - i.Next (optionSize); - - if (op->GetKind () != TcpOption::END) + if (TcpOption::IsKindKnown (kind)) { - if (TcpOption::IsKindKnown (op->GetKind ())) - { - m_options.push_back (op); - } - else - { - NS_LOG_WARN ("Ignored option kind=" << op->GetKind ()); - } + op = TcpOption::CreateOption (kind); + } + else + { + op = TcpOption::CreateOption (TcpOption::UNKNOWN); + NS_LOG_WARN ("Option kind " << static_cast (kind) << " unknown, skipping."); + } + optionSize = op->Deserialize (i); + NS_ASSERT_MSG (optionSize == op->GetSerializedSize (), "Option did not deserialize correctly"); + if (optionLen >= optionSize) + { + optionLen -= optionSize; + i.Next (optionSize); + m_options.push_back (op); } else + { + NS_ASSERT_MSG (false, "Option exceeds TCP option space"); + } + if (op->GetKind () == TcpOption::END) { while (optionLen) { @@ -438,7 +443,7 @@ TcpHeader::AppendOption (Ptr option) { if (!TcpOption::IsKindKnown (option->GetKind ())) { - NS_LOG_WARN ("The option kind " << option->GetKind () << " is unknown"); + NS_LOG_WARN ("The option kind " << static_cast (option->GetKind ()) << " is unknown"); return false; } diff --git a/src/internet/model/tcp-option.cc b/src/internet/model/tcp-option.cc index 341ac8fbb..01c8e51ae 100644 --- a/src/internet/model/tcp-option.cc +++ b/src/internet/model/tcp-option.cc @@ -71,7 +71,8 @@ TcpOption::CreateOption (uint8_t kind) { TcpOption::MSS, TcpOptionMSS::GetTypeId () }, { TcpOption::NOP, TcpOptionNOP::GetTypeId () }, { TcpOption::TS, TcpOptionTS::GetTypeId () }, - { TcpOption::WINSCALE, TcpOptionWinScale::GetTypeId () } + { TcpOption::WINSCALE, TcpOptionWinScale::GetTypeId () }, + { TcpOption::UNKNOWN, TcpOptionUnknown::GetTypeId () } }; for (unsigned int i = 0; i < sizeof (toTid) / sizeof (kindToTid); ++i) @@ -96,6 +97,7 @@ TcpOption::IsKindKnown (uint8_t kind) case MSS: case WINSCALE: case TS: + // Do not add UNKNOWN here return true; } diff --git a/src/internet/model/tcp-option.h b/src/internet/model/tcp-option.h index 90eff1ff3..461e23d5f 100644 --- a/src/internet/model/tcp-option.h +++ b/src/internet/model/tcp-option.h @@ -56,7 +56,8 @@ public: NOP = 1, //!< NOP MSS = 2, //!< MSS WINSCALE = 3, //!< WINSCALE - TS = 8 //!< TS + TS = 8, //!< TS + UNKNOWN = 255 //!< not a standardized value; for unknown recv'd options }; /**