mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 16:47:47 +00:00
[mesh-forwarder] add function to decompress IPv6 Header (#3014)
This commit is contained in:
committed by
Jonathan Hui
parent
5d993e9868
commit
b83fa59914
@@ -97,7 +97,7 @@ public:
|
||||
* @retval TRUE If the header matches the LOWPAN_IPHC dispatch value.
|
||||
* @retval FALSE If the header does not match the LOWPAN_IPHC dispatch value.
|
||||
*/
|
||||
static bool IsLowpanHc(uint8_t *aHeader)
|
||||
static bool IsLowpanHc(const uint8_t *aHeader)
|
||||
{
|
||||
return (aHeader[0] & (Lowpan::kHcDispatchMask >> 8)) == (Lowpan::kHcDispatch >> 8);
|
||||
}
|
||||
@@ -477,7 +477,7 @@ public:
|
||||
* @retval FALSE If the header does not match the Fragment Header dispatch value.
|
||||
*
|
||||
*/
|
||||
bool IsFragmentHeader(void) { return (HostSwap16(mDispatchSize) & kDispatchMask) == kDispatch; }
|
||||
bool IsFragmentHeader(void) const { return (HostSwap16(mDispatchSize) & kDispatchMask) == kDispatch; }
|
||||
|
||||
/**
|
||||
* This method returns the Fragment Header length.
|
||||
|
||||
@@ -453,6 +453,59 @@ otError MeshForwarder::GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Ma
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError MeshForwarder::SkipMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
|
||||
VerifyOrExit(aFrameLength >= 1 && reinterpret_cast<const Lowpan::MeshHeader *>(aFrame)->IsMeshHeader());
|
||||
|
||||
SuccessOrExit(error = meshHeader.Init(aFrame, aFrameLength));
|
||||
aFrame += meshHeader.GetHeaderLength();
|
||||
aFrameLength -= meshHeader.GetHeaderLength();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MeshForwarder::DecompressIp6Header(const uint8_t * aFrame,
|
||||
uint8_t aFrameLength,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
Ip6::Header & aIp6Header,
|
||||
uint8_t & aHeaderLength,
|
||||
bool & aNextHeaderCompressed)
|
||||
{
|
||||
Lowpan::Lowpan & lowpan = GetNetif().GetLowpan();
|
||||
otError error = OT_ERROR_NONE;
|
||||
const uint8_t * start = aFrame;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
int headerLength;
|
||||
|
||||
SuccessOrExit(error = SkipMeshHeader(aFrame, aFrameLength));
|
||||
|
||||
if (aFrameLength >= 1 && reinterpret_cast<const Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader())
|
||||
{
|
||||
SuccessOrExit(error = fragmentHeader.Init(aFrame, aFrameLength));
|
||||
|
||||
// only the first fragment header is followed by a LOWPAN_IPHC header
|
||||
VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
aFrame += fragmentHeader.GetHeaderLength();
|
||||
aFrameLength -= fragmentHeader.GetHeaderLength();
|
||||
}
|
||||
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame), error = OT_ERROR_NOT_FOUND);
|
||||
headerLength =
|
||||
lowpan.DecompressBaseHeader(aIp6Header, aNextHeaderCompressed, aMacSource, aMacDest, aFrame, aFrameLength);
|
||||
|
||||
VerifyOrExit(headerLength > 0, error = OT_ERROR_PARSE);
|
||||
aHeaderLength = static_cast<uint8_t>(aFrame - start) + static_cast<uint8_t>(headerLength);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MeshForwarder::HandleFrameRequest(Mac::Sender &aSender, Mac::Frame &aFrame)
|
||||
{
|
||||
return aSender.GetOwner<MeshForwarder>().HandleFrameRequest(aFrame);
|
||||
|
||||
@@ -271,6 +271,19 @@ private:
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest);
|
||||
|
||||
otError SkipMeshHeader(const uint8_t *&aFrame, uint8_t &aFrameLength);
|
||||
otError DecompressIp6Header(const uint8_t * aFrame,
|
||||
uint8_t aFrameLength,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
Ip6::Header & aIp6Header,
|
||||
uint8_t & aHeaderLength,
|
||||
bool & aNextHeaderCompressed);
|
||||
otError GetIp6Header(const uint8_t * aFrame,
|
||||
uint8_t aFrameLength,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
Ip6::Header & aIp6Header);
|
||||
otError GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
otError GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
Message *GetDirectTransmission(void);
|
||||
|
||||
@@ -829,43 +829,42 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MeshForwarder::GetIp6Header(const uint8_t * aFrame,
|
||||
uint8_t aFrameLength,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
Ip6::Header & aIp6Header)
|
||||
{
|
||||
uint8_t headerLength;
|
||||
bool nextHeaderCompressed;
|
||||
|
||||
return DecompressIp6Header(aFrame, aFrameLength, aMacSource, aMacDest, aIp6Header, headerLength,
|
||||
nextHeaderCompressed);
|
||||
}
|
||||
|
||||
otError MeshForwarder::CheckReachability(uint8_t * aFrame,
|
||||
uint8_t aFrameLength,
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest)
|
||||
{
|
||||
ThreadNetif & netif = GetNetif();
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
bool nextHeaderCompressed;
|
||||
|
||||
VerifyOrExit(meshHeader.Init(aFrame, aFrameLength) == OT_ERROR_NONE, error = OT_ERROR_DROP);
|
||||
|
||||
// skip mesh header
|
||||
aFrame += meshHeader.GetHeaderLength();
|
||||
aFrameLength -= meshHeader.GetHeaderLength();
|
||||
|
||||
// skip fragment header
|
||||
if (aFrameLength >= 1 && reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader())
|
||||
{
|
||||
VerifyOrExit(sizeof(Lowpan::FragmentHeader) <= aFrameLength, error = OT_ERROR_DROP);
|
||||
VerifyOrExit(reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetDatagramOffset() == 0);
|
||||
|
||||
aFrame += reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetHeaderLength();
|
||||
aFrameLength -= reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetHeaderLength();
|
||||
}
|
||||
|
||||
// only process IPv6 packets
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame));
|
||||
|
||||
VerifyOrExit(netif.GetLowpan().DecompressBaseHeader(ip6Header, nextHeaderCompressed, aMeshSource, aMeshDest, aFrame,
|
||||
aFrameLength) > 0,
|
||||
error = OT_ERROR_DROP);
|
||||
ThreadNetif &netif = GetNetif();
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
|
||||
SuccessOrExit(error = GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header));
|
||||
error = netif.GetMle().CheckReachability(aMeshSource.GetShort(), aMeshDest.GetShort(), ip6Header);
|
||||
|
||||
exit:
|
||||
// the message may not contain an IPv6 header
|
||||
if (error == OT_ERROR_NOT_FOUND)
|
||||
{
|
||||
error = OT_ERROR_NONE;
|
||||
}
|
||||
else if (error != OT_ERROR_NONE)
|
||||
{
|
||||
error = OT_ERROR_DROP;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -955,32 +954,9 @@ void MeshForwarder::UpdateRoutes(uint8_t * aFrame,
|
||||
ThreadNetif &netif = GetNetif();
|
||||
Ip6::Header ip6Header;
|
||||
Neighbor * neighbor;
|
||||
bool nextHeaderCompressed;
|
||||
|
||||
VerifyOrExit(!aMeshDest.IsBroadcast() && aMeshSource.IsShort());
|
||||
|
||||
// skip mesh header
|
||||
if (aFrameLength >= 1 && reinterpret_cast<Lowpan::MeshHeader *>(aFrame)->IsMeshHeader())
|
||||
{
|
||||
aFrame += reinterpret_cast<Lowpan::MeshHeader *>(aFrame)->GetHeaderLength();
|
||||
aFrameLength -= reinterpret_cast<Lowpan::MeshHeader *>(aFrame)->GetHeaderLength();
|
||||
}
|
||||
|
||||
// skip fragment header
|
||||
if (aFrameLength >= 1 && reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader())
|
||||
{
|
||||
VerifyOrExit(sizeof(Lowpan::FragmentHeader) <= aFrameLength);
|
||||
VerifyOrExit(reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetDatagramOffset() == 0);
|
||||
|
||||
aFrame += reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetHeaderLength();
|
||||
aFrameLength -= reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetHeaderLength();
|
||||
}
|
||||
|
||||
// only process IPv6 packets
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame));
|
||||
|
||||
VerifyOrExit(netif.GetLowpan().DecompressBaseHeader(ip6Header, nextHeaderCompressed, aMeshSource, aMeshDest, aFrame,
|
||||
aFrameLength) > 0);
|
||||
SuccessOrExit(GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header));
|
||||
|
||||
netif.GetAddressResolver().UpdateCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user