Remove globals from ip6.cpp.

This commit is contained in:
Jonathan Hui
2016-09-07 13:30:22 -07:00
parent 7bc5cb2e5b
commit 7f899dc6dd
18 changed files with 599 additions and 468 deletions
+1
View File
@@ -95,6 +95,7 @@ noinst_HEADERS = \
net/icmp6.hpp \
net/ip6.hpp \
net/ip6_address.hpp \
net/ip6_headers.hpp \
net/ip6_filter.hpp \
net/ip6_mpl.hpp \
net/ip6_routes.hpp \
+9 -6
View File
@@ -43,6 +43,9 @@
using Thread::Encoding::BigEndian::HostSwap16;
namespace Thread {
extern Ip6::Ip6 *sIp6;
namespace Ip6 {
bool Icmp::sIsEchoEnabled = true;
@@ -54,7 +57,7 @@ void *Icmp::sEchoReplyContext = NULL;
Message *Icmp::NewMessage(uint16_t aReserved)
{
return Ip6::NewMessage(sizeof(IcmpHeader) + aReserved);
return sIp6->NewMessage(sizeof(IcmpHeader) + aReserved);
}
ThreadError Icmp::RegisterCallbacks(IcmpHandler &aHandler)
@@ -97,7 +100,7 @@ ThreadError Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessage
SuccessOrExit(error = aMessage.Prepend(&icmpHeader, sizeof(icmpHeader)));
aMessage.SetOffset(0);
SuccessOrExit(error = Ip6::SendDatagram(aMessage, messageInfoLocal, kProtoIcmp6));
SuccessOrExit(error = sIp6->SendDatagram(aMessage, messageInfoLocal, kProtoIcmp6));
otLogInfoIcmp("Sent echo request\n");
@@ -113,7 +116,7 @@ ThreadError Icmp::SendError(const Address &aDestination, IcmpHeader::Type aType,
Message *message = NULL;
IcmpHeader icmp6Header;
VerifyOrExit((message = Ip6::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
VerifyOrExit((message = sIp6->NewMessage(0)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(aHeader)));
message->Write(sizeof(icmp6Header), sizeof(aHeader), &aHeader);
@@ -126,7 +129,7 @@ ThreadError Icmp::SendError(const Address &aDestination, IcmpHeader::Type aType,
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.mPeerAddr = aDestination;
SuccessOrExit(error = Ip6::SendDatagram(*message, messageInfo, kProtoIcmp6));
SuccessOrExit(error = sIp6->SendDatagram(*message, messageInfo, kProtoIcmp6));
otLogInfoIcmp("Sent ICMPv6 Error\n");
@@ -203,7 +206,7 @@ ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo
icmp6Header.Init();
icmp6Header.SetType(IcmpHeader::kTypeEchoReply);
VerifyOrExit((replyMessage = Ip6::NewMessage(0)) != NULL, otLogDebgIcmp("icmp fail\n"));
VerifyOrExit((replyMessage = sIp6->NewMessage(0)) != NULL, otLogDebgIcmp("icmp fail\n"));
payloadLength = aRequestMessage.GetLength() - aRequestMessage.GetOffset() - IcmpHeader::GetDataOffset();
SuccessOrExit(replyMessage->SetLength(IcmpHeader::GetDataOffset() + payloadLength));
@@ -221,7 +224,7 @@ ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo
replyMessageInfo.mInterfaceId = aMessageInfo.mInterfaceId;
SuccessOrExit(error = Ip6::SendDatagram(*replyMessage, replyMessageInfo, kProtoIcmp6));
SuccessOrExit(error = sIp6->SendDatagram(*replyMessage, replyMessageInfo, kProtoIcmp6));
otLogInfoIcmp("Sent Echo Reply\n");
+24 -35
View File
@@ -39,7 +39,6 @@
#include <net/icmp6.hpp>
#include <net/ip6.hpp>
#include <net/ip6_address.hpp>
#include <net/ip6_mpl.hpp>
#include <net/ip6_routes.hpp>
#include <net/netif.hpp>
#include <net/udp6.hpp>
@@ -48,32 +47,22 @@
namespace Thread {
namespace Ip6 {
static otDEFINE_ALIGNED_VAR(sMplBuf, sizeof(Mpl), uint64_t);
static Mpl *sMpl;
static bool sForwardingEnabled;
static otReceiveIp6DatagramCallback sReceiveIp6DatagramCallback = NULL;
static void *sReceiveIp6DatagramCallbackContext = NULL;
static bool sIsReceiveIp6FilterEnabled;
static ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo);
Ip6::Ip6(void):
mForwardingEnabled(false),
mReceiveIp6DatagramCallback(NULL),
mReceiveIp6DatagramCallbackContext(NULL),
mIsReceiveIp6FilterEnabled(false)
{
}
Message *Ip6::NewMessage(uint16_t reserved)
{
return Message::New(Message::kTypeIp6,
sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + reserved);
}
void Ip6::Init(void)
{
sMpl = new(&sMplBuf) Mpl;
sForwardingEnabled = false;
sIsReceiveIp6FilterEnabled = true;
return Message::New(Message::kTypeIp6, sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + reserved);
}
void Ip6::SetForwardingEnabled(bool aEnable)
{
sForwardingEnabled = aEnable;
mForwardingEnabled = aEnable;
}
uint16_t Ip6::UpdateChecksum(uint16_t checksum, uint16_t val)
@@ -113,21 +102,21 @@ uint16_t Ip6::ComputePseudoheaderChecksum(const Address &src, const Address &dst
void Ip6::SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext)
{
sReceiveIp6DatagramCallback = aCallback;
sReceiveIp6DatagramCallbackContext = aCallbackContext;
mReceiveIp6DatagramCallback = aCallback;
mReceiveIp6DatagramCallbackContext = aCallbackContext;
}
bool Ip6::IsReceiveIp6FilterEnabled(void)
{
return sIsReceiveIp6FilterEnabled;
return mIsReceiveIp6FilterEnabled;
}
void Ip6::SetReceiveIp6FilterEnabled(bool aEnabled)
{
sIsReceiveIp6FilterEnabled = aEnabled;
mIsReceiveIp6FilterEnabled = aEnabled;
}
ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength)
ThreadError Ip6::AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength)
{
ThreadError error = kThreadError_None;
HopByHopHeader hbhHeader;
@@ -135,7 +124,7 @@ ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, u
hbhHeader.SetNextHeader(nextHeader);
hbhHeader.SetLength(0);
sMpl->InitOption(mplOption, HostSwap16(header.GetSource().mFields.m16[7]));
mMpl.InitOption(mplOption, HostSwap16(header.GetSource().mFields.m16[7]));
SuccessOrExit(error = message.Prepend(&mplOption, sizeof(mplOption)));
SuccessOrExit(error = message.Prepend(&hbhHeader, sizeof(hbhHeader)));
header.SetPayloadLength(sizeof(hbhHeader) + sizeof(mplOption) + payloadLength);
@@ -209,7 +198,7 @@ exit:
return error;
}
ThreadError HandleOptions(Message &message)
ThreadError Ip6::HandleOptions(Message &message)
{
ThreadError error = kThreadError_None;
HopByHopHeader hbhHeader;
@@ -228,7 +217,7 @@ ThreadError HandleOptions(Message &message)
switch (optionHeader.GetType())
{
case OptionMpl::kType:
SuccessOrExit(error = sMpl->ProcessOption(message));
SuccessOrExit(error = mMpl.ProcessOption(message));
break;
default:
@@ -260,7 +249,7 @@ exit:
return error;
}
ThreadError HandleFragment(Message &message)
ThreadError Ip6::HandleFragment(Message &message)
{
ThreadError error = kThreadError_None;
FragmentHeader fragmentHeader;
@@ -276,7 +265,7 @@ exit:
return error;
}
ThreadError HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive)
ThreadError Ip6::HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive)
{
ThreadError error = kThreadError_None;
ExtensionHeader extensionHeader;
@@ -339,9 +328,9 @@ void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &mes
ThreadError error = kThreadError_None;
Message *messageCopy = NULL;
VerifyOrExit(sReceiveIp6DatagramCallback != NULL, ;);
VerifyOrExit(mReceiveIp6DatagramCallback != NULL, ;);
if (sIsReceiveIp6FilterEnabled)
if (mIsReceiveIp6FilterEnabled)
{
// do not pass messages sent to/from an RLOC
VerifyOrExit(!messageInfo.GetSockAddr().IsRoutingLocator() &&
@@ -384,7 +373,7 @@ void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &mes
aMessage.CopyTo(0, 0, aMessage.GetLength(), *messageCopy);
messageCopy->SetLinkSecurityEnabled(aMessage.IsLinkSecurityEnabled());
sReceiveIp6DatagramCallback(messageCopy, sReceiveIp6DatagramCallbackContext);
mReceiveIp6DatagramCallback(messageCopy, mReceiveIp6DatagramCallbackContext);
exit:
@@ -464,7 +453,7 @@ ThreadError Ip6::HandleDatagram(Message &message, Netif *netif, int8_t interface
}
}
if (!sForwardingEnabled && netif != NULL)
if (!mForwardingEnabled && netif != NULL)
{
forward = false;
}
@@ -516,7 +505,7 @@ exit:
return error;
}
ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo)
ThreadError Ip6::ForwardMessage(Message &message, MessageInfo &messageInfo)
{
ThreadError error = kThreadError_None;
int8_t interfaceId;
+29 -402
View File
@@ -40,6 +40,8 @@
#include <common/encoding.hpp>
#include <common/message.hpp>
#include <net/ip6_address.hpp>
#include <net/ip6_headers.hpp>
#include <net/ip6_mpl.hpp>
#include <net/netif.hpp>
#include <net/socket.hpp>
@@ -84,393 +86,6 @@ namespace Ip6 {
*
*/
/**
* Internet Protocol Numbers
*/
enum IpProto
{
kProtoHopOpts = 0, ///< IPv6 Hop-by-Hop Option
kProtoTcp = 6, ///< Transmission Control Protocol
kProtoUdp = 17, ///< User Datagram
kProtoIp6 = 41, ///< IPv6 encapsulation
kProtoRouting = 43, ///< Routing Header for IPv6
kProtoFragment = 44, ///< Fragment Header for IPv6
kProtoIcmp6 = 58, ///< ICMP for IPv6
kProtoNone = 59, ///< No Next Header for IPv6
kProtoDstOpts = 60, ///< Destination Options for IPv6
};
enum
{
kVersionClassFlowSize = 4, ///< Combined size of Version, Class, Flow Label in bytes.
};
/**
* This structure represents an IPv6 header.
*
*/
OT_TOOL_PACKED_BEGIN
struct HeaderPoD
{
union
{
uint8_t m8[kVersionClassFlowSize / sizeof(uint8_t)];
uint16_t m16[kVersionClassFlowSize / sizeof(uint16_t)];
uint32_t m32[kVersionClassFlowSize / sizeof(uint32_t)];
} mVersionClassFlow; ///< Version, Class, Flow Label
uint16_t mPayloadLength; ///< Payload Length
uint8_t mNextHeader; ///< Next Header
uint8_t mHopLimit; ///< Hop Limit
otIp6Address mSource; ///< Source
otIp6Address mDestination; ///< Destination
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 header generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class Header: private HeaderPoD
{
public:
/**
* This method initializes the IPv6 header.
*
*/
void Init() { mVersionClassFlow.m32[0] = 0; mVersionClassFlow.m8[0] = kVersion6; }
/**
* This method indicates whether or not the IPv6 Version is set to 6.
*
* @retval TRUE If the IPv6 Version is set to 6.
* @retval FALSE If the IPv6 Version is not set to 6.
*
*/
bool IsVersion6() const { return (mVersionClassFlow.m8[0] & kVersionMask) == kVersion6; }
/**
* This method returns the IPv6 Payload Length value.
*
* @returns The IPv6 Payload Length value.
*
*/
uint16_t GetPayloadLength() { return HostSwap16(mPayloadLength); }
/**
* This method sets the IPv6 Payload Length value.
*
* @param[in] aLength The IPv6 Payload Length value.
*
*/
void SetPayloadLength(uint16_t aLength) { mPayloadLength = HostSwap16(aLength); }
/**
* This method returns the IPv6 Next Header value.
*
* @returns The IPv6 Next Header value.
*
*/
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
/**
* This method sets the IPv6 Next Header value.
*
* @param[in] aNextHeader The IPv6 Next Header value.
*
*/
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
/**
* This method returns the IPv6 Hop Limit value.
*
* @returns The IPv6 Hop Limit value.
*
*/
uint8_t GetHopLimit() const { return mHopLimit; }
/**
* This method sets the IPv6 Hop Limit value.
*
* @param[in] aHopLimit The IPv6 Hop Limit value.
*
*/
void SetHopLimit(uint8_t aHopLimit) { mHopLimit = aHopLimit; }
/**
* This method returns the IPv6 Source address.
*
* @returns A reference to the IPv6 Source address.
*
*/
Address &GetSource() { return static_cast<Address &>(mSource); }
/**
* This method sets the IPv6 Source address.
*
* @param[in] aSource A reference to the IPv6 Source address.
*
*/
void SetSource(const Address &aSource) { mSource = aSource; }
/**
* This method returns the IPv6 Destination address.
*
* @returns A reference to the IPv6 Destination address.
*
*/
Address &GetDestination() { return static_cast<Address &>(mDestination); }
/**
* This method sets the IPv6 Destination address.
*
* @param[in] aDestination A reference to the IPv6 Destination address.
*
*/
void SetDestination(const Address &aDestination) { mDestination = aDestination; }
/**
* This static method returns the byte offset of the IPv6 Payload Length field.
*
* @returns The byte offset of the IPv6 Payload Length field.
*
*/
static uint8_t GetPayloadLengthOffset() { return offsetof(HeaderPoD, mPayloadLength); }
/**
* This static method returns the byte offset of the IPv6 Hop Limit field.
*
* @returns The byte offset of the IPv6 Hop Limit field.
*
*/
static uint8_t GetHopLimitOffset() { return offsetof(HeaderPoD, mHopLimit); }
/**
* This static method returns the size of the IPv6 Hop Limit field.
*
* @returns The size of the IPv6 Hop Limit field.
*
*/
static uint8_t GetHopLimitSize() { return sizeof(uint8_t); }
/**
* This static method returns the byte offset of the IPv6 Destination field.
*
* @returns The byte offset of the IPv6 Destination field.
*
*/
static uint8_t GetDestinationOffset() { return offsetof(HeaderPoD, mDestination); }
private:
enum
{
kVersion6 = 0x60,
kVersionMask = 0xf0,
};
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Extension Header generation and processing.
*
*/
OT_TOOL_PACKED_BEGIN
class ExtensionHeader
{
public:
/**
* This method returns the IPv6 Next Header value.
*
* @returns The IPv6 Next Header value.
*
*/
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
/**
* This method sets the IPv6 Next Header value.
*
* @param[in] aNextHeader The IPv6 Next Header value.
*
*/
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
/**
* This method returns the IPv6 Header Extension Length value.
*
* @returns The IPv6 Header Extension Length value.
*
*/
uint8_t GetLength() const { return mLength; }
/**
* This method sets the IPv6 Header Extension Length value.
*
* @param[in] aLength The IPv6 Header Extension Length value.
*
*/
void SetLength(uint8_t aLength) { mLength = aLength; }
private:
uint8_t mNextHeader;
uint8_t mLength;
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Hop-by-Hop Options Header generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class HopByHopHeader: public ExtensionHeader
{
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Options generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class OptionHeader
{
public:
/**
* This method returns the IPv6 Option Type value.
*
* @returns The IPv6 Option Type value.
*
*/
uint8_t GetType() const { return mType; }
/**
* This method sets the IPv6 Option Type value.
*
* @param[in] aType The IPv6 Option Type value.
*
*/
void SetType(uint8_t aType) { mType = aType; }
/**
* IPv6 Option Type actions for unrecognized IPv6 Options.
*
*/
enum Action
{
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
kActionMask = 0xc0, ///< mask for action bits
};
/**
* This method returns the IPv6 Option action for unrecognized IPv6 Options.
*
* @returns The IPv6 Option action for unrecognized IPv6 Options.
*
*/
Action GetAction() const { return static_cast<Action>(mType & kActionMask); }
/**
* This method returns the IPv6 Option Length value.
*
* @returns The IPv6 Option Length value.
*
*/
uint8_t GetLength() const { return mLength; }
/**
* This method sets the IPv6 Option Length value.
*
* @param[in] aLength The IPv6 Option Length value.
*
*/
void SetLength(uint8_t aLength) { mLength = aLength; }
private:
uint8_t mType;
uint8_t mLength;
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Fragment Header generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class FragmentHeader
{
public:
/**
* This method initializes the IPv6 Fragment header.
*
*/
void Init() { mReserved = 0; mIdentification = 0; }
/**
* This method returns the IPv6 Next Header value.
*
* @returns The IPv6 Next Header value.
*
*/
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
/**
* This method sets the IPv6 Next Header value.
*
* @param[in] aNextHeader The IPv6 Next Header value.
*
*/
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
/**
* This method returns the Fragment Offset value.
*
* @returns The Fragment Offset value.
*
*/
uint16_t GetOffset() { return (HostSwap16(mOffsetMore) & kOffsetMask) >> kOffsetOffset; }
/**
* This method sets the Fragment Offset value.
*
* @param[in] aOffset The Fragment Offset value.
*/
void SetOffset(uint16_t aOffset) {
uint16_t tmp = HostSwap16(mOffsetMore);
tmp = (tmp & ~kOffsetMask) | ((aOffset << kOffsetOffset) & kOffsetMask);
mOffsetMore = HostSwap16(tmp);
}
/**
* This method returns the M flag value.
*
* @returns The M flag value.
*
*/
bool IsMoreFlagSet() { return HostSwap16(mOffsetMore) & kMoreFlag; }
/**
* This method clears the M flag value.
*
*/
void ClearMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) & ~kMoreFlag); }
/**
* This method sets the M flag value.
*
*/
void SetMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) | kMoreFlag); }
private:
uint8_t mNextHeader;
uint8_t mReserved;
enum
{
kOffsetOffset = 3,
kOffsetMask = 0xfff8,
kMoreFlag = 1,
};
uint16_t mOffsetMore;
uint32_t mIdentification;
} OT_TOOL_PACKED_END;
/**
* This class implements the core IPv6 message processing.
*
@@ -485,22 +100,22 @@ public:
};
/**
* This static method allocates a new message buffer from the buffer pool.
* This method allocates a new message buffer from the buffer pool.
*
* @param[in] aReserved The number of header bytes to reserve following the IPv6 header.
*
* @returns A pointer to the message or NULL if insufficient message buffers are available.
*
*/
static Message *NewMessage(uint16_t aReserved);
Message *NewMessage(uint16_t aReserved);
/**
* This static method for initialization.
* This constructor initializes the object.
*/
static void Init(void);
Ip6(void);
/**
* This static method sends an IPv6 datagram.
* This method sends an IPv6 datagram.
*
* @param[in] aMessage A reference to the message.
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
@@ -510,10 +125,10 @@ public:
* @retval kThreadError_NoBufs Insufficient available buffer to add the IPv6 headers.
*
*/
static ThreadError SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto aIpProto);
ThreadError SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto aIpProto);
/**
* This static method processes a received IPv6 datagram.
* This method processes a received IPv6 datagram.
*
* @param[in] aMessage A reference to the message.
* @param[in] aNetif A pointer to the network interface that received the message.
@@ -525,8 +140,8 @@ public:
* @retval kThreadError_Drop Message processing failed and the message should be dropped.
*
*/
static ThreadError HandleDatagram(Message &aMessage, Netif *aNetif, int8_t aInterfaceId,
const void *aLinkMessageInfo, bool aFromNcpHost);
ThreadError HandleDatagram(Message &aMessage, Netif *aNetif, int8_t aInterfaceId,
const void *aLinkMessageInfo, bool aFromNcpHost);
/**
* This static method updates a checksum.
@@ -590,7 +205,7 @@ public:
* @sa SetReceiveIp6FilterEnabled
*
*/
static void SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext);
void SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext);
/**
* This method indicates whether or not Thread control traffic is filtered out when delivering IPv6 datagrams
@@ -602,7 +217,7 @@ public:
* @sa SetReceiveIp6FilterEnabled
*
*/
static bool IsReceiveIp6FilterEnabled(void);
bool IsReceiveIp6FilterEnabled(void);
/**
* This method sets whether or not Thread control traffic is filtered out when delivering IPv6 datagrams
@@ -614,18 +229,30 @@ public:
* @sa IsReceiveIp6FilterEnabled
*
*/
static void SetReceiveIp6FilterEnabled(bool aEnabled);
void SetReceiveIp6FilterEnabled(bool aEnabled);
/**
* This static method enables/disables IPv6 forwarding.
* This method enables/disables IPv6 forwarding.
*
* @param[in] aEnable TRUE to enable IPv6 forwarding, FALSE otherwise.
*
*/
static void SetForwardingEnabled(bool aEnable);
void SetForwardingEnabled(bool aEnable);
private:
static void ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto);
void ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto);
ThreadError HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive);
ThreadError HandleFragment(Message &message);
ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength);
ThreadError HandleOptions(Message &message);
ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo);
Mpl mMpl;
bool mForwardingEnabled;
otReceiveIp6DatagramCallback mReceiveIp6DatagramCallback;
void *mReceiveIp6DatagramCallbackContext;
bool mIsReceiveIp6FilterEnabled;
};
/**
+481
View File
@@ -0,0 +1,481 @@
/*
* Copyright (c) 2016, Nest Labs, Inc.
* 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 includes definitions for IPv6 packet processing.
*/
#ifndef IP6_HEADERS_HPP_
#define IP6_HEADERS_HPP_
#include <stddef.h>
#include <openthread-types.h>
#include <common/encoding.hpp>
#include <common/message.hpp>
#include <net/ip6_address.hpp>
#include <net/netif.hpp>
#include <net/socket.hpp>
using Thread::Encoding::BigEndian::HostSwap16;
namespace Thread {
/**
* @namespace Thread::Ip6
*
* @brief
* This namespace includes definitions for IPv6 networking.
*
*/
namespace Ip6 {
/**
* @addtogroup core-ipv6
*
* @brief
* This module includes definitions for the IPv6 network layer.
*
* @{
*
* @defgroup core-ip6-icmp6 ICMPv6
* @defgroup core-ip6-ip6 IPv6
* @defgroup core-ip6-mpl MPL
* @defgroup core-ip6-netif Network Interfaces
*
* @}
*
*/
/**
* @addtogroup core-ip6-ip6
*
* @brief
* This module includes definitions for core IPv6 networking.
*
* @{
*
*/
/**
* Internet Protocol Numbers
*/
enum IpProto
{
kProtoHopOpts = 0, ///< IPv6 Hop-by-Hop Option
kProtoTcp = 6, ///< Transmission Control Protocol
kProtoUdp = 17, ///< User Datagram
kProtoIp6 = 41, ///< IPv6 encapsulation
kProtoRouting = 43, ///< Routing Header for IPv6
kProtoFragment = 44, ///< Fragment Header for IPv6
kProtoIcmp6 = 58, ///< ICMP for IPv6
kProtoNone = 59, ///< No Next Header for IPv6
kProtoDstOpts = 60, ///< Destination Options for IPv6
};
enum
{
kVersionClassFlowSize = 4, ///< Combined size of Version, Class, Flow Label in bytes.
};
/**
* This structure represents an IPv6 header.
*
*/
OT_TOOL_PACKED_BEGIN
struct HeaderPoD
{
union
{
uint8_t m8[kVersionClassFlowSize / sizeof(uint8_t)];
uint16_t m16[kVersionClassFlowSize / sizeof(uint16_t)];
uint32_t m32[kVersionClassFlowSize / sizeof(uint32_t)];
} mVersionClassFlow; ///< Version, Class, Flow Label
uint16_t mPayloadLength; ///< Payload Length
uint8_t mNextHeader; ///< Next Header
uint8_t mHopLimit; ///< Hop Limit
otIp6Address mSource; ///< Source
otIp6Address mDestination; ///< Destination
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 header generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class Header: private HeaderPoD
{
public:
/**
* This method initializes the IPv6 header.
*
*/
void Init() { mVersionClassFlow.m32[0] = 0; mVersionClassFlow.m8[0] = kVersion6; }
/**
* This method indicates whether or not the IPv6 Version is set to 6.
*
* @retval TRUE If the IPv6 Version is set to 6.
* @retval FALSE If the IPv6 Version is not set to 6.
*
*/
bool IsVersion6() const { return (mVersionClassFlow.m8[0] & kVersionMask) == kVersion6; }
/**
* This method returns the IPv6 Payload Length value.
*
* @returns The IPv6 Payload Length value.
*
*/
uint16_t GetPayloadLength() { return HostSwap16(mPayloadLength); }
/**
* This method sets the IPv6 Payload Length value.
*
* @param[in] aLength The IPv6 Payload Length value.
*
*/
void SetPayloadLength(uint16_t aLength) { mPayloadLength = HostSwap16(aLength); }
/**
* This method returns the IPv6 Next Header value.
*
* @returns The IPv6 Next Header value.
*
*/
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
/**
* This method sets the IPv6 Next Header value.
*
* @param[in] aNextHeader The IPv6 Next Header value.
*
*/
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
/**
* This method returns the IPv6 Hop Limit value.
*
* @returns The IPv6 Hop Limit value.
*
*/
uint8_t GetHopLimit() const { return mHopLimit; }
/**
* This method sets the IPv6 Hop Limit value.
*
* @param[in] aHopLimit The IPv6 Hop Limit value.
*
*/
void SetHopLimit(uint8_t aHopLimit) { mHopLimit = aHopLimit; }
/**
* This method returns the IPv6 Source address.
*
* @returns A reference to the IPv6 Source address.
*
*/
Address &GetSource() { return static_cast<Address &>(mSource); }
/**
* This method sets the IPv6 Source address.
*
* @param[in] aSource A reference to the IPv6 Source address.
*
*/
void SetSource(const Address &aSource) { mSource = aSource; }
/**
* This method returns the IPv6 Destination address.
*
* @returns A reference to the IPv6 Destination address.
*
*/
Address &GetDestination() { return static_cast<Address &>(mDestination); }
/**
* This method sets the IPv6 Destination address.
*
* @param[in] aDestination A reference to the IPv6 Destination address.
*
*/
void SetDestination(const Address &aDestination) { mDestination = aDestination; }
/**
* This static method returns the byte offset of the IPv6 Payload Length field.
*
* @returns The byte offset of the IPv6 Payload Length field.
*
*/
static uint8_t GetPayloadLengthOffset() { return offsetof(HeaderPoD, mPayloadLength); }
/**
* This static method returns the byte offset of the IPv6 Hop Limit field.
*
* @returns The byte offset of the IPv6 Hop Limit field.
*
*/
static uint8_t GetHopLimitOffset() { return offsetof(HeaderPoD, mHopLimit); }
/**
* This static method returns the size of the IPv6 Hop Limit field.
*
* @returns The size of the IPv6 Hop Limit field.
*
*/
static uint8_t GetHopLimitSize() { return sizeof(uint8_t); }
/**
* This static method returns the byte offset of the IPv6 Destination field.
*
* @returns The byte offset of the IPv6 Destination field.
*
*/
static uint8_t GetDestinationOffset() { return offsetof(HeaderPoD, mDestination); }
private:
enum
{
kVersion6 = 0x60,
kVersionMask = 0xf0,
};
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Extension Header generation and processing.
*
*/
OT_TOOL_PACKED_BEGIN
class ExtensionHeader
{
public:
/**
* This method returns the IPv6 Next Header value.
*
* @returns The IPv6 Next Header value.
*
*/
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
/**
* This method sets the IPv6 Next Header value.
*
* @param[in] aNextHeader The IPv6 Next Header value.
*
*/
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
/**
* This method returns the IPv6 Header Extension Length value.
*
* @returns The IPv6 Header Extension Length value.
*
*/
uint8_t GetLength() const { return mLength; }
/**
* This method sets the IPv6 Header Extension Length value.
*
* @param[in] aLength The IPv6 Header Extension Length value.
*
*/
void SetLength(uint8_t aLength) { mLength = aLength; }
private:
uint8_t mNextHeader;
uint8_t mLength;
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Hop-by-Hop Options Header generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class HopByHopHeader: public ExtensionHeader
{
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Options generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class OptionHeader
{
public:
/**
* This method returns the IPv6 Option Type value.
*
* @returns The IPv6 Option Type value.
*
*/
uint8_t GetType() const { return mType; }
/**
* This method sets the IPv6 Option Type value.
*
* @param[in] aType The IPv6 Option Type value.
*
*/
void SetType(uint8_t aType) { mType = aType; }
/**
* IPv6 Option Type actions for unrecognized IPv6 Options.
*
*/
enum Action
{
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
kActionMask = 0xc0, ///< mask for action bits
};
/**
* This method returns the IPv6 Option action for unrecognized IPv6 Options.
*
* @returns The IPv6 Option action for unrecognized IPv6 Options.
*
*/
Action GetAction() const { return static_cast<Action>(mType & kActionMask); }
/**
* This method returns the IPv6 Option Length value.
*
* @returns The IPv6 Option Length value.
*
*/
uint8_t GetLength() const { return mLength; }
/**
* This method sets the IPv6 Option Length value.
*
* @param[in] aLength The IPv6 Option Length value.
*
*/
void SetLength(uint8_t aLength) { mLength = aLength; }
private:
uint8_t mType;
uint8_t mLength;
} OT_TOOL_PACKED_END;
/**
* This class implements IPv6 Fragment Header generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class FragmentHeader
{
public:
/**
* This method initializes the IPv6 Fragment header.
*
*/
void Init() { mReserved = 0; mIdentification = 0; }
/**
* This method returns the IPv6 Next Header value.
*
* @returns The IPv6 Next Header value.
*
*/
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
/**
* This method sets the IPv6 Next Header value.
*
* @param[in] aNextHeader The IPv6 Next Header value.
*
*/
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
/**
* This method returns the Fragment Offset value.
*
* @returns The Fragment Offset value.
*
*/
uint16_t GetOffset() { return (HostSwap16(mOffsetMore) & kOffsetMask) >> kOffsetOffset; }
/**
* This method sets the Fragment Offset value.
*
* @param[in] aOffset The Fragment Offset value.
*/
void SetOffset(uint16_t aOffset) {
uint16_t tmp = HostSwap16(mOffsetMore);
tmp = (tmp & ~kOffsetMask) | ((aOffset << kOffsetOffset) & kOffsetMask);
mOffsetMore = HostSwap16(tmp);
}
/**
* This method returns the M flag value.
*
* @returns The M flag value.
*
*/
bool IsMoreFlagSet() { return HostSwap16(mOffsetMore) & kMoreFlag; }
/**
* This method clears the M flag value.
*
*/
void ClearMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) & ~kMoreFlag); }
/**
* This method sets the M flag value.
*
*/
void SetMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) | kMoreFlag); }
private:
uint8_t mNextHeader;
uint8_t mReserved;
enum
{
kOffsetOffset = 3,
kOffsetMask = 0xfff8,
kMoreFlag = 1,
};
uint16_t mOffsetMore;
uint32_t mIdentification;
} OT_TOOL_PACKED_END;
/**
* @}
*
*/
} // namespace Ip6
} // namespace Thread
#endif // NET_IP6_HEADERS_HPP_
+1 -1
View File
@@ -37,7 +37,7 @@
#include <openthread-types.h>
#include <common/message.hpp>
#include <common/timer.hpp>
#include <net/ip6.hpp>
#include <net/ip6_headers.hpp>
namespace Thread {
namespace Ip6 {
+8 -2
View File
@@ -42,8 +42,9 @@ namespace Ip6 {
Netif *Netif::sNetifListHead = NULL;
int8_t Netif::sNextInterfaceId = 1;
Netif::Netif() :
mStateChangedTask(&HandleStateChangedTask, this)
Netif::Netif(Ip6 &aIp6):
mStateChangedTask(&HandleStateChangedTask, this),
mIp6(aIp6)
{
mCallbacks = NULL;
mUnicastAddresses = NULL;
@@ -146,6 +147,11 @@ Netif *Netif::GetNext() const
return mNext;
}
Ip6 &Netif::GetIp6(void)
{
return mIp6;
}
Netif *Netif::GetNetifById(int8_t aInterfaceId)
{
Netif *netif;
+15 -1
View File
@@ -43,6 +43,8 @@
namespace Thread {
namespace Ip6 {
class Ip6;
/**
* @addtogroup core-ip6-netif
*
@@ -196,8 +198,10 @@ public:
/**
* This constructor initializes the network interface.
*
* @param[in] aIp6 A reference to the IPv6 network object.
*
*/
Netif(void);
Netif(Ip6 &aIp6);
/**
* This method enables the network interface.
@@ -217,6 +221,14 @@ public:
*/
ThreadError RemoveNetif(void);
/**
* This method returns a reference to the IPv6 network object.
*
* @returns A reference to the IPv6 network object.
*
*/
Ip6 &GetIp6(void);
/**
* This method returns the next network interface in the list.
*
@@ -472,6 +484,8 @@ private:
Tasklet mStateChangedTask;
Netif *mNext;
Ip6 &mIp6;
uint32_t mStateChangedFlags;
NetifUnicastAddress mExtUnicastAddresses[OPENTHREAD_CONFIG_MAX_EXT_IP_ADDRS];
+1 -1
View File
@@ -35,7 +35,7 @@
#define TCP_HPP_
#include <openthread.h>
#include <net/ip6.hpp>
#include <net/ip6_headers.hpp>
namespace Thread {
namespace Ip6 {
+5 -2
View File
@@ -41,6 +41,9 @@
using Thread::Encoding::BigEndian::HostSwap16;
namespace Thread {
extern Ip6::Ip6 *sIp6;
namespace Ip6 {
UdpSocket *Udp::sSockets = NULL;
@@ -135,7 +138,7 @@ ThreadError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo
SuccessOrExit(error = aMessage.Prepend(&udpHeader, sizeof(udpHeader)));
aMessage.SetOffset(0);
SuccessOrExit(error = Ip6::SendDatagram(aMessage, messageInfoLocal, kProtoUdp));
SuccessOrExit(error = sIp6->SendDatagram(aMessage, messageInfoLocal, kProtoUdp));
exit:
return error;
@@ -143,7 +146,7 @@ exit:
Message *Udp::NewMessage(uint16_t aReserved)
{
return Ip6::NewMessage(sizeof(UdpHeader) + aReserved);
return sIp6->NewMessage(sizeof(UdpHeader) + aReserved);
}
ThreadError Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
+9 -7
View File
@@ -57,6 +57,9 @@ ThreadNetif *sThreadNetif;
static Ip6::NetifCallback sNetifCallback;
static bool mEnabled = false;
static otDEFINE_ALIGNED_VAR(sIp6Raw, sizeof(Ip6::Ip6), uint64_t);
Ip6::Ip6 *sIp6;
#ifdef __cplusplus
extern "C" {
#endif
@@ -870,8 +873,8 @@ ThreadError otEnable(void)
otLogInfoApi("otEnable\n");
Message::Init();
sThreadNetif = new(&sThreadNetifRaw) ThreadNetif;
Ip6::Ip6::Init();
sIp6 = new(&sIp6Raw) Ip6::Ip6;
sThreadNetif = new(&sThreadNetifRaw) ThreadNetif(*sIp6);
mEnabled = true;
exit:
@@ -1047,23 +1050,22 @@ void HandleMleDiscover(otActiveScanResult *aResult, void *aContext)
void otSetReceiveIp6DatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext)
{
Ip6::Ip6::SetReceiveDatagramCallback(aCallback, aCallbackContext);
sIp6->SetReceiveDatagramCallback(aCallback, aCallbackContext);
}
bool otIsReceiveIp6DatagramFilterEnabled(void)
{
return Ip6::Ip6::IsReceiveIp6FilterEnabled();
return sIp6->IsReceiveIp6FilterEnabled();
}
void otSetReceiveIp6DatagramFilterEnabled(bool aEnabled)
{
Ip6::Ip6::SetReceiveIp6FilterEnabled(aEnabled);
sIp6->SetReceiveIp6FilterEnabled(aEnabled);
}
ThreadError otSendIp6Datagram(otMessage aMessage)
{
return Ip6::Ip6::HandleDatagram(*static_cast<Message *>(aMessage), NULL, sThreadNetif->GetInterfaceId(),
NULL, true);
return sIp6->HandleDatagram(*static_cast<Message *>(aMessage), NULL, sThreadNetif->GetInterfaceId(), NULL, true);
}
otMessage otNewUdpMessage(void)
+1 -1
View File
@@ -1441,7 +1441,7 @@ exit:
ThreadError MeshForwarder::HandleDatagram(Message &aMessage, const ThreadMessageInfo &aMessageInfo)
{
return Ip6::Ip6::HandleDatagram(aMessage, &mNetif, mNetif.GetInterfaceId(), &aMessageInfo, false);
return mNetif.GetIp6().HandleDatagram(aMessage, &mNetif, mNetif.GetInterfaceId(), &aMessageInfo, false);
}
void MeshForwarder::UpdateFramePending()
+2 -2
View File
@@ -344,7 +344,7 @@ ThreadError Mle::SetStateDetached(void)
mParentRequestTimer.Stop();
mMesh.SetRxOnWhenIdle(true);
mMleRouter.HandleDetachStart();
Ip6::Ip6::SetForwardingEnabled(false);
mNetif.GetIp6().SetForwardingEnabled(false);
otLogInfoMle("Mode -> Detached\n");
return kThreadError_None;
@@ -371,7 +371,7 @@ ThreadError Mle::SetStateChild(uint16_t aRloc16)
mMleRouter.HandleChildStart(mParentRequestMode);
}
Ip6::Ip6::SetForwardingEnabled(false);
mNetif.GetIp6().SetForwardingEnabled(false);
otLogInfoMle("Mode -> Child\n");
return kThreadError_None;
+2 -2
View File
@@ -340,7 +340,7 @@ ThreadError MleRouter::SetStateRouter(uint16_t aRloc16)
mRouters[mRouterId].mNextHop = mRouterId;
mNetworkData.Stop();
mStateUpdateTimer.Start(kStateUpdatePeriod);
Ip6::Ip6::SetForwardingEnabled(true);
mNetif.GetIp6().SetForwardingEnabled(true);
otLogInfoMle("Mode -> Router\n");
return kThreadError_None;
@@ -367,7 +367,7 @@ ThreadError MleRouter::SetStateLeader(uint16_t aRloc16)
mNetif.GetPendingDataset().ApplyLocalToNetwork();
mCoapServer.AddResource(mAddressSolicit);
mCoapServer.AddResource(mAddressRelease);
Ip6::Ip6::SetForwardingEnabled(true);
mNetif.GetIp6().SetForwardingEnabled(true);
otLogInfoMle("Mode -> Leader %d\n", mLeaderData.GetPartitionId());
return kThreadError_None;
+2 -1
View File
@@ -54,7 +54,8 @@ static const uint8_t kThreadMasterKey[] =
static const char name[] = "thread";
ThreadNetif::ThreadNetif(void):
ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
Netif(aIp6),
mCoapServer(kCoapUdpPort),
mAddressResolver(*this),
mActiveDataset(*this),
+3 -1
View File
@@ -63,8 +63,10 @@ public:
/**
* This constructor initializes the Thread network interface.
*
* @param[in] aIp6 A reference to the IPv6 network object.
*
*/
ThreadNetif(void);
ThreadNetif(Ip6::Ip6 &aIp6);
/**
* This method enables the Thread network interface.
+3 -2
View File
@@ -45,6 +45,7 @@ namespace Thread
{
extern ThreadNetif *sThreadNetif;
extern Ip6::Ip6 *sIp6;
static NcpBase *sNcpContext = NULL;
@@ -3102,7 +3103,7 @@ ThreadError NcpBase::SetPropertyHandler_STREAM_NET_INSECURE(uint8_t header, spin
unsigned int frame_len(0);
const uint8_t *meta_ptr(NULL);
unsigned int meta_len(0);
Message *message(Ip6::Ip6::NewMessage(0));
Message *message(Message::New(Message::kTypeIp6, 0));
if (message == NULL)
{
@@ -3173,7 +3174,7 @@ ThreadError NcpBase::SetPropertyHandler_STREAM_NET(uint8_t header, spinel_prop_k
unsigned int frame_len(0);
const uint8_t *meta_ptr(NULL);
unsigned int meta_len(0);
Message *message(Ip6::Ip6::NewMessage(0));
Message *message(Message::New(Message::kTypeIp6, 0));
if (message == NULL)
{
+3 -2
View File
@@ -75,7 +75,8 @@ extern "C" void otPlatDiagRadioReceiveDone(RadioPacket *aFrame, ThreadError aErr
(void)aError;
}
ThreadNetif sMockThreadNetif;
Ip6::Ip6 sIp6;
ThreadNetif sMockThreadNetif(sIp6);
Lowpan::Lowpan sMockLowpan(sMockThreadNetif);
void TestLowpanIphc(void)
@@ -116,7 +117,7 @@ void TestLowpanIphc(void)
frame.GetSrcAddr(macSource);
frame.GetDstAddr(macDest);
VerifyOrQuit((message = Ip6::Ip6::NewMessage(0)) != NULL,
VerifyOrQuit((message = sIp6.NewMessage(0)) != NULL,
"6lo: Ip6::NewMessage failed");
// ===> Test Lowpan::Decompress