diff --git a/src/core/net/icmp6.cpp b/src/core/net/icmp6.cpp index c8826f3c5..65a5ad90d 100644 --- a/src/core/net/icmp6.cpp +++ b/src/core/net/icmp6.cpp @@ -110,14 +110,16 @@ exit: return error; } -ThreadError Icmp::SendError(const Address &aDestination, IcmpHeader::Type aType, IcmpHeader::Code aCode, +ThreadError Icmp::SendError(IcmpHeader::Type aType, IcmpHeader::Code aCode, const MessageInfo &aMessageInfo, const Header &aHeader) { ThreadError error = kThreadError_None; - MessageInfo messageInfo; + MessageInfo messageInfoLocal; Message *message = NULL; IcmpHeader icmp6Header; + messageInfoLocal = aMessageInfo; + VerifyOrExit((message = mIp6.NewMessage(0)) != NULL, error = kThreadError_NoBufs); SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(aHeader))); @@ -128,9 +130,7 @@ ThreadError Icmp::SendError(const Address &aDestination, IcmpHeader::Type aType, icmp6Header.SetCode(aCode); message->Write(0, sizeof(icmp6Header), &icmp6Header); - messageInfo.SetPeerAddr(aDestination); - - SuccessOrExit(error = mIp6.SendDatagram(*message, messageInfo, kProtoIcmp6)); + SuccessOrExit(error = mIp6.SendDatagram(*message, messageInfoLocal, kProtoIcmp6)); otLogInfoIcmp("Sent ICMPv6 Error"); diff --git a/src/core/net/icmp6.hpp b/src/core/net/icmp6.hpp index b17c7d0a5..e7515f62d 100644 --- a/src/core/net/icmp6.hpp +++ b/src/core/net/icmp6.hpp @@ -95,7 +95,7 @@ public: */ enum Type { - kTypeDstUnreach = 0, ///< Destination Unreachable + kTypeDstUnreach = 1, ///< Destination Unreachable kTypeEchoRequest = 128, ///< Echo Request kTypeEchoReply = 129, ///< Echo Reply }; @@ -321,16 +321,16 @@ public: /** * This method sends an ICMPv6 error message. * - * @param[in] aDestination The IPv6 destination address. * @param[in] aType The ICMPv6 message type. * @param[in] aCode The ICMPv6 message code. + * @param[in] aMessageInfo A reference to the message info. * @param[in] aHeader The IPv6 header of the error-causing message. * * @retval kThreadError_None Successfully enqueued the ICMPv6 error message. * @retval kThreadError_NoBufs Insufficient buffers available. * */ - ThreadError SendError(const Address &aDestination, IcmpHeader::Type aType, IcmpHeader::Code aCode, + ThreadError SendError(IcmpHeader::Type aType, IcmpHeader::Code aCode, const MessageInfo &aMessageInfo, const Header &aHeader); /** diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 85f3b72b8..461b83d9d 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -2994,7 +2994,7 @@ Router *Mle::GetParent() ThreadError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header) { ThreadError error = kThreadError_Drop; - Ip6::Address dst; + Ip6::MessageInfo messageInfo; if (aMeshDest != GetRloc16()) { @@ -3006,10 +3006,13 @@ ThreadError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6 ExitNow(error = kThreadError_None); } - dst = GetMeshLocal16(); - dst.mFields.m16[7] = HostSwap16(aMeshSource); - mNetif.GetIp6().mIcmp.SendError(dst, Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, - aIp6Header); + messageInfo.GetPeerAddr() = GetMeshLocal16(); + messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource); + messageInfo.SetInterfaceId(mNetif.GetInterfaceId()); + + mNetif.GetIp6().mIcmp.SendError(Ip6::IcmpHeader::kTypeDstUnreach, + Ip6::IcmpHeader::kCodeDstUnreachNoRoute, + messageInfo, aIp6Header); exit: return error; diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 830c7102e..81ce3a96d 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -3542,7 +3542,7 @@ void MleRouter::ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16) ThreadError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header) { - Ip6::Address destination; + Ip6::MessageInfo messageInfo; if (mDeviceState == kDeviceStateChild) { @@ -3577,10 +3577,13 @@ ThreadError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDes return kThreadError_None; } - destination = GetMeshLocal16(); - destination.mFields.m16[7] = HostSwap16(aMeshSource); - mNetif.GetIp6().mIcmp.SendError(destination, Ip6::IcmpHeader::kTypeDstUnreach, - Ip6::IcmpHeader::kCodeDstUnreachNoRoute, aIp6Header); + messageInfo.GetPeerAddr() = GetMeshLocal16(); + messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource); + messageInfo.SetInterfaceId(mNetif.GetInterfaceId()); + + mNetif.GetIp6().mIcmp.SendError(Ip6::IcmpHeader::kTypeDstUnreach, + Ip6::IcmpHeader::kCodeDstUnreachNoRoute, + messageInfo, aIp6Header); return kThreadError_Drop; } diff --git a/tests/scripts/thread-cert/ipv6.py b/tests/scripts/thread-cert/ipv6.py index 9a689c8d9..640823224 100644 --- a/tests/scripts/thread-cert/ipv6.py +++ b/tests/scripts/thread-cert/ipv6.py @@ -54,7 +54,7 @@ UPPER_LAYER_PROTOCOLS = [ ] # ICMP Protocol codes -ICMP_DESTINATION_UNREACHABLE = 0 +ICMP_DESTINATION_UNREACHABLE = 1 ICMP_ECHO_REQUEST = 128 ICMP_ECHO_RESPONSE = 129