2020#include < Arduino.h>
2121#include < IPAddress.h>
2222#include < Print.h>
23+ #include < StreamString.h>
2324
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
2732}
2833
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 )
3035{
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 );
3537}
3638
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;
4045}
4146
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;
4565}
4666
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+
5182}
5283
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;
5787}
5888
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 ];
6295}
6396
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
70104 }
71- n += p.print (_address.bytes [3 ], DEC);
72- return n;
105+ return true ;
73106}
74107
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
85110
86111 uint16_t acc = 0 ; // Accumulator
87112 uint8_t dots = 0 ;
@@ -103,7 +128,7 @@ bool IPAddress::fromString(const char *address)
103128 // Too much dots (there must be 3 dots)
104129 return false ;
105130 }
106- _address. bytes [dots++] = acc;
131+ (* this ) [dots++] = acc;
107132 acc = 0 ;
108133 }
109134 else
@@ -117,9 +142,146 @@ bool IPAddress::fromString(const char *address)
117142 // Too few dots (there must be 3 dots)
118143 return false ;
119144 }
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 ();
121282 return true ;
122283}
284+ #endif // LWIP_IPV6
123285
124286// 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