mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[icmp] pass full error-causing message when sending error (#4800)
This commit is contained in:
@@ -90,19 +90,21 @@ exit:
|
||||
otError Icmp::SendError(IcmpHeader::Type aType,
|
||||
IcmpHeader::Code aCode,
|
||||
const MessageInfo &aMessageInfo,
|
||||
const Header & aHeader)
|
||||
const Message & aMessage)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
MessageInfo messageInfoLocal;
|
||||
Message * message = NULL;
|
||||
IcmpHeader icmp6Header;
|
||||
Header ip6Header;
|
||||
|
||||
messageInfoLocal = aMessageInfo;
|
||||
|
||||
VerifyOrExit((message = Get<Ip6>().NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(aHeader)));
|
||||
SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(ip6Header)));
|
||||
|
||||
message->Write(sizeof(icmp6Header), sizeof(aHeader), &aHeader);
|
||||
aMessage.Read(0, sizeof(ip6Header), &ip6Header);
|
||||
message->Write(sizeof(icmp6Header), sizeof(ip6Header), &ip6Header);
|
||||
|
||||
icmp6Header.Init();
|
||||
icmp6Header.SetType(aType);
|
||||
|
||||
@@ -284,7 +284,7 @@ public:
|
||||
* @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.
|
||||
* @param[in] aMessage The error-causing IPv6 message.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully enqueued the ICMPv6 error message.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffers available.
|
||||
@@ -293,7 +293,7 @@ public:
|
||||
otError SendError(IcmpHeader::Type aType,
|
||||
IcmpHeader::Code aCode,
|
||||
const MessageInfo &aMessageInfo,
|
||||
const Header & aHeader);
|
||||
const Message & aMessage);
|
||||
|
||||
/**
|
||||
* This method handles an ICMPv6 message.
|
||||
|
||||
@@ -905,7 +905,7 @@ otError Ip6::SendIcmpError(Message &aMessage, IcmpHeader::Type aIcmpType, IcmpHe
|
||||
messageInfo.SetHopLimit(header.GetHopLimit());
|
||||
messageInfo.SetLinkInfo(NULL);
|
||||
|
||||
SuccessOrExit(error = mIcmp.SendError(aIcmpType, aIcmpCode, messageInfo, header));
|
||||
SuccessOrExit(error = mIcmp.SendError(aIcmpType, aIcmpCode, messageInfo, aMessage));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -332,7 +332,7 @@ otError MeshForwarder::UpdateIp6Route(Message &aMessage)
|
||||
else
|
||||
{
|
||||
#if OPENTHREAD_FTD
|
||||
error = UpdateIp6RouteFtd(ip6Header);
|
||||
error = UpdateIp6RouteFtd(ip6Header, aMessage);
|
||||
#else
|
||||
OT_ASSERT(false);
|
||||
#endif
|
||||
|
||||
@@ -336,7 +336,7 @@ private:
|
||||
kMessageEvict, ///< Indicates that the message was evicted.
|
||||
};
|
||||
|
||||
otError CheckReachability(uint8_t * aFrame,
|
||||
otError CheckReachability(const uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest);
|
||||
@@ -390,9 +390,9 @@ private:
|
||||
uint16_t aMeshDest = 0xffff);
|
||||
|
||||
void SendMesh(Message &aMessage, Mac::TxFrame &aFrame);
|
||||
void SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Header &aIp6Header);
|
||||
void SendDestinationUnreachable(uint16_t aMeshSource, const Message &aMessage);
|
||||
otError UpdateIp6Route(Message &aMessage);
|
||||
otError UpdateIp6RouteFtd(Ip6::Header &ip6Header);
|
||||
otError UpdateIp6RouteFtd(Ip6::Header &ip6Header, const Message &aMessage);
|
||||
otError UpdateMeshRoute(Message &aMessage);
|
||||
bool UpdateReassemblyList(void);
|
||||
bool UpdateFragmentLifetime(void);
|
||||
|
||||
@@ -404,7 +404,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header)
|
||||
otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, const Message &aMessage)
|
||||
{
|
||||
Mle::MleRouter &mle = Get<Mle::MleRouter>();
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -497,7 +497,7 @@ otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header)
|
||||
exit:
|
||||
if (error == OT_ERROR_NO_ROUTE)
|
||||
{
|
||||
SendDestinationUnreachable(mMeshSource, ip6Header);
|
||||
SendDestinationUnreachable(mMeshSource, aMessage);
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -516,32 +516,56 @@ otError MeshForwarder::GetIp6Header(const uint8_t * aFrame,
|
||||
nextHeaderCompressed);
|
||||
}
|
||||
|
||||
otError MeshForwarder::CheckReachability(uint8_t * aFrame,
|
||||
otError MeshForwarder::CheckReachability(const uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
Message * message = NULL;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
uint16_t fragmentHeaderLength;
|
||||
uint16_t datagramSize = 0;
|
||||
|
||||
SuccessOrExit(error = GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header));
|
||||
if (fragmentHeader.ParseFrom(aFrame, aFrameLength, fragmentHeaderLength) == OT_ERROR_NONE)
|
||||
{
|
||||
// Only the first fragment header is followed by a LOWPAN_IPHC header
|
||||
VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, error = OT_ERROR_NOT_FOUND);
|
||||
aFrame += fragmentHeaderLength;
|
||||
aFrameLength -= fragmentHeaderLength;
|
||||
|
||||
datagramSize = fragmentHeader.GetDatagramSize();
|
||||
}
|
||||
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame), error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
error = FrameToMessage(aFrame, aFrameLength, datagramSize, aMeshSource, aMeshDest, message);
|
||||
SuccessOrExit(error);
|
||||
|
||||
message->Read(0, sizeof(ip6Header), &ip6Header);
|
||||
error = Get<Mle::MleRouter>().CheckReachability(aMeshDest.GetShort(), ip6Header);
|
||||
|
||||
exit:
|
||||
// the message may not contain an IPv6 header
|
||||
if (error == OT_ERROR_NOT_FOUND)
|
||||
{
|
||||
// the message may not contain an IPv6 header
|
||||
error = OT_ERROR_NONE;
|
||||
}
|
||||
else if (error == OT_ERROR_NO_ROUTE)
|
||||
{
|
||||
SendDestinationUnreachable(aMeshSource.GetShort(), ip6Header);
|
||||
SendDestinationUnreachable(aMeshSource.GetShort(), *message);
|
||||
}
|
||||
|
||||
if (message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Header &aIp6Header)
|
||||
void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Message &aMessage)
|
||||
{
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
@@ -549,7 +573,7 @@ void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::
|
||||
messageInfo.GetPeerAddr().SetLocator(aMeshSource);
|
||||
|
||||
Get<Ip6::Icmp>().SendError(Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo,
|
||||
aIp6Header);
|
||||
aMessage);
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleMesh(uint8_t * aFrame,
|
||||
|
||||
Reference in New Issue
Block a user