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
+ uint8_t addr[] {
41
+ first_octet,
42
+ second_octet,
43
+ third_octet,
44
+ fourth_octet,
45
+ };
46
+ *this = &addr[0 ];
40
47
}
41
48
42
- IPAddress::IPAddress (const uint8_t *address)
43
- {
44
- memcpy (_address.bytes , address, sizeof (_address.bytes ));
49
+ 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) {
50
+ setV6 ();
51
+ (*this )[0 ] = o1;
52
+ (*this )[1 ] = o2;
53
+ (*this )[2 ] = o3;
54
+ (*this )[3 ] = o4;
55
+ (*this )[4 ] = o5;
56
+ (*this )[5 ] = o6;
57
+ (*this )[6 ] = o7;
58
+ (*this )[7 ] = o8;
59
+ (*this )[8 ] = o9;
60
+ (*this )[9 ] = o10;
61
+ (*this )[10 ] = o11;
62
+ (*this )[11 ] = o12;
63
+ (*this )[12 ] = o13;
64
+ (*this )[13 ] = o14;
65
+ (*this )[14 ] = o15;
66
+ (*this )[15 ] = o16;
45
67
}
46
68
47
- IPAddress& IPAddress::operator =(const uint8_t *address)
48
- {
49
- memcpy (_address.bytes , address, sizeof (_address.bytes ));
50
- return *this ;
69
+ IPAddress::IPAddress (IPType type, const uint8_t *address) {
70
+ IPAddress (type, address, 0 );
51
71
}
52
72
53
- IPAddress& IPAddress::operator =(uint32_t address)
54
- {
55
- _address.dword = address;
56
- return *this ;
57
- }
73
+ IPAddress::IPAddress (IPType type, const uint8_t *address, uint8_t zone) {
74
+ if (type == IPv4) {
75
+ setV4 ();
76
+ memcpy (&this ->_ip .u_addr .ip4 , address, 4 );
77
+ } else if (type == IPv6) {
78
+ setV6 ();
79
+ memcpy (&this ->_ip .u_addr .ip6 .addr [0 ], address, 16 );
80
+ setZone (zone);
81
+ } else {
82
+ #if LWIP_IPV6
83
+ _ip = *IP6_ADDR_ANY;
84
+ #else
85
+ _ip = *IP_ADDR_ANY;
86
+ #endif
87
+ }
58
88
59
- bool IPAddress::operator ==(const uint8_t * addr) const
60
- {
61
- return memcmp (addr, _address.bytes , sizeof (_address.bytes )) == 0 ;
62
89
}
63
90
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 (' .' );
91
+ bool IPAddress::fromString (const char *address) {
92
+ if (!fromString4 (address)) {
93
+ #if LWIP_IPV6
94
+ return fromString6 (address);
95
+ #else
96
+ return false ;
97
+ #endif
70
98
}
71
- n += p.print (_address.bytes [3 ], DEC);
72
- return n;
73
- }
74
-
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);
99
+ return true ;
80
100
}
81
101
82
- bool IPAddress::fromString (const char *address)
83
- {
84
- // TODO: add support for "a", "a.b", "a.b.c" formats
102
+ bool IPAddress::fromString4 (const char *address) {
103
+ // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats
85
104
86
105
uint16_t acc = 0 ; // Accumulator
87
106
uint8_t dots = 0 ;
@@ -103,7 +122,7 @@ bool IPAddress::fromString(const char *address)
103
122
// Too much dots (there must be 3 dots)
104
123
return false ;
105
124
}
106
- _address. bytes [dots++] = acc;
125
+ (* this ) [dots++] = acc;
107
126
acc = 0 ;
108
127
}
109
128
else
@@ -117,9 +136,122 @@ bool IPAddress::fromString(const char *address)
117
136
// Too few dots (there must be 3 dots)
118
137
return false ;
119
138
}
120
- _address.bytes [3 ] = acc;
139
+ (*this )[3 ] = acc;
140
+
141
+ setV4 ();
121
142
return true ;
122
143
}
123
144
145
+ IPAddress& IPAddress::operator =(const uint8_t *address) {
146
+ uint32_t value;
147
+ memcpy_P (&value, address, sizeof (value));
148
+ *this = value;
149
+ return *this ;
150
+ }
151
+
152
+ IPAddress& IPAddress::operator =(uint32_t address) {
153
+ setV4 ();
154
+ v4 () = address;
155
+ return *this ;
156
+ }
157
+
158
+ bool IPAddress::operator ==(const uint8_t * addr) const {
159
+ if (!isV4 ()) {
160
+ return false ;
161
+ }
162
+
163
+ uint32_t value;
164
+ memcpy_P (&value, addr, sizeof (value));
165
+
166
+ return v4 () == value;
167
+ }
168
+
169
+ size_t IPAddress::printTo (Print& p) const {
170
+ size_t n = 0 ;
171
+
172
+ #if LWIP_IPV6
173
+ if (isV6 ()) {
174
+ int count0 = 0 ;
175
+ for (int i = 0 ; i < 8 ; i++) {
176
+ uint16_t bit = PP_NTOHS (raw6 ()[i]);
177
+ if (bit || count0 < 0 ) {
178
+ n += p.printf (" %x" , bit);
179
+ if (count0 > 0 )
180
+ // no more hiding 0
181
+ count0 = -8 ;
182
+ } else
183
+ count0++;
184
+ if ((i != 7 && count0 < 2 ) || count0 == 7 )
185
+ n += p.print (' :' );
186
+ }
187
+ // add a zone if zone-id si non-zero
188
+ if (_ip.u_addr .ip6 .zone ) {
189
+ n += p.print (' %' );
190
+ char if_name[NETIF_NAMESIZE];
191
+ netif_index_to_name (_ip.u_addr .ip6 .zone , if_name);
192
+ n += p.print (if_name);
193
+ }
194
+ return n;
195
+ }
196
+ #endif
197
+
198
+ for (int i = 0 ; i < 4 ; i++) {
199
+ n += p.print ((*this )[i], DEC);
200
+ if (i != 3 )
201
+ n += p.print (' .' );
202
+ }
203
+ return n;
204
+ }
205
+
206
+ String IPAddress::toString () const
207
+ {
208
+ StreamString sstr;
209
+ #if LWIP_IPV6
210
+ if (isV6 ())
211
+ sstr.reserve (44 ); // 8 shorts x 4 chars each + 7 colons + nullterm + '%' + zone-id
212
+ else
213
+ #endif
214
+ sstr.reserve (16 ); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)'
215
+ printTo (sstr);
216
+ return sstr;
217
+ }
218
+
219
+ bool IPAddress::isValid (const String& arg) {
220
+ return IPAddress ().fromString (arg);
221
+ }
222
+
223
+ bool IPAddress::isValid (const char * arg) {
224
+ return IPAddress ().fromString (arg);
225
+ }
226
+
227
+ const IPAddress INADDR46_ANY; // generic "0.0.0.0" for IPv4 & IPv6
228
+ const IPAddress INADDR46_NONE (255 ,255 ,255 ,255 );
229
+
230
+ void IPAddress::clear () {
231
+ (*this ) = INADDR46_ANY;
232
+ }
233
+
234
+ /* *************************************/
235
+
236
+ #if LWIP_IPV6
237
+
238
+ bool IPAddress::fromString6 (const char *address) {
239
+ ip6_addr_t ip6;
240
+ if (ip6addr_aton (address, &ip6)) {
241
+ setV6 ();
242
+ memcpy (&this ->_ip .u_addr .ip6 .addr [0 ], ip6.addr , 16 );
243
+ // look for '%' in string
244
+ const char *s = address;
245
+ while (*s && *s != ' %' ) { s++; }
246
+ if (*s == ' %' ) {
247
+ // we have a zone id
248
+ setZone (netif_name_to_index (s + 1 ));
249
+ }
250
+ return true ;
251
+ }
252
+ return false ;
253
+ }
254
+ #endif // LWIP_IPV6
255
+
124
256
// declared one time - as external in IPAddress.h
125
- IPAddress INADDR_NONE (0 , 0 , 0 , 0 );
257
+ IPAddress INADDR_NONE (0 , 0 , 0 , 0 ); // TODO
0 commit comments