1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00
esp8266/cores/esp8266/IPAddress.h
Allman-astyler 98125f8860 Allman now (#6080)
* switch restyle script for CI

* remove confirmation

* restyle with allman
2019-05-13 16:41:34 +02:00

341 lines
7.9 KiB
C++

/*
IPAddress.h - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. 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
*/
#ifndef IPAddress_h
#define IPAddress_h
#include <stdint.h>
#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_ANY IPADDR_ANY
#define IP4_ADDR_ANY4 IPADDR_ANY
#define IPADDR4_INIT(x) { x }
#define CONST /* nothing: lwIP-v1 does not use const */
#define ip4_addr_netcmp ip_addr_netcmp
#define netif_dhcp_data(netif) ((netif)->dhcp)
#else // lwIP-v2+
#define CONST const
#if !LWIP_IPV6
struct ip_addr: ipv4_addr { };
#endif // !LWIP_IPV6
#endif // lwIP-v2+
// 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:
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 reinterpret_cast<uint8_t*>(&v4());
}
const uint8_t* raw_address() const
{
return reinterpret_cast<const uint8_t*>(&v4());
}
void ctor32(uint32_t);
public:
// Constructors
IPAddress();
IPAddress(const IPAddress& from);
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address)
{
ctor32(address);
}
IPAddress(u32_t address)
{
ctor32(address);
}
IPAddress(int address)
{
ctor32(address);
}
IPAddress(const uint8_t *address);
bool fromString(const char *address);
bool fromString(const String &address)
{
return fromString(address.c_str());
}
// 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 isV4() ? v4() : (uint32_t)0;
}
operator uint32_t()
{
return isV4() ? v4() : (uint32_t)0;
}
operator u32_t() const
{
return isV4() ? v4() : (u32_t)0;
}
operator u32_t()
{
return isV4() ? v4() : (u32_t)0;
}
bool isSet() const;
operator bool () const
{
return isSet(); // <-
}
operator bool ()
{
return isSet(); // <- both are needed
}
// 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 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 isV4() && v4() == addr;
}
bool operator==(u32_t addr) const
{
return isV4() && v4() == addr;
}
bool operator!=(uint32_t addr) const
{
return !(isV4() && v4() == addr);
}
bool operator!=(u32_t addr) const
{
return !(isV4() && v4() == addr);
}
bool operator==(const uint8_t* addr) const;
int operator>>(int n) const
{
return isV4() ? v4() >> n : 0;
}
// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const
{
return isV4() ? *(raw_address() + index) : 0;
}
uint8_t& operator[](int index)
{
setV4();
return *(raw_address() + index);
}
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);
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);
friend class EthernetClass;
friend class UDP;
friend class Client;
friend class Server;
friend class DhcpClass;
friend class DNSClient;
/*
lwIP address compatibility
*/
IPAddress(const ipv4_addr& fw_addr)
{
setV4();
v4() = fw_addr.addr;
}
IPAddress(const ipv4_addr* fw_addr)
{
setV4();
v4() = fw_addr->addr;
}
IPAddress& operator=(const ipv4_addr& fw_addr)
{
setV4();
v4() = fw_addr.addr;
return *this;
}
IPAddress& operator=(const ipv4_addr* fw_addr)
{
setV4();
v4() = fw_addr->addr;
return *this;
}
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
IPAddress(const ip_addr_t& lwip_addr)
{
ip_addr_copy(_ip, lwip_addr);
}
IPAddress(const ip_addr_t* lwip_addr)
{
ip_addr_copy(_ip, *lwip_addr);
}
IPAddress& operator=(const ip_addr_t& lwip_addr)
{
ip_addr_copy(_ip, lwip_addr);
return *this;
}
IPAddress& operator=(const ip_addr_t* lwip_addr)
{
ip_addr_copy(_ip, *lwip_addr);
return *this;
}
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 INADDR_ANY;
extern const IPAddress INADDR_NONE;
#endif