mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 21:57:47 +00:00
[ip6] add GetSize() to ExtensionHeader and OptionHeader (#8684)
This commit adds `GetSize()` to `Ip6::ExtensionHeader` and base class `OptionHeader`. This method returns the size (number of bytes) of the header/option. In case of `ExtensionHeader` the size is derived from "Length" field which is in 8-bye unit and does not count the first 8 bytes.
This commit is contained in:
+22
-21
@@ -192,20 +192,21 @@ Error Ip6::AddMplOption(Message &aMessage, Header &aHeader)
|
||||
Error error = kErrorNone;
|
||||
HopByHopHeader hbhHeader;
|
||||
OptionMpl mplOption;
|
||||
OptionPadN padOption;
|
||||
|
||||
hbhHeader.SetNextHeader(aHeader.GetNextHeader());
|
||||
hbhHeader.SetLength(0);
|
||||
mMpl.InitOption(mplOption, aHeader.GetSource());
|
||||
|
||||
// Mpl option may require two bytes padding.
|
||||
if ((mplOption.GetTotalLength() + sizeof(hbhHeader)) % 8)
|
||||
if ((mplOption.GetSize() + sizeof(hbhHeader)) % 8)
|
||||
{
|
||||
OptionPadN padOption;
|
||||
|
||||
padOption.Init(2);
|
||||
SuccessOrExit(error = aMessage.PrependBytes(&padOption, padOption.GetTotalLength()));
|
||||
SuccessOrExit(error = aMessage.PrependBytes(&padOption, padOption.GetSize()));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = aMessage.PrependBytes(&mplOption, mplOption.GetTotalLength()));
|
||||
SuccessOrExit(error = aMessage.PrependBytes(&mplOption, mplOption.GetSize()));
|
||||
SuccessOrExit(error = aMessage.Prepend(hbhHeader));
|
||||
aHeader.SetPayloadLength(aHeader.GetPayloadLength() + sizeof(hbhHeader) + sizeof(mplOption));
|
||||
aHeader.SetNextHeader(kProtoHopOpts);
|
||||
@@ -253,14 +254,14 @@ Error Ip6::InsertMplOption(Message &aMessage, Header &aHeader)
|
||||
if (aHeader.GetNextHeader() == kProtoHopOpts)
|
||||
{
|
||||
HopByHopHeader hbh;
|
||||
uint16_t hbhLength = 0;
|
||||
uint16_t hbhSize;
|
||||
OptionMpl mplOption;
|
||||
|
||||
// read existing hop-by-hop option header
|
||||
SuccessOrExit(error = aMessage.Read(0, hbh));
|
||||
hbhLength = (hbh.GetLength() + 1) * 8;
|
||||
hbhSize = hbh.GetSize();
|
||||
|
||||
VerifyOrExit(hbhLength <= aHeader.GetPayloadLength(), error = kErrorParse);
|
||||
VerifyOrExit(hbhSize <= aHeader.GetPayloadLength(), error = kErrorParse);
|
||||
|
||||
// increase existing hop-by-hop option header length by 8 bytes
|
||||
hbh.SetLength(hbh.GetLength() + 1);
|
||||
@@ -268,18 +269,19 @@ Error Ip6::InsertMplOption(Message &aMessage, Header &aHeader)
|
||||
|
||||
// make space for MPL Option + padding by shifting hop-by-hop option header
|
||||
SuccessOrExit(error = aMessage.PrependBytes(nullptr, 8));
|
||||
aMessage.CopyTo(8, 0, hbhLength, aMessage);
|
||||
aMessage.CopyTo(/* aSourceOffset */ 8, /* aDestOffset */ 0, hbhSize, aMessage);
|
||||
|
||||
// insert MPL Option
|
||||
mMpl.InitOption(mplOption, aHeader.GetSource());
|
||||
aMessage.WriteBytes(hbhLength, &mplOption, mplOption.GetTotalLength());
|
||||
aMessage.WriteBytes(hbhSize, &mplOption, mplOption.GetSize());
|
||||
|
||||
// insert Pad Option (if needed)
|
||||
if (mplOption.GetTotalLength() % 8)
|
||||
if (mplOption.GetSize() % 8)
|
||||
{
|
||||
OptionPadN padOption;
|
||||
padOption.Init(8 - (mplOption.GetTotalLength() % 8));
|
||||
aMessage.WriteBytes(hbhLength + mplOption.GetTotalLength(), &padOption, padOption.GetTotalLength());
|
||||
|
||||
padOption.Init(8 - (mplOption.GetSize() % 8));
|
||||
aMessage.WriteBytes(hbhSize + mplOption.GetSize(), &padOption, padOption.GetSize());
|
||||
}
|
||||
|
||||
// increase IPv6 Payload Length
|
||||
@@ -336,7 +338,7 @@ Error Ip6::RemoveMplOption(Message &aMessage)
|
||||
VerifyOrExit(ip6Header.GetNextHeader() == kProtoHopOpts);
|
||||
|
||||
IgnoreError(aMessage.Read(offset, hbh));
|
||||
endOffset = offset + (hbh.GetLength() + 1) * 8;
|
||||
endOffset = offset + hbh.GetSize();
|
||||
VerifyOrExit(aMessage.GetLength() >= endOffset, error = kErrorParse);
|
||||
|
||||
offset += sizeof(hbh);
|
||||
@@ -369,7 +371,7 @@ Error Ip6::RemoveMplOption(Message &aMessage)
|
||||
remove = true;
|
||||
}
|
||||
|
||||
offset += sizeof(option) + option.GetLength();
|
||||
offset += option.GetSize();
|
||||
break;
|
||||
|
||||
case OptionPad1::kType:
|
||||
@@ -377,13 +379,13 @@ Error Ip6::RemoveMplOption(Message &aMessage)
|
||||
break;
|
||||
|
||||
case OptionPadN::kType:
|
||||
offset += sizeof(option) + option.GetLength();
|
||||
offset += option.GetSize();
|
||||
break;
|
||||
|
||||
default:
|
||||
// encountered another option, now just replace MPL Option with PadN
|
||||
remove = false;
|
||||
offset += sizeof(option) + option.GetLength();
|
||||
offset += option.GetSize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -428,7 +430,7 @@ Error Ip6::RemoveMplOption(Message &aMessage)
|
||||
OptionPadN padOption;
|
||||
|
||||
padOption.Init(sizeof(OptionHeader) + mplLength);
|
||||
aMessage.WriteBytes(mplOffset, &padOption, padOption.GetTotalLength());
|
||||
aMessage.WriteBytes(mplOffset, &padOption, padOption.GetSize());
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -542,7 +544,7 @@ Error Ip6::HandleOptions(Message &aMessage, Header &aHeader, bool aIsOutbound, b
|
||||
uint16_t endOffset;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), hbhHeader));
|
||||
endOffset = aMessage.GetOffset() + (hbhHeader.GetLength() + 1) * 8;
|
||||
endOffset = aMessage.GetOffset() + hbhHeader.GetSize();
|
||||
|
||||
VerifyOrExit(endOffset <= aMessage.GetLength(), error = kErrorParse);
|
||||
|
||||
@@ -558,8 +560,7 @@ Error Ip6::HandleOptions(Message &aMessage, Header &aHeader, bool aIsOutbound, b
|
||||
continue;
|
||||
}
|
||||
|
||||
VerifyOrExit(aMessage.GetOffset() + sizeof(optionHeader) + optionHeader.GetLength() <= endOffset,
|
||||
error = kErrorParse);
|
||||
VerifyOrExit(aMessage.GetOffset() + optionHeader.GetSize() <= endOffset, error = kErrorParse);
|
||||
|
||||
switch (optionHeader.GetType())
|
||||
{
|
||||
@@ -588,7 +589,7 @@ Error Ip6::HandleOptions(Message &aMessage, Header &aHeader, bool aIsOutbound, b
|
||||
break;
|
||||
}
|
||||
|
||||
aMessage.MoveOffset(sizeof(optionHeader) + optionHeader.GetLength());
|
||||
aMessage.MoveOffset(optionHeader.GetSize());
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -396,6 +396,8 @@ public:
|
||||
/**
|
||||
* This method returns the IPv6 Header Extension Length value.
|
||||
*
|
||||
* The Length is in 8-byte units and does not include the first 8 bytes.
|
||||
*
|
||||
* @returns The IPv6 Header Extension Length value.
|
||||
*
|
||||
*/
|
||||
@@ -404,12 +406,29 @@ public:
|
||||
/**
|
||||
* This method sets the IPv6 Header Extension Length value.
|
||||
*
|
||||
* The Length is in 8-byte units and does not include the first 8 bytes.
|
||||
*
|
||||
* @param[in] aLength The IPv6 Header Extension Length value.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
/**
|
||||
* This method returns the size (number of bytes) of the Extension Header including Next Header and Length fields.
|
||||
*
|
||||
* @returns The size (number of bytes) of the Extension Header.
|
||||
*
|
||||
*/
|
||||
uint16_t GetSize(void) const { return kLengthUnitInBytes * (mLength + 1); }
|
||||
|
||||
private:
|
||||
static constexpr uint16_t kLengthUnitInBytes = 8;
|
||||
|
||||
// | m8[0] | m8[1] | m8[2] | m8[3] |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Next Header | Header Length | . . . |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
uint8_t mNextHeader;
|
||||
uint8_t mLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
@@ -463,10 +482,10 @@ public:
|
||||
*/
|
||||
enum Action : uint8_t
|
||||
{
|
||||
kActionSkip = 0x00, ///< skip over this option and continue processing the header
|
||||
kActionDiscard = 0x40, ///< discard the packet
|
||||
kActionForceIcmp = 0x80, ///< discard the packet and forcibly send an ICMP Parameter Problem
|
||||
kActionIcmp = 0xc0, ///< discard packet and conditionally send an ICMP Parameter Problem
|
||||
kActionSkip = 0x00, ///< Skip over this option and continue processing the header.
|
||||
kActionDiscard = 0x40, ///< Discard the packet.
|
||||
kActionForceIcmp = 0x80, ///< Discard the packet and forcibly send an ICMP Parameter Problem.
|
||||
kActionIcmp = 0xc0, ///< Discard packet and conditionally send an ICMP Parameter Problem.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -493,6 +512,14 @@ public:
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
/**
|
||||
* This method returns the size (number of bytes) of the IPv6 Option including the Type and Length fields.
|
||||
*
|
||||
* @returns The size of the Option.
|
||||
*
|
||||
*/
|
||||
uint16_t GetSize(void) const { return static_cast<uint16_t>(mLength) + sizeof(OptionHeader); }
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kActionMask = 0xc0;
|
||||
|
||||
@@ -515,8 +542,7 @@ public:
|
||||
/**
|
||||
* This method initializes the PadN header.
|
||||
*
|
||||
* @param[in] aPadLength The length of needed padding. Allowed value from
|
||||
* range 2-7.
|
||||
* @param[in] aPadLength The length of needed padding. Allowed value from range 2-7.
|
||||
*
|
||||
*/
|
||||
void Init(uint8_t aPadLength)
|
||||
@@ -526,15 +552,6 @@ public:
|
||||
memset(mPad, kData, aPadLength - sizeof(OptionHeader));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the total IPv6 Option Length value including option
|
||||
* header.
|
||||
*
|
||||
* @returns The total IPv6 Option Length.
|
||||
*
|
||||
*/
|
||||
uint8_t GetTotalLength(void) const { return GetLength() + sizeof(OptionHeader); }
|
||||
|
||||
private:
|
||||
uint8_t mPad[kMaxLength];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
@@ -73,20 +73,11 @@ public:
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
OptionHeader::SetType(kType);
|
||||
OptionHeader::SetLength(sizeof(*this) - sizeof(OptionHeader));
|
||||
SetType(kType);
|
||||
SetLength(sizeof(*this) - sizeof(OptionHeader));
|
||||
mControl = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the total MPL Option length value including option
|
||||
* header.
|
||||
*
|
||||
* @returns The total IPv6 Option Length.
|
||||
*
|
||||
*/
|
||||
uint8_t GetTotalLength(void) const { return OptionHeader::GetLength() + sizeof(OptionHeader); }
|
||||
|
||||
/**
|
||||
* MPL Seed Id lengths.
|
||||
*
|
||||
|
||||
@@ -438,7 +438,7 @@ Error Lowpan::CompressExtensionHeader(Message &aMessage, FrameBuilder &aFrameBui
|
||||
uint16_t startOffset = aMessage.GetOffset();
|
||||
Ip6::ExtensionHeader extHeader;
|
||||
uint16_t len;
|
||||
uint8_t padLength = 0;
|
||||
uint16_t padLength = 0;
|
||||
uint8_t tmpByte;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), extHeader));
|
||||
@@ -461,7 +461,7 @@ Error Lowpan::CompressExtensionHeader(Message &aMessage, FrameBuilder &aFrameBui
|
||||
|
||||
SuccessOrExit(error = aFrameBuilder.AppendUint8(tmpByte));
|
||||
|
||||
len = (extHeader.GetLength() + 1) * 8 - sizeof(extHeader);
|
||||
len = extHeader.GetSize() - sizeof(extHeader);
|
||||
|
||||
// RFC 6282 does not support compressing large extension headers
|
||||
VerifyOrExit(len <= kExtHdrMaxLength, error = kErrorFailed);
|
||||
@@ -485,7 +485,7 @@ Error Lowpan::CompressExtensionHeader(Message &aMessage, FrameBuilder &aFrameBui
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += sizeof(optionHeader) + optionHeader.GetLength();
|
||||
offset += optionHeader.GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ Error Lowpan::CompressExtensionHeader(Message &aMessage, FrameBuilder &aFrameBui
|
||||
}
|
||||
else if (optionHeader.GetType() == Ip6::OptionPadN::kType)
|
||||
{
|
||||
padLength = sizeof(optionHeader) + optionHeader.GetLength();
|
||||
padLength = optionHeader.GetSize();
|
||||
}
|
||||
|
||||
len -= padLength;
|
||||
|
||||
Reference in New Issue
Block a user