mirror of
https://github.com/espressif/openthread.git
synced 2026-09-21 16:37:37 +00:00
[posix] add IPv6 address helper functions in Ip6Utils (#9917)
These helpers are used in `posix/platform/udp.cpp` module.
This commit is contained in:
@@ -33,11 +33,75 @@
|
||||
#include "platform-posix.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openthread/ip6.h>
|
||||
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
namespace Ip6Utils {
|
||||
|
||||
/**
|
||||
* Indicates whether or not the IPv6 address scope is Link-Local.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address to check.
|
||||
*
|
||||
* @retval TRUE If the IPv6 address scope is Link-Local.
|
||||
* @retval FALSE If the IPv6 address scope is not Link-Local.
|
||||
*
|
||||
*/
|
||||
inline bool IsIp6AddressLinkLocal(const otIp6Address &aAddress)
|
||||
{
|
||||
return (aAddress.mFields.m8[0] == 0xfe) && ((aAddress.mFields.m8[1] & 0xc0) == 0x80);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not the IPv6 address is multicast.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address to check.
|
||||
*
|
||||
* @retval TRUE If the IPv6 address scope is multicast.
|
||||
* @retval FALSE If the IPv6 address scope is not multicast.
|
||||
*
|
||||
*/
|
||||
inline bool IsIp6AddressMulticast(const otIp6Address &aAddress) { return (aAddress.mFields.m8[0] == 0xff); }
|
||||
|
||||
/**
|
||||
* Indicates whether or not the IPv6 address is unspecified.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address to check.
|
||||
*
|
||||
* @retval TRUE If the IPv6 address scope is unspecified.
|
||||
* @retval FALSE If the IPv6 address scope is not unspecified.
|
||||
*
|
||||
*/
|
||||
inline bool IsIp6AddressUnspecified(const otIp6Address &aAddress) { return otIp6IsAddressUnspecified(&aAddress); }
|
||||
|
||||
/**
|
||||
* Copies the IPv6 address bytes into a given buffer.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address to copy.
|
||||
* @param[in] aBuffer A pointer to buffer to copy the address to.
|
||||
*
|
||||
*/
|
||||
inline void CopyIp6AddressTo(const otIp6Address &aAddress, void *aBuffer)
|
||||
{
|
||||
memcpy(aBuffer, &aAddress, sizeof(otIp6Address));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and set the the IPv6 address bytes from a given buffer.
|
||||
*
|
||||
* @param[in] aBuffer A pointer to buffer to read from.
|
||||
* @param[out] aAddress A reference to populate with the read IPv6 address.
|
||||
*
|
||||
*/
|
||||
inline void ReadIp6AddressFrom(const void *aBuffer, otIp6Address &aAddress)
|
||||
{
|
||||
memcpy(&aAddress, aBuffer, sizeof(otIp6Address));
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility class converts binary IPv6 address to text format.
|
||||
*
|
||||
|
||||
+13
-17
@@ -69,10 +69,6 @@ void *FdToHandle(int aFd) { return reinterpret_cast<void *>(aFd); }
|
||||
|
||||
int FdFromHandle(void *aHandle) { return static_cast<int>(reinterpret_cast<long>(aHandle)); }
|
||||
|
||||
bool IsLinkLocal(const struct in6_addr &aAddress) { return aAddress.s6_addr[0] == 0xfe && aAddress.s6_addr[1] == 0x80; }
|
||||
|
||||
bool IsMulticast(const otIp6Address &aAddress) { return aAddress.mFields.m8[0] == 0xff; }
|
||||
|
||||
otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, const otMessageInfo &aMessageInfo)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
@@ -93,9 +89,9 @@ otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, const otMes
|
||||
memset(&peerAddr, 0, sizeof(peerAddr));
|
||||
peerAddr.sin6_port = htons(aMessageInfo.mPeerPort);
|
||||
peerAddr.sin6_family = AF_INET6;
|
||||
memcpy(&peerAddr.sin6_addr, &aMessageInfo.mPeerAddr, sizeof(peerAddr.sin6_addr));
|
||||
CopyIp6AddressTo(aMessageInfo.mPeerAddr, &peerAddr.sin6_addr);
|
||||
|
||||
if (IsLinkLocal(peerAddr.sin6_addr) && !aMessageInfo.mIsHostInterface)
|
||||
if (IsIp6AddressLinkLocal(aMessageInfo.mPeerAddr) && !aMessageInfo.mIsHostInterface)
|
||||
{
|
||||
// sin6_scope_id only works for link local destinations
|
||||
peerAddr.sin6_scope_id = gNetifIndex;
|
||||
@@ -127,8 +123,7 @@ otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, const otMes
|
||||
controlLength += CMSG_SPACE(sizeof(int));
|
||||
}
|
||||
|
||||
if (!IsMulticast(aMessageInfo.mSockAddr) &&
|
||||
memcmp(&aMessageInfo.mSockAddr, &in6addr_any, sizeof(aMessageInfo.mSockAddr)))
|
||||
if (!IsIp6AddressMulticast(aMessageInfo.mSockAddr) && !IsIp6AddressUnspecified(aMessageInfo.mSockAddr))
|
||||
{
|
||||
struct in6_pktinfo pktinfo;
|
||||
|
||||
@@ -139,7 +134,7 @@ otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, const otMes
|
||||
|
||||
pktinfo.ipi6_ifindex = aMessageInfo.mIsHostInterface ? 0 : gNetifIndex;
|
||||
|
||||
memcpy(&pktinfo.ipi6_addr, &aMessageInfo.mSockAddr, sizeof(pktinfo.ipi6_addr));
|
||||
CopyIp6AddressTo(aMessageInfo.mSockAddr, &pktinfo.ipi6_addr);
|
||||
memcpy(CMSG_DATA(cmsg), &pktinfo, sizeof(pktinfo));
|
||||
|
||||
controlLength += CMSG_SPACE(sizeof(pktinfo));
|
||||
@@ -206,13 +201,13 @@ otError receivePacket(int aFd, uint8_t *aPayload, uint16_t &aLength, otMessageIn
|
||||
memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo));
|
||||
|
||||
aMessageInfo.mIsHostInterface = (pktinfo.ipi6_ifindex != gNetifIndex);
|
||||
memcpy(&aMessageInfo.mSockAddr, &pktinfo.ipi6_addr, sizeof(aMessageInfo.mSockAddr));
|
||||
ReadIp6AddressFrom(&pktinfo.ipi6_addr, aMessageInfo.mSockAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aMessageInfo.mPeerPort = ntohs(peerAddr.sin6_port);
|
||||
memcpy(&aMessageInfo.mPeerAddr, &peerAddr.sin6_addr, sizeof(aMessageInfo.mPeerAddr));
|
||||
ReadIp6AddressFrom(&peerAddr.sin6_addr, aMessageInfo.mPeerAddr);
|
||||
|
||||
exit:
|
||||
return rval > 0 ? OT_ERROR_NONE : OT_ERROR_FAILED;
|
||||
@@ -270,7 +265,8 @@ otError otPlatUdpBind(otUdpSocket *aUdpSocket)
|
||||
memset(&sin6, 0, sizeof(struct sockaddr_in6));
|
||||
sin6.sin6_port = htons(aUdpSocket->mSockName.mPort);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
memcpy(&sin6.sin6_addr, &aUdpSocket->mSockName.mAddress, sizeof(sin6.sin6_addr));
|
||||
CopyIp6AddressTo(aUdpSocket->mSockName.mAddress, &sin6.sin6_addr);
|
||||
|
||||
VerifyOrExit(0 == bind(fd, reinterpret_cast<struct sockaddr *>(&sin6), sizeof(sin6)), error = OT_ERROR_FAILED);
|
||||
}
|
||||
|
||||
@@ -358,8 +354,7 @@ otError otPlatUdpConnect(otUdpSocket *aUdpSocket)
|
||||
otError error = OT_ERROR_NONE;
|
||||
struct sockaddr_in6 sin6;
|
||||
int fd;
|
||||
bool isDisconnect = memcmp(&aUdpSocket->mPeerName.mAddress, &in6addr_any, sizeof(in6addr_any)) == 0 &&
|
||||
aUdpSocket->mPeerName.mPort == 0;
|
||||
bool isDisconnect = IsIp6AddressUnspecified(aUdpSocket->mPeerName.mAddress) && (aUdpSocket->mPeerName.mPort == 0);
|
||||
|
||||
VerifyOrExit(aUdpSocket->mHandle != nullptr, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
@@ -367,10 +362,11 @@ otError otPlatUdpConnect(otUdpSocket *aUdpSocket)
|
||||
|
||||
memset(&sin6, 0, sizeof(struct sockaddr_in6));
|
||||
sin6.sin6_port = htons(aUdpSocket->mPeerName.mPort);
|
||||
|
||||
if (!isDisconnect)
|
||||
{
|
||||
sin6.sin6_family = AF_INET6;
|
||||
memcpy(&sin6.sin6_addr, &aUdpSocket->mPeerName.mAddress, sizeof(sin6.sin6_addr));
|
||||
CopyIp6AddressTo(aUdpSocket->mPeerName.mAddress, &sin6.sin6_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -468,7 +464,7 @@ otError otPlatUdpJoinMulticastGroup(otUdpSocket *aUdpSocket,
|
||||
VerifyOrExit(aUdpSocket->mHandle != nullptr, error = OT_ERROR_INVALID_ARGS);
|
||||
fd = FdFromHandle(aUdpSocket->mHandle);
|
||||
|
||||
memcpy(&mreq.ipv6mr_multiaddr, aAddress->mFields.m8, sizeof(mreq.ipv6mr_multiaddr));
|
||||
CopyIp6AddressTo(*aAddress, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
switch (aNetifIdentifier)
|
||||
{
|
||||
@@ -508,7 +504,7 @@ otError otPlatUdpLeaveMulticastGroup(otUdpSocket *aUdpSocket,
|
||||
VerifyOrExit(aUdpSocket->mHandle != nullptr, error = OT_ERROR_INVALID_ARGS);
|
||||
fd = FdFromHandle(aUdpSocket->mHandle);
|
||||
|
||||
memcpy(&mreq.ipv6mr_multiaddr, aAddress->mFields.m8, sizeof(mreq.ipv6mr_multiaddr));
|
||||
CopyIp6AddressTo(*aAddress, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
switch (aNetifIdentifier)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
#define OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifndef OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE 1
|
||||
#endif
|
||||
|
||||
#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
|
||||
|
||||
#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1
|
||||
|
||||
Reference in New Issue
Block a user