diff --git a/etc/visual-studio/libopenthread.vcxproj b/etc/visual-studio/libopenthread.vcxproj index 9386127cf..1d7356a38 100644 --- a/etc/visual-studio/libopenthread.vcxproj +++ b/etc/visual-studio/libopenthread.vcxproj @@ -113,6 +113,7 @@ + diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters index 8cee5ee62..2f64f57f1 100644 --- a/etc/visual-studio/libopenthread.vcxproj.filters +++ b/etc/visual-studio/libopenthread.vcxproj.filters @@ -180,6 +180,9 @@ Source Files\net + + Source Files\net + Source Files\net diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj index e9ee136f7..db4763ee7 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj +++ b/etc/visual-studio/libopenthread_k.vcxproj @@ -121,6 +121,7 @@ + diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters index 7a245e0e0..536e40f2b 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj.filters +++ b/etc/visual-studio/libopenthread_k.vcxproj.filters @@ -180,6 +180,9 @@ Source Files\net + + Source Files\net + Source Files\net diff --git a/src/core/Makefile.am b/src/core/Makefile.am index c5fa42b87..0ca3b2083 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -156,6 +156,7 @@ SOURCES_COMMON = \ net/ip6.cpp \ net/ip6_address.cpp \ net/ip6_filter.cpp \ + net/ip6_headers.cpp \ net/ip6_mpl.cpp \ net/ip6_routes.cpp \ net/netif.cpp \ diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 04e1f5c0f..844815d0a 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -665,8 +665,7 @@ otError Ip6::SendRaw(Message &aMessage, int8_t aInterfaceId) Header header; MessageInfo messageInfo; - // check aMessage length - VerifyOrExit(aMessage.Read(0, sizeof(header), &header) == sizeof(header), error = OT_ERROR_DROP); + SuccessOrExit(error = header.Init(aMessage)); messageInfo.SetPeerAddr(header.GetSource()); messageInfo.SetSockAddr(header.GetDestination()); @@ -691,7 +690,6 @@ otError Ip6::HandleDatagram(Message &aMessage, Netif *aNetif, int8_t aInterfaceI otError error = OT_ERROR_NONE; MessageInfo messageInfo; Header header; - uint16_t payloadLength; bool receive = false; bool forward = false; bool tunnel = false; @@ -708,16 +706,7 @@ otError Ip6::HandleDatagram(Message &aMessage, Netif *aNetif, int8_t aInterfaceI dump("handle datagram", buf, aMessage.GetLength()); #endif - // check aMessage length - VerifyOrExit(aMessage.Read(0, sizeof(header), &header) == sizeof(header), error = OT_ERROR_DROP); - payloadLength = header.GetPayloadLength(); - - // check Version - VerifyOrExit(header.IsVersion6(), error = OT_ERROR_DROP); - - // check Payload Length - VerifyOrExit(sizeof(header) + payloadLength == aMessage.GetLength() && - sizeof(header) + payloadLength <= Ip6::kMaxDatagramLength, error = OT_ERROR_DROP); + SuccessOrExit(error = header.Init(aMessage)); messageInfo.SetPeerAddr(header.GetSource()); messageInfo.SetSockAddr(header.GetDestination()); diff --git a/src/core/net/ip6_headers.cpp b/src/core/net/ip6_headers.cpp new file mode 100644 index 000000000..5b087a271 --- /dev/null +++ b/src/core/net/ip6_headers.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements IP6 header processing. + */ + +#include + +#include "ip6_headers.hpp" + +#include "net/ip6.hpp" + +namespace ot { +namespace Ip6 { + +otError Header::Init(const Message &aMessage) +{ + otError error = OT_ERROR_NONE; + uint16_t length; + + // check aMessage length + VerifyOrExit(aMessage.Read(0, sizeof(*this), this) == sizeof(*this), error = OT_ERROR_PARSE); + + // check Version + VerifyOrExit(IsVersion6(), error = OT_ERROR_PARSE); + + // check Payload Length + length = sizeof(*this) + GetPayloadLength(); + VerifyOrExit(length == aMessage.GetLength() && length <= Ip6::kMaxDatagramLength, error = OT_ERROR_PARSE); + +exit: + return error; +} + +} // namespace Ip6 +} // namespace ot diff --git a/src/core/net/ip6_headers.hpp b/src/core/net/ip6_headers.hpp index 3892c3619..b38ccae7e 100644 --- a/src/core/net/ip6_headers.hpp +++ b/src/core/net/ip6_headers.hpp @@ -146,6 +146,17 @@ public: */ void Init(uint32_t aVersionClassFlow) { mVersionClassFlow.m32[0] = HostSwap32(aVersionClassFlow); } + /** + * This method reads the IPv6 header from @p aMessage. + * + * @param[in] aMessage The IPv6 datagram. + * + * @retval OT_ERROR_NONE Successfully read the IPv6 header. + * @retval OT_ERROR_PARSE Malformed IPv6 header. + * + */ + otError Init(const Message &aMessage); + /** * This method indicates whether or not the IPv6 Version is set to 6. *