[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:
Abtin Keshavarzian
2023-01-24 20:54:53 -08:00
committed by GitHub
parent a1a223fcd1
commit dbadefa5c8
4 changed files with 60 additions and 51 deletions
+22 -21
View File
@@ -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:
+32 -15
View File
@@ -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;
+2 -11
View File
@@ -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.
*
+4 -4
View File
@@ -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;