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 " IPAddress.h"
21
- #include " Print.h"
20
+ #include < Arduino.h>
21
+ #include < IPAddress.h>
22
+ #include < Print.h>
22
23
23
- using namespace arduino ;
24
-
25
- IPAddress::IPAddress ()
24
+ IPAddress::IPAddress (const IPAddress& from)
26
25
{
27
- _address. dword = 0 ;
26
+ ip_addr_copy (_ip, from. _ip ) ;
28
27
}
29
28
30
- IPAddress::IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
31
- {
32
- _address.bytes [0 ] = first_octet;
33
- _address.bytes [1 ] = second_octet;
34
- _address.bytes [2 ] = third_octet;
35
- _address.bytes [3 ] = fourth_octet;
29
+ IPAddress::IPAddress () {
30
+ _ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address
36
31
}
37
32
38
- IPAddress::IPAddress (uint32_t address)
39
- {
40
- _address.dword = address;
33
+ bool IPAddress::isSet () const {
34
+ return !ip_addr_isany (&_ip) && ((*this ) != IPADDR_NONE);
41
35
}
42
36
43
- IPAddress::IPAddress (const uint8_t *address)
44
- {
45
- memcpy (_address.bytes , address, sizeof (_address.bytes ));
37
+ IPAddress::IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) {
38
+ setV4 ();
39
+ (*this )[0 ] = first_octet;
40
+ (*this )[1 ] = second_octet;
41
+ (*this )[2 ] = third_octet;
42
+ (*this )[3 ] = fourth_octet;
46
43
}
47
44
48
- bool IPAddress::fromString (const char *address)
49
- {
50
- // TODO: add support for "a", "a.b", "a.b.c" formats
45
+ void IPAddress::ctor32 (uint32_t address) {
46
+ setV4 ();
47
+ v4 () = address;
48
+ }
49
+
50
+ IPAddress::IPAddress (const uint8_t *address) {
51
+ setV4 ();
52
+ (*this )[0 ] = address[0 ];
53
+ (*this )[1 ] = address[1 ];
54
+ (*this )[2 ] = address[2 ];
55
+ (*this )[3 ] = address[3 ];
56
+ }
57
+
58
+ bool IPAddress::fromString (const char *address) {
59
+ if (!fromString4 (address)) {
60
+ #if LWIP_IPV6
61
+ return fromString6 (address);
62
+ #else
63
+ return false ;
64
+ #endif
65
+ }
66
+ return true ;
67
+ }
68
+
69
+ bool IPAddress::fromString4 (const char *address) {
70
+ // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats
51
71
52
- int16_t acc = - 1 ; // Accumulator
72
+ uint16_t acc = 0 ; // Accumulator
53
73
uint8_t dots = 0 ;
54
74
55
75
while (*address)
56
76
{
57
77
char c = *address++;
58
78
if (c >= ' 0' && c <= ' 9' )
59
79
{
60
- acc = (acc < 0 ) ? (c - ' 0 ' ) : acc * 10 + (c - ' 0' );
80
+ acc = acc * 10 + (c - ' 0' );
61
81
if (acc > 255 ) {
62
82
// Value out of [0..255] range
63
83
return false ;
@@ -69,12 +89,8 @@ bool IPAddress::fromString(const char *address)
69
89
// Too much dots (there must be 3 dots)
70
90
return false ;
71
91
}
72
- if (acc < 0 ) {
73
- /* No value between dots, e.g. '1..' */
74
- return false ;
75
- }
76
- _address.bytes [dots++] = acc;
77
- acc = -1 ;
92
+ (*this )[dots++] = acc;
93
+ acc = 0 ;
78
94
}
79
95
else
80
96
{
@@ -87,41 +103,146 @@ bool IPAddress::fromString(const char *address)
87
103
// Too few dots (there must be 3 dots)
88
104
return false ;
89
105
}
90
- if (acc < 0 ) {
91
- /* No value between dots, e.g. '1..' */
92
- return false ;
93
- }
94
- _address.bytes [3 ] = acc;
106
+ (*this )[3 ] = acc;
107
+
108
+ setV4 ();
95
109
return true ;
96
110
}
97
111
98
- IPAddress& IPAddress::operator =(const uint8_t *address)
99
- {
100
- memcpy (_address. bytes , address, sizeof (_address. bytes ) );
112
+ IPAddress& IPAddress::operator =(const uint8_t *address) {
113
+ setV4 ();
114
+ v4 () = * reinterpret_cast < const uint32_t *>(address );
101
115
return *this ;
102
116
}
103
117
104
- IPAddress& IPAddress::operator =(uint32_t address)
105
- {
106
- _address. dword = address;
118
+ IPAddress& IPAddress::operator =(uint32_t address) {
119
+ setV4 ();
120
+ v4 () = address;
107
121
return *this ;
108
122
}
109
123
110
- bool IPAddress::operator ==(const uint8_t * addr) const
111
- {
112
- return memcmp (addr, _address.bytes , sizeof (_address.bytes )) == 0 ;
124
+ bool IPAddress::operator ==(const uint8_t * addr) const {
125
+ return isV4 () && v4 () == *reinterpret_cast <const uint32_t *>(addr);
126
+ }
127
+
128
+ size_t IPAddress::printTo (Print& p) const {
129
+ String s = toString ();
130
+ return p.print (s);
113
131
}
114
132
115
- size_t IPAddress::printTo (Print& p ) const
133
+ String IPAddress::toString ( ) const
116
134
{
117
- size_t n = 0 ;
118
- for (int i =0 ; i < 3 ; i++)
135
+ String s;
136
+
137
+ if (!isSet ())
138
+ return " (IP unset)" ;
139
+
140
+ #if LWIP_IPV6
141
+ if (isV6 ()) {
142
+ int count0 = 0 ;
143
+ for (int i = 0 ; i < 8 ; i++) {
144
+ uint16_t bit = PP_NTOHS (raw6 ()[i]);
145
+ if (bit || count0 < 0 ) {
146
+ char buff[64 ];
147
+ snprintf (buff, 64 , " %x" , bit);
148
+ buff[63 ] = 0 ;
149
+ s += buff;
150
+ if (count0 > 0 )
151
+ // no more hiding 0
152
+ count0 = -8 ;
153
+ } else
154
+ count0++;
155
+ if ((i != 7 && count0 < 2 ) || count0 == 7 )
156
+ s += ' :' ;
157
+ }
158
+ return s;
159
+ }
160
+ #endif
161
+
162
+ for (int i = 0 ; i < 4 ; i++) {
163
+ char buff[16 ];
164
+ snprintf (buff, 16 , " %d" , (*this )[i]);
165
+ buff[15 ] = 0 ;
166
+ s += buff;
167
+ if (i != 3 )
168
+ s += ' .' ;
169
+ }
170
+ return s;
171
+
172
+ }
173
+
174
+ bool IPAddress::isValid (const String& arg) {
175
+ return IPAddress ().fromString (arg);
176
+ }
177
+
178
+ bool IPAddress::isValid (const char * arg) {
179
+ return IPAddress ().fromString (arg);
180
+ }
181
+
182
+ namespace arduino {
183
+ const IPAddress INADDR_ANY; // generic "0.0.0.0" for IPv4 & IPv6
184
+ const IPAddress INADDR_NONE (255 ,255 ,255 ,255 );
185
+ };
186
+
187
+ void IPAddress::clear () {
188
+ (*this ) = INADDR_ANY;
189
+ }
190
+
191
+ /* *************************************/
192
+
193
+ #if LWIP_IPV6
194
+
195
+ bool IPAddress::fromString6 (const char *address) {
196
+ // TODO: test test test
197
+
198
+ uint32_t acc = 0 ; // Accumulator
199
+ int dots = 0 , doubledots = -1 ;
200
+
201
+ while (*address)
119
202
{
120
- n += p.print (_address.bytes [i], DEC);
121
- n += p.print (' .' );
203
+ char c = tolower (*address++);
204
+ if (isalnum (c)) {
205
+ if (c >= ' a' )
206
+ c -= ' a' - ' 0' - 10 ;
207
+ acc = acc * 16 + (c - ' 0' );
208
+ if (acc > 0xffff )
209
+ // Value out of range
210
+ return false ;
211
+ }
212
+ else if (c == ' :' ) {
213
+ if (*address == ' :' ) {
214
+ if (doubledots >= 0 )
215
+ // :: allowed once
216
+ return false ;
217
+ // remember location
218
+ doubledots = dots + !!acc;
219
+ address++;
220
+ }
221
+ if (dots == 7 )
222
+ // too many separators
223
+ return false ;
224
+ raw6 ()[dots++] = PP_HTONS (acc);
225
+ acc = 0 ;
226
+ }
227
+ else
228
+ // Invalid char
229
+ return false ;
122
230
}
123
- n += p.print (_address.bytes [3 ], DEC);
124
- return n;
231
+
232
+ if (doubledots == -1 && dots != 7 )
233
+ // Too few separators
234
+ return false ;
235
+ raw6 ()[dots++] = PP_HTONS (acc);
236
+
237
+ if (doubledots != -1 ) {
238
+ for (int i = dots - doubledots - 1 ; i >= 0 ; i--)
239
+ raw6 ()[8 - dots + doubledots + i] = raw6 ()[doubledots + i];
240
+ for (int i = doubledots; i < 8 - dots + doubledots; i++)
241
+ raw6 ()[i] = 0 ;
242
+ }
243
+
244
+ setV6 ();
245
+ return true ;
125
246
}
126
247
127
- const IPAddress arduino::INADDR_NONE ( 0 , 0 , 0 , 0 );
248
+ # endif
0 commit comments