20
20
#ifndef IPAddress_h
21
21
#define IPAddress_h
22
22
23
- #include < stdint.h>
24
23
#include < WString.h>
25
24
#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>
31
26
32
27
enum IPType
33
28
{
34
- IPv4,
35
- IPv6
29
+ IPv4 = IPADDR_TYPE_V4 ,
30
+ IPv6 = IPADDR_TYPE_V6
36
31
};
37
32
38
33
class IPAddress : public Printable
39
34
{
40
35
private:
41
- union {
42
- uint8_t bytes[16 ];
43
- uint32_t dword[4 ];
44
- } _address;
45
- IPType _type;
36
+ ip_addr_t _ip;
46
37
47
38
// Access the raw byte array containing the address. Because this returns a pointer
48
39
// to the internal structure rather than a copy of the address this function should only
49
40
// be used when you know that the usage of the returned uint8_t* will be transient and not
50
41
// 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 ());
54
44
}
45
+ const uint8_t * raw_address () const {
46
+ return reinterpret_cast <const uint8_t *>(&v4 ());
47
+ }
48
+
49
+ void ctor32 (uint32_t );
55
50
56
51
public:
57
52
// Constructors
58
53
IPAddress ();
59
- IPAddress (IPType ip_type );
54
+ IPAddress (const IPAddress& from );
60
55
IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
61
56
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);
68
62
69
63
bool fromString (const char *address);
70
64
bool fromString (const String &address) { return fromString (address.c_str ()); }
71
65
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 ; }
78
74
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
+ // }
80
93
bool operator ==(const uint8_t * addr) const ;
81
94
95
+ int operator >>(int n) const {
96
+ return isV4 ()? v4 () >> n: 0 ;
97
+ }
98
+
82
99
// 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
+ }
85
112
86
113
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
87
114
IPAddress& operator =(const uint8_t *address);
88
115
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 ; }
91
119
92
120
virtual size_t printTo (Print& p) const ;
93
121
String toString () const ;
94
122
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);
96
132
97
133
friend class EthernetClass ;
98
134
friend class UDP ;
@@ -101,14 +137,73 @@ class IPAddress: public Printable
101
137
friend class DhcpClass ;
102
138
friend class DNSClient ;
103
139
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
+
104
185
protected:
105
- bool fromString4 (const char *address);
106
186
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);
109
203
};
110
204
111
205
// changed to extern because const declaration creates copies in BSS of INADDR_NONE for each CPP unit that includes it
112
206
extern IPAddress INADDR_NONE;
113
207
extern IPAddress IN6ADDR_ANY;
208
+
114
209
#endif
0 commit comments