mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-30 16:24:09 +03:00
IPv6 on esp8266-nonos-sdk and arduino (#5136)
This commit is contained in:
168
cores/esp8266/AddrList.h
Normal file
168
cores/esp8266/AddrList.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
AddrList.h - cycle through lwIP netif's ip addresses like a c++ list
|
||||
Copyright (c) 2018 david gauchard. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
This class allows to explore all configured IP addresses
|
||||
in lwIP netifs, with that kind of c++ loop:
|
||||
|
||||
for (auto a: ifList)
|
||||
out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n",
|
||||
a->iface().c_str(),
|
||||
a->number(),
|
||||
a->addr().isLegacy(),
|
||||
a->addr().isV4(),
|
||||
a->addr().isLocal(),
|
||||
a->hostname().c_str(),
|
||||
a->addr().toString().c_str());
|
||||
|
||||
This loop:
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED()) {
|
||||
Serial.print('.');
|
||||
delay(500);
|
||||
}
|
||||
|
||||
can be replaced by:
|
||||
|
||||
for (bool configured = false; !configured; ) {
|
||||
for (auto iface: ifList)
|
||||
if ((configured = !iface->addr().isLocal())
|
||||
break;
|
||||
Serial.print('.');
|
||||
delay(500);
|
||||
}
|
||||
|
||||
waiting for an IPv6 global address:
|
||||
|
||||
for (bool configured = false; !configured; ) {
|
||||
for (auto iface: ifList)
|
||||
if ((configured = ( !iface->addr()->isV4()
|
||||
&& !iface->addr().isLocal())))
|
||||
break;
|
||||
Serial.print('.');
|
||||
delay(500);
|
||||
}
|
||||
|
||||
waiting for an IPv6 global address, on a specific interface:
|
||||
|
||||
for (bool configured = false; !configured; ) {
|
||||
for (auto iface: ifList)
|
||||
if ((configured = ( !iface->addr()->isV4()
|
||||
&& !iface->addr().isLocal()
|
||||
&& iface->number() == STATION_IF)))
|
||||
break;
|
||||
Serial.print('.');
|
||||
delay(500);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifndef __ADDRLIST_H
|
||||
#define __ADDRLIST_H
|
||||
|
||||
#include <IPAddress.h>
|
||||
#include <lwip/netif.h>
|
||||
|
||||
#if LWIP_IPV6
|
||||
#define IF_NUM_ADDRESSES (1 + LWIP_IPV6_NUM_ADDRESSES)
|
||||
#else
|
||||
#define IF_NUM_ADDRESSES (1)
|
||||
#endif
|
||||
|
||||
|
||||
class AddrListClass {
|
||||
|
||||
// no member in this class
|
||||
// lwIP's global 'struct netif* netif_list' is used
|
||||
// designed to be used with 'for (auto x: ifList)'
|
||||
|
||||
public:
|
||||
|
||||
class const_iterator {
|
||||
|
||||
public:
|
||||
|
||||
// iterator operations:
|
||||
|
||||
const_iterator (bool begin = true): _netif(begin? netif_list: nullptr), _num(-1) { ++*this; }
|
||||
const_iterator (const const_iterator& o): _netif(o._netif), _num(o._num) { }
|
||||
const_iterator& operator= (const const_iterator& o) { _netif = o._netif; _num = o._num; return *this; }
|
||||
|
||||
bool operator!= (const const_iterator& o) { return !equal(o); }
|
||||
bool operator== (const const_iterator& o) { return equal(o); }
|
||||
|
||||
const_iterator operator++(int) {
|
||||
const_iterator ret = *this;
|
||||
++(*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const_iterator& operator++() {
|
||||
while (_netif) {
|
||||
if (++_num == IF_NUM_ADDRESSES) {
|
||||
_num = -1;
|
||||
_netif = _netif->next;
|
||||
continue;
|
||||
}
|
||||
if (!ip_addr_isany(_ip_from_netif_num()))
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// (*iterator) emulation:
|
||||
|
||||
const const_iterator& operator* () const { return *this; }
|
||||
const const_iterator* operator-> () const { return this; }
|
||||
|
||||
bool isLegacy() const { return _num == 0; }
|
||||
bool isLocal() const { return addr().isLocal(); }
|
||||
IPAddress addr () const { return _ip_from_netif_num(); }
|
||||
IPAddress netmask () const { return _netif->netmask; }
|
||||
IPAddress gw () const { return _netif->gw; }
|
||||
String iface () const { return String(_netif->name[0]) + _netif->name[1]; }
|
||||
const char* hostname () const { return _netif->hostname?: emptyString.c_str(); }
|
||||
const char* mac () const { return (const char*)_netif->hwaddr; }
|
||||
int number () const { return _netif->num; }
|
||||
|
||||
protected:
|
||||
|
||||
bool equal (const const_iterator& o) {
|
||||
return _netif == o._netif
|
||||
&& (!_netif || _num == o._num);
|
||||
}
|
||||
|
||||
const ip_addr_t* _ip_from_netif_num () const {
|
||||
#if LWIP_IPV6
|
||||
return _num? &_netif->ip6_addr[_num - 1]: &_netif->ip_addr;
|
||||
#else
|
||||
return &_netif->ip_addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
netif* _netif;
|
||||
int _num; // address index (0 is legacy, _num-1 is ip6_addr[]'s index)
|
||||
};
|
||||
|
||||
const const_iterator begin () const { return const_iterator(true); }
|
||||
const const_iterator end () const { return const_iterator(false); }
|
||||
};
|
||||
|
||||
extern AddrListClass addrList;
|
||||
|
||||
#endif // __ADDRLIST_H
|
@ -26,7 +26,7 @@
|
||||
class Client: public Stream {
|
||||
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) =0;
|
||||
virtual int connect(CONST IPAddress& ip, uint16_t port) =0;
|
||||
virtual int connect(const char *host, uint16_t port) =0;
|
||||
virtual size_t write(uint8_t) =0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) =0;
|
||||
@ -39,7 +39,7 @@ class Client: public Stream {
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) {
|
||||
CONST uint8_t* rawIPAddress(CONST IPAddress& addr) {
|
||||
return addr.raw_address();
|
||||
}
|
||||
;
|
||||
|
@ -29,9 +29,6 @@
|
||||
#define STR(x) STRHELPER(x) // stringifier
|
||||
|
||||
static const char arduino_esp8266_git_ver [] PROGMEM = STR(ARDUINO_ESP8266_GIT_DESC);
|
||||
#if LWIP_VERSION_MAJOR != 1
|
||||
static const char lwip2_version [] PROGMEM = "/lwIP:" STR(LWIP_VERSION_MAJOR) "." STR(LWIP_VERSION_MINOR) "." STR(LWIP_VERSION_REVISION);
|
||||
#endif
|
||||
static const char bearssl_version [] PROGMEM = "/BearSSL:" STR(BEARSSL_GIT);
|
||||
|
||||
String EspClass::getFullVersion()
|
||||
@ -40,17 +37,18 @@ String EspClass::getFullVersion()
|
||||
+ F("/Core:") + FPSTR(arduino_esp8266_git_ver)
|
||||
#if LWIP_VERSION_MAJOR == 1
|
||||
+ F("/lwIP:") + String(LWIP_VERSION_MAJOR) + "." + String(LWIP_VERSION_MINOR) + "." + String(LWIP_VERSION_REVISION)
|
||||
#else
|
||||
+ FPSTR(lwip2_version)
|
||||
#endif
|
||||
#if LWIP_VERSION_IS_DEVELOPMENT
|
||||
+ F("-dev")
|
||||
#endif
|
||||
#if LWIP_VERSION_IS_RC
|
||||
+ F("rc") + String(LWIP_VERSION_RC)
|
||||
#endif
|
||||
#ifdef LWIP_HASH_STR
|
||||
+ "(" + F(LWIP_HASH_STR) + ")"
|
||||
#else // LWIP_VERSION_MAJOR != 1
|
||||
+ F("/lwIP:")
|
||||
#if LWIP_IPV6
|
||||
+ F("IPv6+")
|
||||
#endif
|
||||
+ F(LWIP_HASH_STR)
|
||||
#endif
|
||||
+ FPSTR(bearssl_version)
|
||||
;
|
||||
|
@ -20,28 +20,47 @@
|
||||
#include <Arduino.h>
|
||||
#include <IPAddress.h>
|
||||
#include <Print.h>
|
||||
#include <StreamString.h>
|
||||
|
||||
IPAddress::IPAddress() {
|
||||
_address.dword = 0;
|
||||
_ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address
|
||||
}
|
||||
|
||||
bool IPAddress::isSet () const {
|
||||
return !ip_addr_isany(&_ip);
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) {
|
||||
_address.bytes[0] = first_octet;
|
||||
_address.bytes[1] = second_octet;
|
||||
_address.bytes[2] = third_octet;
|
||||
_address.bytes[3] = fourth_octet;
|
||||
setV4();
|
||||
(*this)[0] = first_octet;
|
||||
(*this)[1] = second_octet;
|
||||
(*this)[2] = third_octet;
|
||||
(*this)[3] = fourth_octet;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint32_t address) {
|
||||
_address.dword = address;
|
||||
setV4();
|
||||
v4() = address;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(const uint8_t *address) {
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
setV4();
|
||||
v4() = *reinterpret_cast<const uint32_t*>(address);
|
||||
}
|
||||
|
||||
bool IPAddress::fromString(const char *address) {
|
||||
// TODO: add support for "a", "a.b", "a.b.c" formats
|
||||
if (!fromString4(address)) {
|
||||
#if LWIP_IPV6
|
||||
return fromString6(address);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPAddress::fromString4(const char *address) {
|
||||
// TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats
|
||||
|
||||
uint16_t acc = 0; // Accumulator
|
||||
uint8_t dots = 0;
|
||||
@ -63,7 +82,7 @@ bool IPAddress::fromString(const char *address) {
|
||||
// Too much dots (there must be 3 dots)
|
||||
return false;
|
||||
}
|
||||
_address.bytes[dots++] = acc;
|
||||
(*this)[dots++] = acc;
|
||||
acc = 0;
|
||||
}
|
||||
else
|
||||
@ -77,39 +96,72 @@ bool IPAddress::fromString(const char *address) {
|
||||
// Too few dots (there must be 3 dots)
|
||||
return false;
|
||||
}
|
||||
_address.bytes[3] = acc;
|
||||
(*this)[3] = acc;
|
||||
|
||||
setV4();
|
||||
return true;
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(const uint8_t *address) {
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
setV4();
|
||||
v4() = *reinterpret_cast<const uint32_t*>(address);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(uint32_t address) {
|
||||
_address.dword = address;
|
||||
setV4();
|
||||
v4() = address;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IPAddress::operator==(const uint8_t* addr) const {
|
||||
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
|
||||
return isV4() && v4() == *reinterpret_cast<const uint32_t*>(addr);
|
||||
}
|
||||
|
||||
size_t IPAddress::printTo(Print& p) const {
|
||||
size_t n = 0;
|
||||
for(int i = 0; i < 3; i++) {
|
||||
n += p.print(_address.bytes[i], DEC);
|
||||
n += p.print('.');
|
||||
|
||||
if (!isSet())
|
||||
return p.print(F("(IP unset)"));
|
||||
|
||||
#if LWIP_IPV6
|
||||
if (isV6()) {
|
||||
int count0 = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint16_t bit = PP_NTOHS(raw6()[i]);
|
||||
if (bit || count0 < 0) {
|
||||
n += p.printf("%x", bit);
|
||||
if (count0 > 0)
|
||||
// no more hiding 0
|
||||
count0 = -8;
|
||||
} else
|
||||
count0++;
|
||||
if ((i != 7 && count0 < 2) || count0 == 7)
|
||||
n += p.print(':');
|
||||
}
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
n += p.print((*this)[i], DEC);
|
||||
if (i != 3)
|
||||
n += p.print('.');
|
||||
}
|
||||
n += p.print(_address.bytes[3], DEC);
|
||||
return n;
|
||||
}
|
||||
|
||||
String IPAddress::toString() const
|
||||
{
|
||||
char szRet[16];
|
||||
sprintf(szRet,"%u.%u.%u.%u", _address.bytes[0], _address.bytes[1], _address.bytes[2], _address.bytes[3]);
|
||||
return String(szRet);
|
||||
StreamString sstr;
|
||||
#if LWIP_IPV6
|
||||
if (isV6())
|
||||
sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm
|
||||
else
|
||||
#endif
|
||||
sstr.reserve(16); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)'
|
||||
printTo(sstr);
|
||||
return sstr;
|
||||
}
|
||||
|
||||
bool IPAddress::isValid(const String& arg) {
|
||||
@ -120,4 +172,63 @@ bool IPAddress::isValid(const char* arg) {
|
||||
return IPAddress().fromString(arg);
|
||||
}
|
||||
|
||||
const IPAddress INADDR_NONE(0, 0, 0, 0);
|
||||
CONST IPAddress IPNoAddress; // generic "0.0.0.0" for v4 & v6
|
||||
|
||||
/**************************************/
|
||||
|
||||
#if LWIP_IPV6
|
||||
|
||||
bool IPAddress::fromString6(const char *address) {
|
||||
// TODO: test test test
|
||||
|
||||
uint32_t acc = 0; // Accumulator
|
||||
int dots = 0, doubledots = -1;
|
||||
|
||||
while (*address)
|
||||
{
|
||||
char c = tolower(*address++);
|
||||
if (isalnum(c)) {
|
||||
if (c >= 'a')
|
||||
c -= 'a' - '0' - 10;
|
||||
acc = acc * 16 + (c - '0');
|
||||
if (acc > 0xffff)
|
||||
// Value out of range
|
||||
return false;
|
||||
}
|
||||
else if (c == ':') {
|
||||
if (*address == ':') {
|
||||
if (doubledots >= 0)
|
||||
// :: allowed once
|
||||
return false;
|
||||
// remember location
|
||||
doubledots = dots + !!acc;
|
||||
address++;
|
||||
}
|
||||
if (dots == 7)
|
||||
// too many separators
|
||||
return false;
|
||||
raw6()[dots++] = PP_HTONS(acc);
|
||||
acc = 0;
|
||||
}
|
||||
else
|
||||
// Invalid char
|
||||
return false;
|
||||
}
|
||||
|
||||
if (doubledots == -1 && dots != 7)
|
||||
// Too few separators
|
||||
return false;
|
||||
raw6()[dots++] = PP_HTONS(acc);
|
||||
|
||||
if (doubledots != -1) {
|
||||
for (int i = dots - doubledots - 1; i >= 0; i--)
|
||||
raw6()[8 - dots + doubledots + i] = raw6()[doubledots + i];
|
||||
for (int i = doubledots; i < 8 - dots + doubledots; i++)
|
||||
raw6()[i] = 0;
|
||||
}
|
||||
|
||||
setV6();
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -24,21 +24,44 @@
|
||||
#include <WString.h>
|
||||
#include <Printable.h>
|
||||
|
||||
#include <lwip/init.h>
|
||||
#include <lwip/ip_addr.h>
|
||||
|
||||
#if LWIP_VERSION_MAJOR == 1
|
||||
// compatibility macros to make lwIP-v1 compiling lwIP-v2 API
|
||||
#define LWIP_IPV6_NUM_ADDRESSES 0
|
||||
#define ip_2_ip4(x) (x)
|
||||
#define ipv4_addr ip_addr
|
||||
#define IP_IS_V4_VAL(x) (1)
|
||||
#define IP_SET_TYPE_VAL(x,y) do { (void)0; } while (0)
|
||||
#define IP_ANY_TYPE (&ip_addr_any)
|
||||
#define IP4_ADDR_ANY4 IPADDR_ANY
|
||||
#define IPADDR4_INIT(x) { x }
|
||||
#define CONST /* nothing: lwIP-v1 does not use const */
|
||||
#else
|
||||
#define CONST const
|
||||
#endif
|
||||
|
||||
// A class to make it easier to handle and pass around IP addresses
|
||||
// IPv6 update:
|
||||
// IPAddress is now a decorator class for lwIP's ip_addr_t
|
||||
// fully backward compatible with legacy IPv4-only Arduino's
|
||||
// with unchanged footprint when IPv6 is disabled
|
||||
|
||||
class IPAddress: public Printable {
|
||||
private:
|
||||
union {
|
||||
uint8_t bytes[4]; // IPv4 address
|
||||
uint32_t dword;
|
||||
} _address;
|
||||
|
||||
ip_addr_t _ip;
|
||||
|
||||
// Access the raw byte array containing the address. Because this returns a pointer
|
||||
// to the internal structure rather than a copy of the address this function should only
|
||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
||||
// stored.
|
||||
uint8_t* raw_address() {
|
||||
return _address.bytes;
|
||||
return reinterpret_cast<uint8_t*>(&v4());
|
||||
}
|
||||
const uint8_t* raw_address() const {
|
||||
return reinterpret_cast<const uint8_t*>(&v4());
|
||||
}
|
||||
|
||||
public:
|
||||
@ -54,22 +77,37 @@ class IPAddress: public Printable {
|
||||
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
|
||||
// to a four-byte uint8_t array is expected
|
||||
operator uint32_t() const {
|
||||
return _address.dword;
|
||||
return isV4()? v4(): (uint32_t)0;
|
||||
}
|
||||
|
||||
// the above uint32_t() cast can be ambiguous
|
||||
// if gcc complains, use instead isSet() or v4() according to what's relevant
|
||||
bool isSet () const;
|
||||
// generic IPv4 wrapper to uint32-view like arduino loves to see it
|
||||
const u32_t& v4() const { return ip_2_ip4(&_ip)->addr; } // for raw_address(const)
|
||||
u32_t& v4() { return ip_2_ip4(&_ip)->addr; }
|
||||
|
||||
bool operator==(const IPAddress& addr) const {
|
||||
return _address.dword == addr._address.dword;
|
||||
return ip_addr_cmp(&_ip, &addr._ip);
|
||||
}
|
||||
bool operator!=(const IPAddress& addr) const {
|
||||
return !ip_addr_cmp(&_ip, &addr._ip);
|
||||
}
|
||||
bool operator==(uint32_t addr) const {
|
||||
return _address.dword == addr;
|
||||
return isV4() && v4() == addr;
|
||||
}
|
||||
bool operator!=(uint32_t addr) const {
|
||||
return !(isV4() && v4() == addr);
|
||||
}
|
||||
bool operator==(const uint8_t* addr) const;
|
||||
|
||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
||||
uint8_t operator[](int index) const {
|
||||
return _address.bytes[index];
|
||||
return isV4()? *(raw_address() + index): 0;
|
||||
}
|
||||
uint8_t& operator[](int index) {
|
||||
return _address.bytes[index];
|
||||
setV4();
|
||||
return *(raw_address() + index);
|
||||
}
|
||||
|
||||
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
|
||||
@ -79,13 +117,13 @@ class IPAddress: public Printable {
|
||||
virtual size_t printTo(Print& p) const;
|
||||
String toString() const;
|
||||
|
||||
/*
|
||||
check if input string(arg) is a valid IPV4 address or not.
|
||||
return true on valid.
|
||||
return false on invalid.
|
||||
*/
|
||||
static bool isValid(const String& arg);
|
||||
static bool isValid(const char* arg);
|
||||
/*
|
||||
check if input string(arg) is a valid IPV4 address or not.
|
||||
return true on valid.
|
||||
return false on invalid.
|
||||
*/
|
||||
static bool isValid(const String& arg);
|
||||
static bool isValid(const char* arg);
|
||||
|
||||
friend class EthernetClass;
|
||||
friend class UDP;
|
||||
@ -93,8 +131,68 @@ class IPAddress: public Printable {
|
||||
friend class Server;
|
||||
friend class DhcpClass;
|
||||
friend class DNSClient;
|
||||
};
|
||||
|
||||
extern const IPAddress INADDR_NONE;
|
||||
/*
|
||||
lwIP address compatibility
|
||||
*/
|
||||
IPAddress(const ipv4_addr* fw_addr) { setV4(); v4() = fw_addr->addr; }
|
||||
IPAddress(const ip_addr_t& lwip_addr) { _ip = lwip_addr; }
|
||||
|
||||
#if LWIP_VERSION_MAJOR != 1
|
||||
IPAddress(ipv4_addr fw_addr) { setV4(); v4() = fw_addr.addr; }
|
||||
IPAddress(const ip_addr_t* lwip_addr) { _ip = *lwip_addr; }
|
||||
#endif
|
||||
|
||||
operator ip_addr_t () const { return _ip; }
|
||||
operator const ip_addr_t*() const { return &_ip; }
|
||||
operator ip_addr_t*() { return &_ip; }
|
||||
|
||||
bool isV4() const { return IP_IS_V4_VAL(_ip); }
|
||||
void setV4() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V4); }
|
||||
|
||||
bool isLocal () const { return ip_addr_islinklocal(&_ip); }
|
||||
|
||||
#if LWIP_IPV6
|
||||
|
||||
uint16_t* raw6()
|
||||
{
|
||||
setV6();
|
||||
return reinterpret_cast<uint16_t*>(ip_2_ip6(&_ip));
|
||||
}
|
||||
|
||||
const uint16_t* raw6() const
|
||||
{
|
||||
return isV6()? reinterpret_cast<const uint16_t*>(ip_2_ip6(&_ip)): nullptr;
|
||||
}
|
||||
|
||||
// when not IPv6, ip_addr_t == ip4_addr_t so this one would be ambiguous
|
||||
// required otherwise
|
||||
operator const ip4_addr_t*() const { return isV4()? ip_2_ip4(&_ip): nullptr; }
|
||||
|
||||
bool isV6() const { return IP_IS_V6_VAL(_ip); }
|
||||
void setV6() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V6); }
|
||||
|
||||
protected:
|
||||
bool fromString6(const char *address);
|
||||
|
||||
#else
|
||||
|
||||
// allow portable code when IPv6 is not enabled
|
||||
|
||||
uint16_t* raw6() { return nullptr; }
|
||||
const uint16_t* raw6() const { return nullptr; }
|
||||
bool isV6() const { return false; }
|
||||
void setV6() { }
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool fromString4(const char *address);
|
||||
|
||||
};
|
||||
|
||||
extern CONST IPAddress IPNoAddress;
|
||||
|
||||
#include <AddrList.h>
|
||||
|
||||
#endif
|
||||
|
@ -78,11 +78,11 @@ class UDP: public Stream {
|
||||
virtual void flush() =0; // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() =0;
|
||||
virtual IPAddress remoteIP() const =0;
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() =0;
|
||||
virtual uint16_t remotePort() const =0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) {
|
||||
CONST uint8_t* rawIPAddress(CONST IPAddress& addr) {
|
||||
return addr.raw_address();
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user