2020#ifndef IPAddress_h
2121#define IPAddress_h
2222
23- #include < stdint.h>
2423#include < WString.h>
2524#include < Printable.h>
26-
27- // A class to make it easier to handle and pass around IP addresses
28-
29- #define IPADDRESS_V4_BYTES_INDEX 12
30- #define IPADDRESS_V4_DWORD_INDEX 3
25+ #include < lwip/netif.h>
3126
3227enum IPType
3328{
34- IPv4,
35- IPv6
29+ IPv4 = IPADDR_TYPE_V4 ,
30+ IPv6 = IPADDR_TYPE_V6
3631};
3732
3833class IPAddress : public Printable
3934{
4035private:
41- union {
42- uint8_t bytes[16 ];
43- uint32_t dword[4 ];
44- } _address;
45- IPType _type;
36+ ip_addr_t _ip;
4637
4738 // Access the raw byte array containing the address. Because this returns a pointer
4839 // to the internal structure rather than a copy of the address this function should only
4940 // be used when you know that the usage of the returned uint8_t* will be transient and not
5041 // stored.
51- uint8_t * raw_address ()
52- {
53- return _type == IPv4 ? &_address.bytes [IPADDRESS_V4_BYTES_INDEX] : _address.bytes ;
42+ uint8_t * raw_address () {
43+ return reinterpret_cast <uint8_t *>(&v4 ());
5444 }
45+ const uint8_t * raw_address () const {
46+ return reinterpret_cast <const uint8_t *>(&v4 ());
47+ }
48+
49+ void ctor32 (uint32_t );
5550
5651public:
5752 // Constructors
5853 IPAddress ();
59- IPAddress (IPType ip_type );
54+ IPAddress (const IPAddress& from );
6055 IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
6156 IPAddress (uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16);
62- IPAddress (uint32_t address);
63- IPAddress (const uint8_t *address);
64- IPAddress (IPType ip_type, const uint8_t *address);
65- // If IPv4 fails tries IPv6 see fromString function
66- IPAddress (const char *address);
67- virtual ~IPAddress () {}
57+ IPAddress (uint32_t address) { *this = address; }
58+ IPAddress (int address) { *this = address; }
59+ IPAddress (const uint8_t *address) { *this = address; }
60+ IPAddress (IPType type, const uint8_t *address);
61+ IPAddress (IPType type, const uint8_t *address, uint8_t zone);
6862
6963 bool fromString (const char *address);
7064 bool fromString (const String &address) { return fromString (address.c_str ()); }
7165
72- // Overloaded cast operator to allow IPAddress objects to be used where a
73- // uint32_t is expected
74- operator uint32_t () const
75- {
76- return _type == IPv4 ? _address.dword [IPADDRESS_V4_DWORD_INDEX] : 0 ;
77- }
66+ // Overloaded cast operator to allow IPAddress objects to be used where a pointer
67+ // to a four-byte uint8_t array is expected
68+ operator uint32_t () const { return isV4 ()? v4 (): (uint32_t )0 ; }
69+ operator uint32_t () { return isV4 ()? v4 (): (uint32_t )0 ; }
70+
71+ // generic IPv4 wrapper to uint32-view like arduino loves to see it
72+ const uint32_t & v4 () const { return ip_2_ip4 (&_ip)->addr ; }
73+ uint32_t & v4 () { return ip_2_ip4 (&_ip)->addr ; }
7874
79- bool operator ==(const IPAddress& addr) const ;
75+ bool operator ==(const IPAddress& addr) const {
76+ return ip_addr_cmp (&_ip, &addr._ip );
77+ }
78+ bool operator !=(const IPAddress& addr) const {
79+ return !ip_addr_cmp (&_ip, &addr._ip );
80+ }
81+ bool operator ==(uint32_t addr) const {
82+ return isV4 () && v4 () == addr;
83+ }
84+ // bool operator==(unsigned long addr) const {
85+ // return isV4() && v4() == (uint32_t)addr;
86+ // }
87+ bool operator !=(uint32_t addr) const {
88+ return !(isV4 () && v4 () == addr);
89+ }
90+ // bool operator!=(unsigned long addr) const {
91+ // return isV4() && v4() != (uint32_t)addr;
92+ // }
8093 bool operator ==(const uint8_t * addr) const ;
8194
95+ int operator >>(int n) const {
96+ return isV4 ()? v4 () >> n: 0 ;
97+ }
98+
8299 // Overloaded index operator to allow getting and setting individual octets of the address
83- uint8_t operator [](int index) const ;
84- uint8_t & operator [](int index);
100+ uint8_t operator [](int index) const {
101+ if (!isV4 ()) {
102+ return 0 ;
103+ }
104+
105+ return ip4_addr_get_byte_val (*ip_2_ip4 (&_ip), index);
106+ }
107+ uint8_t & operator [](int index) {
108+ setV4 ();
109+ uint8_t * ptr = reinterpret_cast <uint8_t *>(&v4 ());
110+ return *(ptr + index);
111+ }
85112
86113 // Overloaded copy operators to allow initialisation of IPAddress objects from other types
87114 IPAddress& operator =(const uint8_t *address);
88115 IPAddress& operator =(uint32_t address);
89- // If IPv4 fails tries IPv6 see fromString function
90- IPAddress& operator =(const char *address);
116+ IPAddress& operator =(const IPAddress&) = default ;
117+
118+ IPType type () const { return (IPType)_ip.type ; }
91119
92120 virtual size_t printTo (Print& p) const ;
93121 String toString () const ;
94122
95- IPType type () const { return _type; }
123+ void clear ();
124+
125+ /*
126+ check if input string(arg) is a valid IPV4 address or not.
127+ return true on valid.
128+ return false on invalid.
129+ */
130+ static bool isValid (const String& arg);
131+ static bool isValid (const char * arg);
96132
97133 friend class EthernetClass ;
98134 friend class UDP ;
@@ -101,14 +137,73 @@ class IPAddress: public Printable
101137 friend class DhcpClass ;
102138 friend class DNSClient ;
103139
140+ operator ip_addr_t () const { return _ip; }
141+ operator const ip_addr_t *() const { return &_ip; }
142+ operator ip_addr_t *() { return &_ip; }
143+
144+ bool isV4 () const { return IP_IS_V4_VAL (_ip); }
145+ void setV4 () { IP_SET_TYPE_VAL (_ip, IPADDR_TYPE_V4); }
146+
147+ bool isLocal () const { return ip_addr_islinklocal (&_ip); }
148+ bool isAny () const { return ip_addr_isany_val (_ip); }
149+
150+ #if LWIP_IPV6
151+ IPAddress (const ip_addr_t & lwip_addr) { ip_addr_copy (_ip, lwip_addr); }
152+ IPAddress (const ip_addr_t * lwip_addr) { ip_addr_copy (_ip, *lwip_addr); }
153+
154+ IPAddress& operator =(const ip_addr_t & lwip_addr) { ip_addr_copy (_ip, lwip_addr); return *this ; }
155+ IPAddress& operator =(const ip_addr_t * lwip_addr) { ip_addr_copy (_ip, *lwip_addr); return *this ; }
156+
157+ uint16_t * raw6 ()
158+ {
159+ setV6 ();
160+ return reinterpret_cast <uint16_t *>(ip_2_ip6 (&_ip));
161+ }
162+
163+ const uint16_t * raw6 () const
164+ {
165+ return isV6 ()? reinterpret_cast <const uint16_t *>(ip_2_ip6 (&_ip)): nullptr ;
166+ }
167+
168+ // when not IPv6, ip_addr_t == ip4_addr_t so this one would be ambiguous
169+ // required otherwise
170+ operator const ip4_addr_t *() const { return isV4 ()? ip_2_ip4 (&_ip): nullptr ; }
171+
172+ bool isV6 () const { return IP_IS_V6_VAL (_ip); }
173+ void setV6 () {
174+ IP_SET_TYPE_VAL (_ip, IPADDR_TYPE_V6);
175+ ip6_addr_clear_zone (ip_2_ip6 (&_ip));
176+ }
177+ inline uint8_t zone () const { return isV6 () ? ip_2_ip6 (&_ip)->zone : 0 ; }
178+ void setZone (uint8_t zone) {
179+ if (isV6 ()) {
180+ ip_2_ip6 (&_ip)->zone = zone;
181+ }
182+ }
183+
184+
104185protected:
105- bool fromString4 (const char *address);
106186 bool fromString6 (const char *address);
107- String toString4 () const ;
108- String toString6 () const ;
187+
188+ #else /* !LWIP_IPV6 */
189+
190+ // allow portable code when IPv6 is not enabled
191+
192+ uint16_t * raw6 () { return nullptr ; }
193+ const uint16_t * raw6 () const { return nullptr ; }
194+ bool isV6 () const { return false ; }
195+ void setV6 () { }
196+ inline uint8_t zone () const { return 0 ; }
197+ void setZone (uint8_t zone) { }
198+
199+ #endif
200+
201+ protected:
202+ bool fromString4 (const char *address);
109203};
110204
111205// changed to extern because const declaration creates copies in BSS of INADDR_NONE for each CPP unit that includes it
112206extern IPAddress INADDR_NONE;
113207extern IPAddress IN6ADDR_ANY;
208+
114209#endif
0 commit comments