mirror of
https://github.com/espressif/openthread.git
synced 2026-08-20 17:39:51 +00:00
[ip6] clean up return values for otIp6Send() (#3751)
- Return OT_ERROR_PARSE when encountering mal-formatted headers. - Return OT_ERROR_NO_ROUTE when there is no route to host. - Document possible return values for `otIp6Send()`.
This commit is contained in:
@@ -409,9 +409,18 @@ void otIp6SetReceiveFilterEnabled(otInstance *aInstance, bool aEnabled);
|
||||
/**
|
||||
* This function sends an IPv6 datagram via the Thread interface.
|
||||
*
|
||||
* The caller transfers ownership of @p aMessage when making this call. OpenThread will free @p aMessage when
|
||||
* processing is complete, including when a value other than `OT_ERROR_NONE` is returned.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMessage A pointer to the message buffer containing the IPv6 datagram.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully processed the message.
|
||||
* @retval OT_ERROR_DROP Message was well-formed but not fully processed due to packet processing rules.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate necessary message buffers when processing the datagram.
|
||||
* @retval OT_ERROR_NO_ROUTE No route to host.
|
||||
* @retval OT_ERROR_PARSE Encountered a malformed header when processing the message.
|
||||
*
|
||||
*/
|
||||
otError otIp6Send(otInstance *aInstance, otMessage *aMessage);
|
||||
|
||||
|
||||
@@ -215,6 +215,7 @@ otError Ip6::AddMplOption(Message &aMessage, Header &aHeader)
|
||||
SuccessOrExit(error = aMessage.Prepend(&hbhHeader, sizeof(hbhHeader)));
|
||||
aHeader.SetPayloadLength(aHeader.GetPayloadLength() + sizeof(hbhHeader) + sizeof(mplOption));
|
||||
aHeader.SetNextHeader(kProtoHopOpts);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
@@ -554,17 +555,17 @@ otError Ip6::HandleOptions(Message &aMessage, Header &aHeader, bool &aForward)
|
||||
uint16_t endOffset;
|
||||
|
||||
VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(hbhHeader), &hbhHeader) == sizeof(hbhHeader),
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
endOffset = aMessage.GetOffset() + (hbhHeader.GetLength() + 1) * 8;
|
||||
|
||||
VerifyOrExit(endOffset <= aMessage.GetLength(), error = OT_ERROR_DROP);
|
||||
VerifyOrExit(endOffset <= aMessage.GetLength(), error = OT_ERROR_PARSE);
|
||||
|
||||
aMessage.MoveOffset(sizeof(optionHeader));
|
||||
|
||||
while (aMessage.GetOffset() < endOffset)
|
||||
{
|
||||
VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(optionHeader), &optionHeader) == sizeof(optionHeader),
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
if (optionHeader.GetType() == OptionPad1::kType)
|
||||
{
|
||||
@@ -573,7 +574,7 @@ otError Ip6::HandleOptions(Message &aMessage, Header &aHeader, bool &aForward)
|
||||
}
|
||||
|
||||
VerifyOrExit(aMessage.GetOffset() + sizeof(optionHeader) + optionHeader.GetLength() <= endOffset,
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
switch (optionHeader.GetType())
|
||||
{
|
||||
@@ -615,7 +616,7 @@ otError Ip6::HandleFragment(Message &aMessage)
|
||||
FragmentHeader fragmentHeader;
|
||||
|
||||
VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(fragmentHeader), &fragmentHeader) == sizeof(fragmentHeader),
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
VerifyOrExit(fragmentHeader.GetOffset() == 0 && fragmentHeader.IsMoreFlagSet() == false, error = OT_ERROR_DROP);
|
||||
|
||||
@@ -637,7 +638,7 @@ otError Ip6::HandleExtensionHeaders(Message &aMessage,
|
||||
while (aReceive == true || aNextHeader == kProtoHopOpts)
|
||||
{
|
||||
VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(extHeader), &extHeader) == sizeof(extHeader),
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
switch (aNextHeader)
|
||||
{
|
||||
@@ -696,7 +697,7 @@ otError Ip6::ProcessReceiveCallback(const Message & aMessage,
|
||||
otError error = OT_ERROR_NONE;
|
||||
Message *messageCopy = NULL;
|
||||
|
||||
VerifyOrExit(aFromNcpHost == false, error = OT_ERROR_DROP);
|
||||
VerifyOrExit(aFromNcpHost == false, error = OT_ERROR_NO_ROUTE);
|
||||
VerifyOrExit(mReceiveIp6DatagramCallback != NULL, error = OT_ERROR_NO_ROUTE);
|
||||
|
||||
if (mIsReceiveIp6FilterEnabled)
|
||||
@@ -716,7 +717,7 @@ otError Ip6::ProcessReceiveCallback(const Message & aMessage,
|
||||
aMessage.Read(aMessage.GetOffset(), sizeof(icmp), &icmp);
|
||||
|
||||
// do not pass ICMP Echo Request messages
|
||||
VerifyOrExit(icmp.GetType() != IcmpHeader::kTypeEchoRequest, error = OT_ERROR_NO_ROUTE);
|
||||
VerifyOrExit(icmp.GetType() != IcmpHeader::kTypeEchoRequest, error = OT_ERROR_DROP);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
+13
-4
@@ -183,11 +183,17 @@ public:
|
||||
/**
|
||||
* This method sends a raw IPv6 datagram with a fully formed IPv6 header.
|
||||
*
|
||||
* The caller transfers ownership of @p aMessage when making this call. OpenThread will free @p aMessage when
|
||||
* processing is complete, including when a value other than `OT_ERROR_NONE` is returned.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aInterfaceId The interface identifier of the network interface that received the message.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully processed the message.
|
||||
* @retval OT_ERROR_DROP Message processing failed and the message should be dropped.
|
||||
* @retval OT_ERROR_NONE Successfully processed the message.
|
||||
* @retval OT_ERROR_DROP Message was well-formed but not fully processed due to packet processing rules.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate necessary message buffers when processing the datagram.
|
||||
* @retval OT_ERROR_NO_ROUTE No route to host.
|
||||
* @retval OT_ERROR_PARSE Encountered a malformed header when processing the message.
|
||||
*
|
||||
*/
|
||||
otError SendRaw(Message &aMessage, int8_t aInterfaceId);
|
||||
@@ -201,8 +207,11 @@ public:
|
||||
* @param[in] aLinkMessageInfo A pointer to link-specific message information.
|
||||
* @param[in] aFromNcpHost TRUE if the message was submitted by the NCP host, FALSE otherwise.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully processed the message.
|
||||
* @retval OT_ERROR_DROP Message processing failed and the message should be dropped.
|
||||
* @retval OT_ERROR_NONE Successfully processed the message.
|
||||
* @retval OT_ERROR_DROP Message was well-formed but not fully processed due to packet processing rules.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate necessary message buffers when processing the datagram.
|
||||
* @retval OT_ERROR_NO_ROUTE No route to host.
|
||||
* @retval OT_ERROR_PARSE Encountered a malformed header when processing the message.
|
||||
*
|
||||
*/
|
||||
otError HandleDatagram(Message & aMessage,
|
||||
|
||||
@@ -300,7 +300,7 @@ otError Mpl::ProcessOption(Message &aMessage, const Address &aAddress, bool aIsO
|
||||
VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(option), &option) >= OptionMpl::kMinLength &&
|
||||
(option.GetSeedIdLength() == OptionMpl::kSeedIdLength0 ||
|
||||
option.GetSeedIdLength() == OptionMpl::kSeedIdLength2),
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
if (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0)
|
||||
{
|
||||
|
||||
@@ -1309,7 +1309,7 @@ void MeshForwarder::HandleFragment(uint8_t * aFrame,
|
||||
int headerLength;
|
||||
|
||||
// Check the fragment header
|
||||
VerifyOrExit(fragmentHeader.Init(aFrame, aFrameLength) == OT_ERROR_NONE, error = OT_ERROR_DROP);
|
||||
VerifyOrExit(fragmentHeader.Init(aFrame, aFrameLength) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
|
||||
aFrame += fragmentHeader.GetHeaderLength();
|
||||
aFrameLength -= fragmentHeader.GetHeaderLength();
|
||||
|
||||
|
||||
@@ -924,7 +924,7 @@ void MeshForwarder::HandleMesh(uint8_t * aFrame,
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
|
||||
// Check the mesh header
|
||||
VerifyOrExit(meshHeader.Init(aFrame, aFrameLength) == OT_ERROR_NONE, error = OT_ERROR_DROP);
|
||||
VerifyOrExit(meshHeader.Init(aFrame, aFrameLength) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
|
||||
|
||||
// Security Check: only process Mesh Header frames that had security enabled.
|
||||
VerifyOrExit(aLinkInfo.mLinkSecurity && meshHeader.IsValid(), error = OT_ERROR_SECURITY);
|
||||
@@ -1212,13 +1212,13 @@ otError MeshForwarder::GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, ui
|
||||
else
|
||||
{
|
||||
// ServiceTLV without ServerTLV? Can't forward packet anywhere.
|
||||
ExitNow(error = OT_ERROR_DROP);
|
||||
ExitNow(error = OT_ERROR_NO_ROUTE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown service, can't forward
|
||||
ExitNow(error = OT_ERROR_DROP);
|
||||
ExitNow(error = OT_ERROR_NO_ROUTE);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -290,7 +290,7 @@ otError NetworkDiagnostic::FillRequestedTlvs(Message & aRequest,
|
||||
|
||||
for (uint32_t i = 0; i < aNetworkDiagnosticTlv.GetLength(); i++)
|
||||
{
|
||||
VerifyOrExit(aRequest.Read(offset, sizeof(type), &type) == sizeof(type), error = OT_ERROR_DROP);
|
||||
VerifyOrExit(aRequest.Read(offset, sizeof(type), &type) == sizeof(type), error = OT_ERROR_PARSE);
|
||||
|
||||
otLogInfoNetDiag("Type %d", type);
|
||||
|
||||
@@ -454,7 +454,7 @@ otError NetworkDiagnostic::FillRequestedTlvs(Message & aRequest,
|
||||
}
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_DROP);
|
||||
ExitNow(error = OT_ERROR_PARSE);
|
||||
}
|
||||
|
||||
offset += sizeof(type);
|
||||
@@ -483,11 +483,11 @@ void NetworkDiagnostic::HandleDiagnosticGetQuery(Coap::Message &aMessage, const
|
||||
|
||||
VerifyOrExit((aMessage.Read(aMessage.GetOffset(), sizeof(NetworkDiagnosticTlv), &networkDiagnosticTlv) ==
|
||||
sizeof(NetworkDiagnosticTlv)),
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList, error = OT_ERROR_DROP);
|
||||
VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList, error = OT_ERROR_PARSE);
|
||||
|
||||
VerifyOrExit((static_cast<TypeListTlv *>(&networkDiagnosticTlv)->IsValid()), error = OT_ERROR_DROP);
|
||||
VerifyOrExit((static_cast<TypeListTlv *>(&networkDiagnosticTlv)->IsValid()), error = OT_ERROR_PARSE);
|
||||
|
||||
// DIAG_GET.qry may be sent as a confirmable message.
|
||||
if (aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE)
|
||||
@@ -556,11 +556,11 @@ void NetworkDiagnostic::HandleDiagnosticGetRequest(Coap::Message &aMessage, cons
|
||||
|
||||
VerifyOrExit((aMessage.Read(aMessage.GetOffset(), sizeof(NetworkDiagnosticTlv), &networkDiagnosticTlv) ==
|
||||
sizeof(NetworkDiagnosticTlv)),
|
||||
error = OT_ERROR_DROP);
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList, error = OT_ERROR_DROP);
|
||||
VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList, error = OT_ERROR_PARSE);
|
||||
|
||||
VerifyOrExit((static_cast<TypeListTlv *>(&networkDiagnosticTlv)->IsValid()), error = OT_ERROR_DROP);
|
||||
VerifyOrExit((static_cast<TypeListTlv *>(&networkDiagnosticTlv)->IsValid()), error = OT_ERROR_PARSE);
|
||||
|
||||
VerifyOrExit((message = Get<Coap::Coap>().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user