20
20
#include < Arduino.h>
21
21
#include < IPAddress.h>
22
22
#include < Print.h>
23
+ #include < StreamString.h>
23
24
24
- IPAddress::IPAddress ()
25
- {
26
- _address.dword = 0 ;
25
+ IPAddress::IPAddress () {
26
+ #if LWIP_IPV6
27
+ _ip = *IP6_ADDR_ANY;
28
+ #else
29
+ _ip = *IP_ADDR_ANY;
30
+ #endif
31
+ // _ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address
27
32
}
28
33
29
- IPAddress::IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet )
34
+ IPAddress::IPAddress (const IPAddress& from )
30
35
{
31
- _address.bytes [0 ] = first_octet;
32
- _address.bytes [1 ] = second_octet;
33
- _address.bytes [2 ] = third_octet;
34
- _address.bytes [3 ] = fourth_octet;
36
+ ip_addr_copy (_ip, from._ip );
35
37
}
36
38
37
- IPAddress::IPAddress (uint32_t address)
38
- {
39
- _address.dword = address;
39
+ IPAddress::IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) {
40
+ setV4 ();
41
+ (*this )[0 ] = first_octet;
42
+ (*this )[1 ] = second_octet;
43
+ (*this )[2 ] = third_octet;
44
+ (*this )[3 ] = fourth_octet;
40
45
}
41
46
42
- IPAddress::IPAddress (const uint8_t *address)
43
- {
44
- memcpy (_address.bytes , address, sizeof (_address.bytes ));
47
+ IPAddress::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) {
48
+ setV6 ();
49
+ (*this )[0 ] = o1;
50
+ (*this )[1 ] = o2;
51
+ (*this )[2 ] = o3;
52
+ (*this )[3 ] = o4;
53
+ (*this )[4 ] = o5;
54
+ (*this )[5 ] = o6;
55
+ (*this )[6 ] = o7;
56
+ (*this )[7 ] = o8;
57
+ (*this )[8 ] = o9;
58
+ (*this )[9 ] = o10;
59
+ (*this )[10 ] = o11;
60
+ (*this )[11 ] = o12;
61
+ (*this )[12 ] = o13;
62
+ (*this )[13 ] = o14;
63
+ (*this )[14 ] = o15;
64
+ (*this )[15 ] = o16;
45
65
}
46
66
47
- IPAddress& IPAddress::operator =(const uint8_t *address)
48
- {
49
- memcpy (_address.bytes , address, sizeof (_address.bytes ));
50
- return *this ;
67
+ IPAddress::IPAddress (IPType type, const uint8_t *address) {
68
+ if (type == IPv4) {
69
+ setV4 ();
70
+ memcpy (&this ->_ip .u_addr .ip4 , address, 4 );
71
+ } else if (type == IPv6) {
72
+ setV6 ();
73
+ memcpy (&this ->_ip .u_addr .ip6 .addr [0 ], address, 16 );
74
+ } else {
75
+ #if LWIP_IPV6
76
+ _ip = *IP6_ADDR_ANY;
77
+ #else
78
+ _ip = *IP_ADDR_ANY;
79
+ #endif
80
+ }
81
+
51
82
}
52
83
53
- IPAddress& IPAddress::operator =(uint32_t address)
54
- {
55
- _address.dword = address;
56
- return *this ;
84
+ void IPAddress::ctor32 (uint32_t address) {
85
+ setV4 ();
86
+ v4 () = address;
57
87
}
58
88
59
- bool IPAddress::operator ==(const uint8_t * addr) const
60
- {
61
- return memcmp (addr, _address.bytes , sizeof (_address.bytes )) == 0 ;
89
+ IPAddress::IPAddress (const uint8_t *address) {
90
+ setV4 ();
91
+ (*this )[0 ] = address[0 ];
92
+ (*this )[1 ] = address[1 ];
93
+ (*this )[2 ] = address[2 ];
94
+ (*this )[3 ] = address[3 ];
62
95
}
63
96
64
- size_t IPAddress::printTo (Print& p) const
65
- {
66
- size_t n = 0 ;
67
- for (int i = 0 ; i < 3 ; i++) {
68
- n += p.print (_address.bytes [i], DEC);
69
- n += p.print (' .' );
97
+ bool IPAddress::fromString (const char *address) {
98
+ if (!fromString4 (address)) {
99
+ #if LWIP_IPV6
100
+ return fromString6 (address);
101
+ #else
102
+ return false ;
103
+ #endif
70
104
}
71
- n += p.print (_address.bytes [3 ], DEC);
72
- return n;
105
+ return true ;
73
106
}
74
107
75
- String IPAddress::toString () const
76
- {
77
- char szRet[16 ];
78
- sprintf (szRet," %u.%u.%u.%u" , _address.bytes [0 ], _address.bytes [1 ], _address.bytes [2 ], _address.bytes [3 ]);
79
- return String (szRet);
80
- }
81
-
82
- bool IPAddress::fromString (const char *address)
83
- {
84
- // TODO: add support for "a", "a.b", "a.b.c" formats
108
+ bool IPAddress::fromString4 (const char *address) {
109
+ // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats
85
110
86
111
uint16_t acc = 0 ; // Accumulator
87
112
uint8_t dots = 0 ;
@@ -103,7 +128,7 @@ bool IPAddress::fromString(const char *address)
103
128
// Too much dots (there must be 3 dots)
104
129
return false ;
105
130
}
106
- _address. bytes [dots++] = acc;
131
+ (* this ) [dots++] = acc;
107
132
acc = 0 ;
108
133
}
109
134
else
@@ -117,9 +142,146 @@ bool IPAddress::fromString(const char *address)
117
142
// Too few dots (there must be 3 dots)
118
143
return false ;
119
144
}
120
- _address.bytes [3 ] = acc;
145
+ (*this )[3 ] = acc;
146
+
147
+ setV4 ();
148
+ return true ;
149
+ }
150
+
151
+ IPAddress& IPAddress::operator =(const uint8_t *address) {
152
+ setV4 ();
153
+ v4 () = *reinterpret_cast <const uint32_t *>(address);
154
+ return *this ;
155
+ }
156
+
157
+ IPAddress& IPAddress::operator =(uint32_t address) {
158
+ setV4 ();
159
+ v4 () = address;
160
+ return *this ;
161
+ }
162
+
163
+ bool IPAddress::operator ==(const uint8_t * addr) const {
164
+ return isV4 () && v4 () == *reinterpret_cast <const uint32_t *>(addr);
165
+ }
166
+
167
+ size_t IPAddress::printTo (Print& p) const {
168
+ size_t n = 0 ;
169
+
170
+ // if (!isSet())
171
+ // return p.print(F("(IP unset)"));
172
+
173
+ #if LWIP_IPV6
174
+ if (isV6 ()) {
175
+ int count0 = 0 ;
176
+ for (int i = 0 ; i < 8 ; i++) {
177
+ uint16_t bit = PP_NTOHS (raw6 ()[i]);
178
+ if (bit || count0 < 0 ) {
179
+ n += p.printf (" %x" , bit);
180
+ if (count0 > 0 )
181
+ // no more hiding 0
182
+ count0 = -8 ;
183
+ } else
184
+ count0++;
185
+ if ((i != 7 && count0 < 2 ) || count0 == 7 )
186
+ n += p.print (' :' );
187
+ }
188
+ return n;
189
+ }
190
+ #endif
191
+
192
+ for (int i = 0 ; i < 4 ; i++) {
193
+ n += p.print ((*this )[i], DEC);
194
+ if (i != 3 )
195
+ n += p.print (' .' );
196
+ }
197
+ return n;
198
+ }
199
+
200
+ String IPAddress::toString () const
201
+ {
202
+ StreamString sstr;
203
+ #if LWIP_IPV6
204
+ if (isV6 ())
205
+ sstr.reserve (40 ); // 8 shorts x 4 chars each + 7 colons + nullterm
206
+ else
207
+ #endif
208
+ sstr.reserve (16 ); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)'
209
+ printTo (sstr);
210
+ return sstr;
211
+ }
212
+
213
+ bool IPAddress::isValid (const String& arg) {
214
+ return IPAddress ().fromString (arg);
215
+ }
216
+
217
+ bool IPAddress::isValid (const char * arg) {
218
+ return IPAddress ().fromString (arg);
219
+ }
220
+
221
+ const IPAddress INADDR46_ANY; // generic "0.0.0.0" for IPv4 & IPv6
222
+ const IPAddress INADDR46_NONE (255 ,255 ,255 ,255 );
223
+
224
+ void IPAddress::clear () {
225
+ (*this ) = INADDR46_ANY;
226
+ }
227
+
228
+ /* *************************************/
229
+
230
+ #if LWIP_IPV6
231
+
232
+ bool IPAddress::fromString6 (const char *address) {
233
+ // TODO: test test test
234
+
235
+ uint32_t acc = 0 ; // Accumulator
236
+ int dots = 0 , doubledots = -1 ;
237
+
238
+ while (*address)
239
+ {
240
+ char c = tolower (*address++);
241
+ if (isalnum (c)) {
242
+ if (c >= ' a' )
243
+ c -= ' a' - ' 0' - 10 ;
244
+ acc = acc * 16 + (c - ' 0' );
245
+ if (acc > 0xffff )
246
+ // Value out of range
247
+ return false ;
248
+ }
249
+ else if (c == ' :' ) {
250
+ if (*address == ' :' ) {
251
+ if (doubledots >= 0 )
252
+ // :: allowed once
253
+ return false ;
254
+ // remember location
255
+ doubledots = dots + !!acc;
256
+ address++;
257
+ }
258
+ if (dots == 7 )
259
+ // too many separators
260
+ return false ;
261
+ raw6 ()[dots++] = PP_HTONS (acc);
262
+ acc = 0 ;
263
+ }
264
+ else
265
+ // Invalid char
266
+ return false ;
267
+ }
268
+
269
+ if (doubledots == -1 && dots != 7 )
270
+ // Too few separators
271
+ return false ;
272
+ raw6 ()[dots++] = PP_HTONS (acc);
273
+
274
+ if (doubledots != -1 ) {
275
+ for (int i = dots - doubledots - 1 ; i >= 0 ; i--)
276
+ raw6 ()[8 - dots + doubledots + i] = raw6 ()[doubledots + i];
277
+ for (int i = doubledots; i < 8 - dots + doubledots; i++)
278
+ raw6 ()[i] = 0 ;
279
+ }
280
+
281
+ setV6 ();
121
282
return true ;
122
283
}
284
+ #endif // LWIP_IPV6
123
285
124
286
// declared one time - as external in IPAddress.h
125
- IPAddress INADDR_NONE (0 , 0 , 0 , 0 );
287
+ IPAddress INADDR_NONE (0 , 0 , 0 , 0 ); // TODO
0 commit comments