mirror of
https://github.com/espressif/openthread.git
synced 2026-09-14 21:20:11 +00:00
Remove globals from ip6.cpp.
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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_
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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];
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#define TCP_HPP_
|
||||
|
||||
#include <openthread.h>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_headers.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user