diff --git a/include/openthread/icmp6.h b/include/openthread/icmp6.h index 39611d55f..f927a1be1 100644 --- a/include/openthread/icmp6.h +++ b/include/openthread/icmp6.h @@ -52,6 +52,77 @@ extern "C" { * */ +/** + * ICMPv6 Message Types + * + */ +typedef enum otIcmp6Type +{ + OT_ICMP6_TYPE_DST_UNREACH = 1, ///< Destination Unreachable + OT_ICMP6_TYPE_ECHO_REQUEST = 128, ///< Echo Request + OT_ICMP6_TYPE_ECHO_REPLY = 129, ///< Echo Reply +} otIcmp6Type; + +/** + * ICMPv6 Message Codes + * + */ +typedef enum otIcmp6Code +{ + OT_ICMP6_CODE_DST_UNREACH_NO_ROUTE = 0, ///< Destination Unreachable No Route +} otIcmp6Code; + +#define OT_ICMP6_HEADER_DATA_SIZE 4 ///< Size of an message specific data of ICMPv6 Header. + +/** + * @struct otIcmp6Header + * + * This structure represents an ICMPv6 header. + * + */ +OT_TOOL_PACKED_BEGIN +struct otIcmp6Header +{ + uint8_t mType; ///< Type + uint8_t mCode; ///< Code + uint16_t mChecksum; ///< Checksum + union + { + uint8_t m8[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint8_t)]; + uint16_t m16[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint16_t)]; + uint32_t m32[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint32_t)]; + } mData; ///< Message-specific data +} OT_TOOL_PACKED_END; + +/** + * This type represents an ICMPv6 header. + * + */ +typedef struct otIcmp6Header otIcmp6Header; + +/** + * This callback allows OpenThread to inform the application of a received ICMPv6 message. + * + * @param[in] aContext A pointer to arbitrary context information. + * @param[in] aMessage A pointer to the received message. + * @param[in] aMessageInfo A pointer to message information associated with @p aMessage. + * @param[in] aIcmpHeader A pointer to the received ICMPv6 header. + * + */ +typedef void (*otIcmp6ReceiveCallback)(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, + const otIcmp6Header *aIcmpHeader); + +/** + * This structure implements ICMPv6 message handler. + * + */ +typedef struct otIcmp6Handler +{ + otIcmp6ReceiveCallback mReceiveCallback; ///< The ICMPv6 received callback + void *mContext; ///< A pointer to arbitrary context information. + struct otIcmp6Handler *mNext; ///< A pointer to the next handler in the list. +} otIcmp6Handler; + /** * This function indicates whether or not ICMPv6 Echo processing is enabled. * diff --git a/include/openthread/types.h b/include/openthread/types.h index 939ea8043..77a989b47 100644 --- a/include/openthread/types.h +++ b/include/openthread/types.h @@ -994,77 +994,6 @@ typedef struct uint16_t mSecretKeyLength; ///< Secret key length in bytes. Should be at least 16 bytes == 128 bits. } otSemanticallyOpaqueIidGeneratorData; -/** - * ICMPv6 Message Types - * - */ -typedef enum otIcmp6Type -{ - kIcmp6TypeDstUnreach = 1, ///< Destination Unreachable - kIcmp6TypeEchoRequest = 128, ///< Echo Request - kIcmp6TypeEchoReply = 129, ///< Echo Reply -} otIcmp6Type; - -/** - * ICMPv6 Message Codes - * - */ -typedef enum otIcmp6Code -{ - kIcmp6CodeDstUnreachNoRoute = 0, ///< Destination Unreachable No Route -} otIcmp6Code; - -#define OT_ICMP6_HEADER_DATA_SIZE 4 ///< Size of an message specific data of ICMPv6 Header. - -/** - * @struct otIcmp6Header - * - * This structure represents an ICMPv6 header. - * - */ -OT_TOOL_PACKED_BEGIN -struct otIcmp6Header -{ - uint8_t mType; ///< Type - uint8_t mCode; ///< Code - uint16_t mChecksum; ///< Checksum - union - { - uint8_t m8[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint8_t)]; - uint16_t m16[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint16_t)]; - uint32_t m32[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint32_t)]; - } mData; ///< Message-specific data -} OT_TOOL_PACKED_END; - -/** - * This type represents an ICMPv6 header. - * - */ -typedef struct otIcmp6Header otIcmp6Header; - -/** - * This callback allows OpenThread to inform the application of a received ICMPv6 message. - * - * @param[in] aContext A pointer to arbitrary context information. - * @param[in] aMessage A pointer to the received message. - * @param[in] aMessageInfo A pointer to message information associated with @p aMessage. - * @param[in] aIcmpHeader A pointer to the received ICMPv6 header. - * - */ -typedef void (*otIcmp6ReceiveCallback)(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, - const otIcmp6Header *aIcmpHeader); - -/** - * This structure implements ICMPv6 message handler. - * - */ -typedef struct otIcmp6Handler -{ - otIcmp6ReceiveCallback mReceiveCallback; ///< The ICMPv6 received callback - void *mContext; ///< A pointer to arbitrary context information. - struct otIcmp6Handler *mNext; ///< A pointer to the next handler in the list. -} otIcmp6Handler; - /** * This structure represents an IPv6 socket address. */ diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 412cb9492..01dd5f908 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #if OPENTHREAD_FTD @@ -1547,11 +1548,11 @@ void Interpreter::s_HandleIcmpReceive(void *aContext, otMessage *aMessage, const } void Interpreter::HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, - const Ip6::IcmpHeader &aIcmpHeader) + const otIcmp6Header &aIcmpHeader) { uint32_t timestamp = 0; - VerifyOrExit(aIcmpHeader.GetType() == kIcmp6TypeEchoReply); + VerifyOrExit(aIcmpHeader.mType == OT_ICMP6_TYPE_ECHO_REPLY); sServer->OutputFormat("%d bytes from ", aMessage.GetLength() - aMessage.GetOffset()); sServer->OutputFormat("%x:%x:%x:%x:%x:%x:%x:%x", @@ -1563,7 +1564,7 @@ void Interpreter::HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &a HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[5]), HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[6]), HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7])); - sServer->OutputFormat(": icmp_seq=%d hlim=%d", aIcmpHeader.GetSequence(), aMessageInfo.mHopLimit); + sServer->OutputFormat(": icmp_seq=%d hlim=%d", HostSwap16(aIcmpHeader.mData.m16[1]), aMessageInfo.mHopLimit); if (aMessage.Read(aMessage.GetOffset(), sizeof(uint32_t), ×tamp) >= static_cast(sizeof(uint32_t))) diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 8b6c47e71..7967e67d1 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -298,7 +298,7 @@ private: #ifndef OTDLL void HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, - const Ip6::IcmpHeader &aIcmpHeader); + const otIcmp6Header &aIcmpHeader); void HandlePingTimer(); #endif void HandleActiveScanResult(otActiveScanResult *aResult); diff --git a/src/core/net/icmp6.cpp b/src/core/net/icmp6.cpp index 6a3854e92..9db6dda34 100644 --- a/src/core/net/icmp6.cpp +++ b/src/core/net/icmp6.cpp @@ -101,7 +101,7 @@ otError Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo messageInfoLocal = aMessageInfo; icmpHeader.Init(); - icmpHeader.SetType(kIcmp6TypeEchoRequest); + icmpHeader.SetType(IcmpHeader::kTypeEchoRequest); icmpHeader.SetId(aIdentifier); icmpHeader.SetSequence(mEchoSequence++); @@ -166,7 +166,7 @@ otError Icmp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo) checksum = aMessage.UpdateChecksum(checksum, aMessage.GetOffset(), payloadLength); VerifyOrExit(checksum == 0xffff, error = OT_ERROR_PARSE); - if (mIsEchoEnabled && (icmp6Header.GetType() == kIcmp6TypeEchoRequest)) + if (mIsEchoEnabled && (icmp6Header.GetType() == IcmpHeader::kTypeEchoRequest)) { HandleEchoRequest(aMessage, aMessageInfo); } @@ -193,7 +193,7 @@ otError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo &aMe otLogInfoIcmp(GetInstance(), "Received Echo Request"); icmp6Header.Init(); - icmp6Header.SetType(kIcmp6TypeEchoReply); + icmp6Header.SetType(IcmpHeader::kTypeEchoReply); if ((replyMessage = mIp6.NewMessage(0)) == NULL) { diff --git a/src/core/net/icmp6.hpp b/src/core/net/icmp6.hpp index aee5b59b0..d17492de2 100644 --- a/src/core/net/icmp6.hpp +++ b/src/core/net/icmp6.hpp @@ -34,7 +34,7 @@ #ifndef ICMP6_HPP_ #define ICMP6_HPP_ -#include +#include #include "common/encoding.hpp" #include "net/ip6_headers.hpp" @@ -72,13 +72,21 @@ public: * ICMPv6 Message Types * */ - typedef otIcmp6Type Type; + enum Type + { + kTypeDstUnreach = OT_ICMP6_TYPE_DST_UNREACH, ///< Destination Unreachable + kTypeEchoRequest = OT_ICMP6_TYPE_ECHO_REQUEST, ///< Echo Request + kTypeEchoReply = OT_ICMP6_TYPE_ECHO_REPLY, ///< Echo Reply + }; /** * ICMPv6 Message Codes * */ - typedef otIcmp6Code Code; + enum Code + { + kCodeDstUnreachNoRoute = OT_ICMP6_CODE_DST_UNREACH_NO_ROUTE, ///< Destination Unreachable No Route + }; /** * This method returns the ICMPv6 message type. diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 4a27e04f3..d36ccb791 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -609,7 +609,7 @@ otError Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo & aMessage.Read(aMessage.GetOffset(), sizeof(icmp), &icmp); // do not pass ICMP Echo Request messages - VerifyOrExit(icmp.GetType() != kIcmp6TypeEchoRequest, error = OT_ERROR_NO_ROUTE); + VerifyOrExit(icmp.GetType() != IcmpHeader::kTypeEchoRequest, error = OT_ERROR_NO_ROUTE); } break; diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index e0228000c..0a4125d8b 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -674,8 +674,8 @@ void AddressResolver::HandleIcmpReceive(Message &aMessage, const Ip6::MessageInf { Ip6::Header ip6Header; - VerifyOrExit(aIcmpHeader.GetType() == kIcmp6TypeDstUnreach); - VerifyOrExit(aIcmpHeader.GetCode() == kIcmp6CodeDstUnreachNoRoute); + VerifyOrExit(aIcmpHeader.GetType() == Ip6::IcmpHeader::kTypeDstUnreach); + VerifyOrExit(aIcmpHeader.GetCode() == Ip6::IcmpHeader::kCodeDstUnreachNoRoute); VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(ip6Header), &ip6Header) == sizeof(ip6Header)); for (int i = 0; i < kCacheEntries; i++) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index da6834035..70e5a805f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -3271,8 +3271,8 @@ otError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::He messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource); messageInfo.SetInterfaceId(mNetif.GetInterfaceId()); - mNetif.GetIp6().mIcmp.SendError(kIcmp6TypeDstUnreach, - kIcmp6CodeDstUnreachNoRoute, + mNetif.GetIp6().mIcmp.SendError(Ip6::IcmpHeader::kTypeDstUnreach, + Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo, aIp6Header); exit: diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index e5f748ca5..baae32704 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -3786,8 +3786,8 @@ otError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, I messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource); messageInfo.SetInterfaceId(mNetif.GetInterfaceId()); - mNetif.GetIp6().mIcmp.SendError(kIcmp6TypeDstUnreach, - kIcmp6CodeDstUnreachNoRoute, + mNetif.GetIp6().mIcmp.SendError(Ip6::IcmpHeader::kTypeDstUnreach, + Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo, aIp6Header); return OT_ERROR_DROP;