Added IPv6 support and implemented new wifi stack ip utils

This commit is contained in:
2021-06-18 02:40:14 +02:00
parent f05c62238f
commit 1db1655f18
2 changed files with 65 additions and 80 deletions

View File

@ -78,26 +78,14 @@ void _udp_recv(void *arg, udp_pcb *pcb, pbuf *pb, const ip_addr_t *addr, uint16_
_this->_udp_task_post(pcb, pb, addr, port, ip_current_input_netif());
}
UdpPacketWrapper makeUdpPacketWrapper(pbufUniquePtr &&_pb, const ip_addr_t *raddr, uint16_t rport, struct netif *ntif)
UdpPacketWrapper makeUdpPacketWrapper(pbufUniquePtr &&_pb, const ip_addr_t *raddr, uint16_t rport, struct netif *_ntif)
{
assert(_pb);
tcpip_adapter_if_t _if{TCPIP_ADAPTER_IF_MAX};
std::string_view _data;
ip_addr_t _localIp;
uint16_t _localPort;
ip_addr_t _remoteIp;
uint16_t _remotePort;
wifi_stack::mac_t _remoteMac;
auto payload = reinterpret_cast<const char *>(_pb->payload);
_data = std::string_view{payload, _pb->len};
//memcpy(&_remoteIp, raddr, sizeof(ip_addr_t));
_remoteIp.type = raddr->type;
_localIp.type = _remoteIp.type;
const eth_hdr *eth{};
uint16_t _localPort;
uint16_t _remotePort;
{
const udp_hdr *udphdr = reinterpret_cast<const udp_hdr*>(payload - UDP_HLEN);
@ -105,42 +93,67 @@ UdpPacketWrapper makeUdpPacketWrapper(pbufUniquePtr &&_pb, const ip_addr_t *radd
_remotePort = ntohs(udphdr->src);
}
if (_remoteIp.type == IPADDR_TYPE_V4)
const eth_hdr *ethHdr{};
//memcpy(&_remoteIp, raddr, sizeof(ip_addr_t));
ip_addr_t _localAddr { .type = raddr->type };
ip_addr_t _remoteAddr { .type = raddr->type };
switch (_remoteAddr.type)
{
eth = reinterpret_cast<const eth_hdr *>(payload - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR);
case IPADDR_TYPE_V4:
{
ethHdr = reinterpret_cast<const eth_hdr *>(payload - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR);
const ip_hdr *iphdr = reinterpret_cast<const ip_hdr *>(payload - UDP_HLEN - IP_HLEN);
_localIp.u_addr.ip4.addr = iphdr->dest.addr;
_remoteIp.u_addr.ip4.addr = iphdr->src.addr;
_localAddr.u_addr.ip4.addr = iphdr->dest.addr;
_remoteAddr.u_addr.ip4.addr = iphdr->src.addr;
break;
}
else
case IPADDR_TYPE_V6:
{
eth = reinterpret_cast<const eth_hdr *>(payload - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR);
ethHdr = reinterpret_cast<const eth_hdr *>(payload - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR);
const ip6_hdr *ip6hdr = reinterpret_cast<const ip6_hdr *>(payload - UDP_HLEN - IP6_HLEN);
std::memcpy(&_localIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16);
std::memcpy(&_remoteIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->src.addr, 16);
std::copy(std::cbegin(ip6hdr->dest.addr), std::cend(ip6hdr->dest.addr), std::begin(_localAddr.u_addr.ip6.addr));
std::copy(std::cbegin(ip6hdr->src.addr), std::cend(ip6hdr->src.addr), std::begin(_remoteAddr.u_addr.ip6.addr));
break;
}
default:
ESP_LOGW(TAG, "unknown ip type %i", _remoteAddr.type);
}
_remoteMac = wifi_stack::mac_t{eth->src.addr};
for (int i = 0; i < TCPIP_ADAPTER_IF_MAX; i++)
{
void *nif{};
tcpip_adapter_get_netif(tcpip_adapter_if_t(i), &nif);
const struct netif *netif = reinterpret_cast<const struct netif *>(nif);
if (netif && netif == ntif)
{
_if = tcpip_adapter_if_t(i);
break;
}
}
return UdpPacketWrapper{std::move(_pb), _if, _data, _localIp, _localPort, _remoteIp, _remotePort, _remoteMac};
std::string_view _data{payload, _pb->len};
return UdpPacketWrapper{
._pb = std::move(_pb),
._data = _data,
._ntif = _ntif,
._local = { .addr = _localAddr, .port = _localPort },
._remote = { .addr = _remoteAddr, .port = _remotePort },
._remoteMac = ethHdr ? wifi_stack::mac_t{ethHdr->src.addr} : wifi_stack::mac_t{}
};
}
} // namespace
tcpip_adapter_if_t UdpPacketWrapper::tcpIpAdapter() const
{
for (int i = 0; i < TCPIP_ADAPTER_IF_MAX; i++)
{
tcpip_adapter_if_t tcpip_if = tcpip_adapter_if_t(i);
struct netif *nif{};
if (const auto result = tcpip_adapter_get_netif(tcpip_if, &nif); result != ESP_OK)
{
ESP_LOGW(TAG, "tcpip_adapter_get_netif() failed with %s", esp_err_to_name(result));
continue;
}
if (nif && nif == _ntif)
return tcpip_if;
}
return TCPIP_ADAPTER_IF_MAX;
}
bool AsyncUdpListener::listen(const ip_addr_t *addr, uint16_t port)
{
if (!_udp_queue.constructed())

View File

@ -33,59 +33,31 @@ struct UdpPacketWrapper
UdpPacketWrapper &operator=(const UdpPacketWrapper &other) = delete;
auto data() const { return _data; }
bool isBroadcast() const
{
if (_localIp.type == IPADDR_TYPE_V6)
return false;
uint32_t ip = _localIp.u_addr.ip4.addr;
return ip == 0xFFFFFFFF || ip == 0 || (ip & 0xFF000000) == 0xFF000000;
}
bool isMulticast() const { return ip_addr_ismulticast(&(_localIp)); }
bool isIPv6() const { return _localIp.type == IPADDR_TYPE_V6; }
tcpip_adapter_if_t interface() const { return _if; }
tcpip_adapter_if_t tcpIpAdapter() const;
std::optional<u32_t> localIP() const
{
if (_localIp.type != IPADDR_TYPE_V4)
return std::nullopt;
return _localIp.u_addr.ip4.addr;
}
struct netif *ntif() const { return _ntif; }
std::optional<std::array<u32_t, 4>> localIPv6() const
{
if (_localIp.type != IPADDR_TYPE_V6)
return std::nullopt;
return *reinterpret_cast<const std::array<u32_t, 4>*>(_localIp.u_addr.ip6.addr);
}
bool isBroadcast() const { return ip_addr_isbroadcast(&(_local.addr), _ntif); }
bool isMulticast() const { return ip_addr_ismulticast(&(_local.addr)); }
uint16_t localPort() const { return _localPort; }
ip_addr_t localAddr() const { return _local.addr; }
std::optional<u32_t> remoteIP() const
{
if (_remoteIp.type != IPADDR_TYPE_V4)
return std::nullopt;
return _remoteIp.u_addr.ip4.addr;
}
uint16_t localPort() const { return _local.port; }
std::optional<std::array<u32_t, 4>> remoteIPv6() const
{
if (_remoteIp.type != IPADDR_TYPE_V6)
return std::nullopt;
return *reinterpret_cast<const std::array<u32_t, 4>*>(_remoteIp.u_addr.ip6.addr);
}
ip_addr_t remoteAddr() const { return _remote.addr; }
uint16_t remotePort() const { return _remotePort; }
uint16_t remotePort() const { return _remote.port; }
wifi_stack::mac_t remoteMac() const { return _remoteMac; }
pbufUniquePtr _pb;
tcpip_adapter_if_t _if{TCPIP_ADAPTER_IF_MAX};
std::string_view _data;
ip_addr_t _localIp;
uint16_t _localPort;
ip_addr_t _remoteIp;
uint16_t _remotePort;
struct netif *_ntif;
struct {
ip_addr_t addr;
uint16_t port;
} _local, _remote;
wifi_stack::mac_t _remoteMac;
};