From a43fb455d99d3692bdc68aa6d9be96f973a1a4ea Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Fri, 24 Jun 2016 12:43:02 -0700 Subject: [PATCH] Add ability to configure whether or not OpenThread handles ICMPv6 Echo Request/Reply messages. (#207) --- include/openthread.h | 17 +++++++++++++++++ src/core/net/icmp6.cpp | 22 ++++++++++++++++++---- src/core/net/icmp6.hpp | 19 +++++++++++++++++++ src/core/openthread.cpp | 11 +++++++++++ src/ncp/ncp_base.cpp | 1 + 5 files changed, 66 insertions(+), 4 deletions(-) diff --git a/include/openthread.h b/include/openthread.h index b0f0413d5..3bf9789fb 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -1194,6 +1194,23 @@ void otSetReceiveIp6DatagramCallback(otReceiveIp6DatagramCallback aCallback); */ ThreadError otSendIp6Datagram(otMessage aMessage); +/** + * This function indicates whether or not ICMPv6 Echo processing is enabled. + * + * @retval TRUE ICMPv6 Echo processing is enabled. + * @retval FALSE ICMPv6 Echo processing is disabled. + * + */ +bool otIsIcmpEchoEnabled(void); + +/** + * This function sets whether or not ICMPv6 Echo processing is enabled. + * + * @param[in] aEnabled TRUE to enable ICMPv6 Echo processing, FALSE otherwise. + * + */ +void otSetIcmpEchoEnabled(bool aEnabled); + /** * @} * diff --git a/src/core/net/icmp6.cpp b/src/core/net/icmp6.cpp index 695859813..b9401aed2 100644 --- a/src/core/net/icmp6.cpp +++ b/src/core/net/icmp6.cpp @@ -45,6 +45,8 @@ using Thread::Encoding::BigEndian::HostSwap16; namespace Thread { namespace Ip6 { +bool Icmp::sIsEchoEnabled = true; + uint16_t IcmpEcho::sNextId = 1; IcmpEcho *IcmpEcho::sEchoClients = NULL; IcmpHandler *IcmpHandler::sHandlers = NULL; @@ -205,7 +207,7 @@ ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo MessageInfo replyMessageInfo; uint16_t payloadLength; - payloadLength = aRequestMessage.GetLength() - aRequestMessage.GetOffset() - IcmpHeader::GetDataOffset(); + VerifyOrExit(sIsEchoEnabled, ;); otLogInfoIcmp("Received Echo Request\n"); @@ -213,6 +215,7 @@ ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo icmp6Header.SetType(IcmpHeader::kTypeEchoReply); VerifyOrExit((replyMessage = Ip6::NewMessage(0)) != NULL, otLogDebgIcmp("icmp fail\n")); + payloadLength = aRequestMessage.GetLength() - aRequestMessage.GetOffset() - IcmpHeader::GetDataOffset(); SuccessOrExit(replyMessage->SetLength(IcmpHeader::GetDataOffset() + payloadLength)); replyMessage->Write(0, IcmpHeader::GetDataOffset(), &icmp6Header); @@ -244,18 +247,19 @@ exit: } ThreadError Icmp::HandleEchoReply(Message &aMessage, const MessageInfo &aMessageInfo, - const IcmpHeader &aIcmpheader) + const IcmpHeader &aIcmpHeader) { - uint16_t id = aIcmpheader.GetId(); + VerifyOrExit(sIsEchoEnabled, ;); for (IcmpEcho *client = IcmpEcho::sEchoClients; client; client = client->mNext) { - if (client->mId == id) + if (client->mId == aIcmpHeader.GetId()) { client->HandleEchoReply(aMessage, aMessageInfo); } } +exit: return kThreadError_None; } @@ -274,5 +278,15 @@ ThreadError Icmp::UpdateChecksum(Message &aMessage, uint16_t aChecksum) return kThreadError_None; } +bool Icmp::IsEchoEnabled(void) +{ + return sIsEchoEnabled; +} + +void Icmp::SetEchoEnabled(bool aEnabled) +{ + sIsEchoEnabled = aEnabled; +} + } // namespace Ip6 } // namespace Thread diff --git a/src/core/net/icmp6.hpp b/src/core/net/icmp6.hpp index 8951e8c21..954075903 100644 --- a/src/core/net/icmp6.hpp +++ b/src/core/net/icmp6.hpp @@ -367,12 +367,31 @@ public: */ static ThreadError UpdateChecksum(Message &aMessage, uint16_t aPseudoHeaderChecksum); + /** + * This static method indicates whether or not ICMPv6 Echo processing is enabled. + * + * @retval TRUE ICMPv6 Echo processing is enabled. + * @retval FALSE ICMPv6 Echo processing is disabled. + * + */ + static bool IsEchoEnabled(void); + + /** + * This static method sets whether or not ICMPv6 Echo processing is enabled. + * + * @param[in] aEnabled TRUE to enable ICMPv6 Echo processing, FALSE otherwise. + * + */ + static void SetEchoEnabled(bool aEnabled); + private: static ThreadError HandleDstUnreach(Message &aMessage, const MessageInfo &aMessageInfo, const IcmpHeader &aIcmpHeader); static ThreadError HandleEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo); static ThreadError HandleEchoReply(Message &aMessage, const MessageInfo &aMessageInfo, const IcmpHeader &aIcmpHeader); + + static bool sIsEchoEnabled; }; /** diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index 8205d044e..05ba554df 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -735,6 +736,16 @@ ThreadError otSendUdp(otUdpSocket *aSocket, otMessage aMessage, const otMessageI *reinterpret_cast(aMessageInfo)); } +bool otIsIcmpEchoEnabled(void) +{ + return Ip6::Icmp::IsEchoEnabled(); +} + +void otSetIcmpEchoEnabled(bool aEnabled) +{ + Ip6::Icmp::SetEchoEnabled(aEnabled); +} + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index d370f3a6d..729a829e0 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -239,6 +239,7 @@ NcpBase::NcpBase(): assert(sThreadNetif != NULL); otSetStateChangedCallback(&HandleNetifStateChanged, this); otSetReceiveIp6DatagramCallback(&HandleDatagramFromStack); + otSetIcmpEchoEnabled(false); } // ----------------------------------------------------------------------------