diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index adc4fd374..c74c2b4b9 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -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: diff --git a/src/core/net/ip6_headers.hpp b/src/core/net/ip6_headers.hpp index c6846a7fc..83ced3f33 100644 --- a/src/core/net/ip6_headers.hpp +++ b/src/core/net/ip6_headers.hpp @@ -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(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; diff --git a/src/core/net/ip6_mpl.hpp b/src/core/net/ip6_mpl.hpp index 5688e5f0d..22955a3ca 100644 --- a/src/core/net/ip6_mpl.hpp +++ b/src/core/net/ip6_mpl.hpp @@ -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. * diff --git a/src/core/thread/lowpan.cpp b/src/core/thread/lowpan.cpp index 3c816bdc9..f9fc767b1 100644 --- a/src/core/thread/lowpan.cpp +++ b/src/core/thread/lowpan.cpp @@ -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;