1
1
/*
2
- IPAddress.cpp - Base class that provides IPAddress
3
- Copyright (c) 2011 Adrian McEwen. All right reserved.
2
+ IPAddress.cpp - Base class that provides IPAddress
3
+ Copyright (c) 2011 Adrian McEwen. All right reserved.
4
4
5
- This library is free software; you can redistribute it and/or
6
- modify it under the terms of the GNU Lesser General Public
7
- License as published by the Free Software Foundation; either
8
- version 2.1 of the License, or (at your option) any later version.
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
9
10
- This library is distributed in the hope that it will be useful,
11
- but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- Lesser General Public License for more details.
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
14
15
- You should have received a copy of the GNU Lesser General Public
16
- License along with this library; if not, write to the Free Software
17
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
- */
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
19
20
- #include < Arduino.h>
21
- #include < IPAddress.h>
22
- #include < Print.h>
23
- #include < StreamString.h>
20
+ #include " IPAddress.h"
21
+ #include " Print.h"
22
+ #include " lwip/netif.h"
24
23
25
24
IPAddress::IPAddress () : IPAddress(IPv4) {}
26
25
27
26
IPAddress::IPAddress (IPType ip_type)
28
27
{
29
28
_type = ip_type;
29
+ _zone = IP6_NO_ZONE;
30
30
memset (_address.bytes , 0 , sizeof (_address.bytes ));
31
31
}
32
32
33
33
IPAddress::IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
34
34
{
35
35
_type = IPv4;
36
+ _zone = IP6_NO_ZONE;
36
37
memset (_address.bytes , 0 , sizeof (_address.bytes ));
37
38
_address.bytes [IPADDRESS_V4_BYTES_INDEX] = first_octet;
38
39
_address.bytes [IPADDRESS_V4_BYTES_INDEX + 1 ] = second_octet;
39
40
_address.bytes [IPADDRESS_V4_BYTES_INDEX + 2 ] = third_octet;
40
41
_address.bytes [IPADDRESS_V4_BYTES_INDEX + 3 ] = fourth_octet;
41
42
}
42
43
43
- 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) {
44
+ 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, uint8_t z ) {
44
45
_type = IPv6;
45
46
_address.bytes [0 ] = o1;
46
47
_address.bytes [1 ] = o2;
@@ -58,6 +59,7 @@ IPAddress::IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5,
58
59
_address.bytes [13 ] = o14;
59
60
_address.bytes [14 ] = o15;
60
61
_address.bytes [15 ] = o16;
62
+ _zone = z;
61
63
}
62
64
63
65
IPAddress::IPAddress (uint32_t address)
@@ -78,14 +80,16 @@ IPAddress::IPAddress(uint32_t address)
78
80
79
81
IPAddress::IPAddress (const uint8_t *address) : IPAddress(IPv4, address) {}
80
82
81
- IPAddress::IPAddress (IPType ip_type, const uint8_t *address)
83
+ IPAddress::IPAddress (IPType ip_type, const uint8_t *address, uint8_t z )
82
84
{
83
85
_type = ip_type;
84
86
if (ip_type == IPv4) {
85
87
memset (_address.bytes , 0 , sizeof (_address.bytes ));
86
88
memcpy (&_address.bytes [IPADDRESS_V4_BYTES_INDEX], address, sizeof (uint32_t ));
89
+ _zone = 0 ;
87
90
} else {
88
91
memcpy (_address.bytes , address, sizeof (_address.bytes ));
92
+ _zone = z;
89
93
}
90
94
}
91
95
@@ -94,121 +98,9 @@ IPAddress::IPAddress(const char *address)
94
98
fromString (address);
95
99
}
96
100
97
- IPAddress& IPAddress::operator =(const uint8_t *address)
98
- {
99
- // IPv4 only conversion from byte pointer
100
- _type = IPv4;
101
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
102
- memcpy (&_address.bytes [IPADDRESS_V4_BYTES_INDEX], address, sizeof (uint32_t ));
103
- return *this ;
104
- }
105
-
106
- IPAddress& IPAddress::operator =(const char *address)
101
+ IPAddress::IPAddress (const IPAddress& address)
107
102
{
108
- fromString (address);
109
- return *this ;
110
- }
111
-
112
- IPAddress& IPAddress::operator =(uint32_t address)
113
- {
114
- // IPv4 conversion
115
- // See note on conversion/comparison and uint32_t
116
- _type = IPv4;
117
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
118
- _address.dword [IPADDRESS_V4_DWORD_INDEX] = address;
119
- return *this ;
120
- }
121
-
122
- bool IPAddress::operator ==(const IPAddress& addr) const
123
- {
124
- return (addr._type == _type)
125
- && (memcmp (addr._address .bytes , _address.bytes , sizeof (_address.bytes )) == 0 );
126
- }
127
-
128
- bool IPAddress::operator ==(const uint8_t * addr) const
129
- {
130
- // IPv4 only comparison to byte pointer
131
- // Can't support IPv6 as we know our type, but not the length of the pointer
132
- return _type == IPv4 && memcmp (addr, &_address.bytes [IPADDRESS_V4_BYTES_INDEX], sizeof (uint32_t )) == 0 ;
133
- }
134
-
135
- uint8_t IPAddress::operator [](int index) const {
136
- if (_type == IPv4) {
137
- return _address.bytes [IPADDRESS_V4_BYTES_INDEX + index];
138
- }
139
- return _address.bytes [index];
140
- }
141
-
142
- uint8_t & IPAddress::operator [](int index) {
143
- if (_type == IPv4) {
144
- return _address.bytes [IPADDRESS_V4_BYTES_INDEX + index];
145
- }
146
- return _address.bytes [index];
147
- }
148
-
149
- size_t IPAddress::printTo (Print& p) const
150
- {
151
- size_t n = 0 ;
152
-
153
- if (_type == IPv6) {
154
- // IPv6 IETF canonical format: compress left-most longest run of two or more zero fields, lower case
155
- int8_t longest_start = -1 ;
156
- int8_t longest_length = 1 ;
157
- int8_t current_start = -1 ;
158
- int8_t current_length = 0 ;
159
- for (int8_t f = 0 ; f < 8 ; f++) {
160
- if (_address.bytes [f * 2 ] == 0 && _address.bytes [f * 2 + 1 ] == 0 ) {
161
- if (current_start == -1 ) {
162
- current_start = f;
163
- current_length = 1 ;
164
- } else {
165
- current_length++;
166
- }
167
- if (current_length > longest_length) {
168
- longest_start = current_start;
169
- longest_length = current_length;
170
- }
171
- } else {
172
- current_start = -1 ;
173
- }
174
- }
175
- for (int f = 0 ; f < 8 ; f++) {
176
- if (f < longest_start || f >= longest_start + longest_length) {
177
- uint8_t c1 = _address.bytes [f * 2 ] >> 4 ;
178
- uint8_t c2 = _address.bytes [f * 2 ] & 0xf ;
179
- uint8_t c3 = _address.bytes [f * 2 + 1 ] >> 4 ;
180
- uint8_t c4 = _address.bytes [f * 2 + 1 ] & 0xf ;
181
- if (c1 > 0 ) {
182
- n += p.print ((char )(c1 < 10 ? ' 0' + c1 : ' a' + c1 - 10 ));
183
- }
184
- if (c1 > 0 || c2 > 0 ) {
185
- n += p.print ((char )(c2 < 10 ? ' 0' + c2 : ' a' + c2 - 10 ));
186
- }
187
- if (c1 > 0 || c2 > 0 || c3 > 0 ) {
188
- n += p.print ((char )(c3 < 10 ? ' 0' + c3 : ' a' + c3 - 10 ));
189
- }
190
- n += p.print ((char )(c4 < 10 ? ' 0' + c4 : ' a' + c4 - 10 ));
191
- if (f < 7 ) {
192
- n += p.print (' :' );
193
- }
194
- } else if (f == longest_start) {
195
- if (longest_start == 0 ) {
196
- n += p.print (' :' );
197
- }
198
- n += p.print (' :' );
199
- }
200
- }
201
- return n;
202
- }
203
-
204
- // IPv4
205
- for (int i =0 ; i < 3 ; i++)
206
- {
207
- n += p.print (_address.bytes [IPADDRESS_V4_BYTES_INDEX + i], DEC);
208
- n += p.print (' .' );
209
- }
210
- n += p.print (_address.bytes [IPADDRESS_V4_BYTES_INDEX + 3 ], DEC);
211
- return n;
103
+ *this = address;
212
104
}
213
105
214
106
String IPAddress::toString4 () const
@@ -220,10 +112,13 @@ String IPAddress::toString4() const
220
112
221
113
String IPAddress::toString6 () const
222
114
{
223
- StreamString s;
224
- s.reserve (40 );
225
- printTo (s);
226
- return s;
115
+ char szRet[40 ];
116
+ snprintf (szRet, sizeof (szRet), " %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" ,
117
+ _address.bytes [0 ], _address.bytes [1 ], _address.bytes [2 ], _address.bytes [3 ],
118
+ _address.bytes [4 ], _address.bytes [5 ], _address.bytes [6 ], _address.bytes [7 ],
119
+ _address.bytes [8 ], _address.bytes [9 ], _address.bytes [10 ], _address.bytes [11 ],
120
+ _address.bytes [12 ], _address.bytes [13 ], _address.bytes [14 ], _address.bytes [15 ]);
121
+ return String (szRet);
227
122
}
228
123
229
124
String IPAddress::toString () const
@@ -235,10 +130,8 @@ String IPAddress::toString() const
235
130
}
236
131
}
237
132
238
- bool IPAddress::fromString (const char *address)
239
- {
240
- if (!fromString4 (address))
241
- {
133
+ bool IPAddress::fromString (const char *address) {
134
+ if (!fromString4 (address)) {
242
135
return fromString6 (address);
243
136
}
244
137
return true ;
@@ -336,6 +229,12 @@ bool IPAddress::fromString6(const char *address) {
336
229
colons++;
337
230
acc = 0 ;
338
231
}
232
+ else if (c == ' %' ) {
233
+ _zone = netif_name_to_index (address);
234
+ while (*address != ' \0 ' ){
235
+ address++;
236
+ }
237
+ }
339
238
else
340
239
// Invalid char
341
240
return false ;
@@ -364,5 +263,144 @@ bool IPAddress::fromString6(const char *address) {
364
263
return true ;
365
264
}
366
265
367
- // declared one time - as external in IPAddress.h
368
- IPAddress INADDR_NONE (0 , 0 , 0 , 0 );
266
+ IPAddress& IPAddress::operator =(const uint8_t *address)
267
+ {
268
+ // IPv4 only conversion from byte pointer
269
+ _type = IPv4;
270
+ memset (_address.bytes , 0 , sizeof (_address.bytes ));
271
+ memcpy (&_address.bytes [IPADDRESS_V4_BYTES_INDEX], address, sizeof (uint32_t ));
272
+ return *this ;
273
+ }
274
+
275
+ IPAddress& IPAddress::operator =(const char *address)
276
+ {
277
+ fromString (address);
278
+ return *this ;
279
+ }
280
+
281
+ IPAddress& IPAddress::operator =(uint32_t address)
282
+ {
283
+ // IPv4 conversion
284
+ // See note on conversion/comparison and uint32_t
285
+ _type = IPv4;
286
+ memset (_address.bytes , 0 , sizeof (_address.bytes ));
287
+ _address.dword [IPADDRESS_V4_DWORD_INDEX] = address;
288
+ return *this ;
289
+ }
290
+
291
+ IPAddress& IPAddress::operator =(const IPAddress& address){
292
+ _type = address.type ();
293
+ _zone = address.zone ();
294
+ memcpy (_address.bytes , address._address .bytes , sizeof (_address.bytes ));
295
+ return *this ;
296
+ }
297
+
298
+ bool IPAddress::operator ==(const IPAddress& addr) const {
299
+ return (addr._type == _type)
300
+ && (memcmp (addr._address .bytes , _address.bytes , sizeof (_address.bytes )) == 0 );
301
+ }
302
+
303
+ bool IPAddress::operator ==(const uint8_t * addr) const
304
+ {
305
+ // IPv4 only comparison to byte pointer
306
+ // Can't support IPv6 as we know our type, but not the length of the pointer
307
+ return _type == IPv4 && memcmp (addr, &_address.bytes [IPADDRESS_V4_BYTES_INDEX], sizeof (uint32_t )) == 0 ;
308
+ }
309
+
310
+ uint8_t IPAddress::operator [](int index) const {
311
+ if (_type == IPv4) {
312
+ return _address.bytes [IPADDRESS_V4_BYTES_INDEX + index];
313
+ }
314
+ return _address.bytes [index];
315
+ }
316
+
317
+ uint8_t & IPAddress::operator [](int index) {
318
+ if (_type == IPv4) {
319
+ return _address.bytes [IPADDRESS_V4_BYTES_INDEX + index];
320
+ }
321
+ return _address.bytes [index];
322
+ }
323
+
324
+ size_t IPAddress::printTo (Print& p) const
325
+ {
326
+ size_t n = 0 ;
327
+
328
+ if (_type == IPv6) {
329
+ // IPv6 IETF canonical format: compress left-most longest run of two or more zero fields, lower case
330
+ int8_t longest_start = -1 ;
331
+ int8_t longest_length = 1 ;
332
+ int8_t current_start = -1 ;
333
+ int8_t current_length = 0 ;
334
+ for (int8_t f = 0 ; f < 8 ; f++) {
335
+ if (_address.bytes [f * 2 ] == 0 && _address.bytes [f * 2 + 1 ] == 0 ) {
336
+ if (current_start == -1 ) {
337
+ current_start = f;
338
+ current_length = 1 ;
339
+ } else {
340
+ current_length++;
341
+ }
342
+ if (current_length > longest_length) {
343
+ longest_start = current_start;
344
+ longest_length = current_length;
345
+ }
346
+ } else {
347
+ current_start = -1 ;
348
+ }
349
+ }
350
+ for (int f = 0 ; f < 8 ; f++) {
351
+ if (f < longest_start || f >= longest_start + longest_length) {
352
+ uint8_t c1 = _address.bytes [f * 2 ] >> 4 ;
353
+ uint8_t c2 = _address.bytes [f * 2 ] & 0xf ;
354
+ uint8_t c3 = _address.bytes [f * 2 + 1 ] >> 4 ;
355
+ uint8_t c4 = _address.bytes [f * 2 + 1 ] & 0xf ;
356
+ if (c1 > 0 ) {
357
+ n += p.print ((char )(c1 < 10 ? ' 0' + c1 : ' a' + c1 - 10 ));
358
+ }
359
+ if (c1 > 0 || c2 > 0 ) {
360
+ n += p.print ((char )(c2 < 10 ? ' 0' + c2 : ' a' + c2 - 10 ));
361
+ }
362
+ if (c1 > 0 || c2 > 0 || c3 > 0 ) {
363
+ n += p.print ((char )(c3 < 10 ? ' 0' + c3 : ' a' + c3 - 10 ));
364
+ }
365
+ n += p.print ((char )(c4 < 10 ? ' 0' + c4 : ' a' + c4 - 10 ));
366
+ if (f < 7 ) {
367
+ n += p.print (' :' );
368
+ }
369
+ } else if (f == longest_start) {
370
+ if (longest_start == 0 ) {
371
+ n += p.print (' :' );
372
+ }
373
+ n += p.print (' :' );
374
+ }
375
+ }
376
+ return n;
377
+ }
378
+
379
+ // IPv4
380
+ for (int i =0 ; i < 3 ; i++)
381
+ {
382
+ n += p.print (_address.bytes [IPADDRESS_V4_BYTES_INDEX + i], DEC);
383
+ n += p.print (' .' );
384
+ }
385
+ n += p.print (_address.bytes [IPADDRESS_V4_BYTES_INDEX + 3 ], DEC);
386
+ return n;
387
+ }
388
+
389
+ void IPAddress::to_ip_addr_t (ip_addr_t * addr){
390
+ if (_type == IPv6){
391
+ addr->type = IPADDR_TYPE_V6;
392
+ addr->u_addr .ip6 .addr [0 ] = _address.dword [0 ];
393
+ addr->u_addr .ip6 .addr [1 ] = _address.dword [1 ];
394
+ addr->u_addr .ip6 .addr [2 ] = _address.dword [2 ];
395
+ addr->u_addr .ip6 .addr [3 ] = _address.dword [3 ];
396
+ #if LWIP_IPV6_SCOPES
397
+ addr->u_addr .ip6 .zone = _zone;
398
+ #endif /* LWIP_IPV6_SCOPES */
399
+ } else {
400
+ addr->type = IPADDR_TYPE_V4;
401
+ addr->u_addr .ip4 .addr = _address.dword [IPADDRESS_V4_DWORD_INDEX];
402
+ }
403
+ }
404
+
405
+ const IPAddress IN6ADDR_ANY (IPv6);
406
+ const IPAddress INADDR_NONE (0 ,0 ,0 ,0 );
0 commit comments