From 1db1655f18d690d3f292f6584cf07c0d74259b1f Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Fri, 18 Jun 2021 02:40:14 +0200 Subject: [PATCH] Added IPv6 support and implemented new wifi stack ip utils --- src/asyncudplistener.cpp | 91 +++++++++++++++++++++++----------------- src/asyncudplistener.h | 54 ++++++------------------ 2 files changed, 65 insertions(+), 80 deletions(-) diff --git a/src/asyncudplistener.cpp b/src/asyncudplistener.cpp index 538f2ff..3a70c5f 100644 --- a/src/asyncudplistener.cpp +++ b/src/asyncudplistener.cpp @@ -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(_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(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(payload - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR); + case IPADDR_TYPE_V4: + { + ethHdr = reinterpret_cast(payload - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR); const ip_hdr *iphdr = reinterpret_cast(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(payload - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR); + ethHdr = reinterpret_cast(payload - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR); const ip6_hdr *ip6hdr = reinterpret_cast(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(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()) diff --git a/src/asyncudplistener.h b/src/asyncudplistener.h index 43afecf..139f832 100644 --- a/src/asyncudplistener.h +++ b/src/asyncudplistener.h @@ -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 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> localIPv6() const - { - if (_localIp.type != IPADDR_TYPE_V6) - return std::nullopt; - return *reinterpret_cast*>(_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 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> remoteIPv6() const - { - if (_remoteIp.type != IPADDR_TYPE_V6) - return std::nullopt; - return *reinterpret_cast*>(_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; };