@@ -40,6 +40,26 @@ IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_oc
40
40
_address.bytes [15 ] = fourth_octet;
41
41
}
42
42
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
+ _type = IPv6;
45
+ _address.bytes [0 ] = o1;
46
+ _address.bytes [1 ] = o2;
47
+ _address.bytes [2 ] = o3;
48
+ _address.bytes [3 ] = o4;
49
+ _address.bytes [4 ] = o5;
50
+ _address.bytes [5 ] = o6;
51
+ _address.bytes [6 ] = o7;
52
+ _address.bytes [7 ] = o8;
53
+ _address.bytes [8 ] = o9;
54
+ _address.bytes [9 ] = o10;
55
+ _address.bytes [10 ] = o11;
56
+ _address.bytes [11 ] = o12;
57
+ _address.bytes [12 ] = o13;
58
+ _address.bytes [13 ] = o14;
59
+ _address.bytes [14 ] = o15;
60
+ _address.bytes [15 ] = o16;
61
+ }
62
+
43
63
IPAddress::IPAddress (uint32_t address)
44
64
{
45
65
// IPv4 only
@@ -135,7 +155,7 @@ bool IPAddress::fromString6(const char *address) {
135
155
while (*address)
136
156
{
137
157
char c = tolower (*address++);
138
- if (isalnum (c)) {
158
+ if (isalnum (c) && c <= ' f ' ) {
139
159
if (c >= ' a' )
140
160
c -= ' a' - ' 0' - 10 ;
141
161
acc = acc * 16 + (c - ' 0' );
@@ -145,18 +165,26 @@ bool IPAddress::fromString6(const char *address) {
145
165
}
146
166
else if (c == ' :' ) {
147
167
if (*address == ' :' ) {
148
- if (doubledots >= 0 )
168
+ if (doubledots >= 0 ) {
149
169
// :: allowed once
150
170
return false ;
171
+ }
172
+ if (*address != ' \0 ' && *(address + 1 ) == ' :' ) {
173
+ // ::: not allowed
174
+ return false ;
175
+ }
151
176
// remember location
152
177
doubledots = dots + !!acc;
153
178
address++;
179
+ } else if (*address == ' \0 ' ) {
180
+ // can't end with a single colon
181
+ return false ;
154
182
}
155
183
if (dots == 7 )
156
184
// too many separators
157
185
return false ;
158
- _address.bytes [dots] = acc >> 2 ;
159
- _address.bytes [dots + 1 ] = acc & 0xff ;
186
+ _address.bytes [dots * 2 ] = acc >> 8 ;
187
+ _address.bytes [dots * 2 + 1 ] = acc & 0xff ;
160
188
dots++;
161
189
acc = 0 ;
162
190
}
@@ -165,11 +193,16 @@ bool IPAddress::fromString6(const char *address) {
165
193
return false ;
166
194
}
167
195
168
- if (doubledots == -1 && dots != 7 )
196
+ if (doubledots == -1 && dots != 7 ) {
169
197
// Too few separators
170
198
return false ;
171
- _address.bytes [dots] = acc >> 2 ;
172
- _address.bytes [dots + 1 ] = acc & 0xff ;
199
+ }
200
+ if (doubledots > -1 && dots > 6 ) {
201
+ // Too many segments
202
+ return false ;
203
+ }
204
+ _address.bytes [dots * 2 ] = acc >> 8 ;
205
+ _address.bytes [dots * 2 + 1 ] = acc & 0xff ;
173
206
dots++;
174
207
175
208
if (doubledots != -1 ) {
@@ -235,16 +268,16 @@ size_t IPAddress::printTo(Print& p) const
235
268
size_t n = 0 ;
236
269
237
270
if (_type == IPv6) {
238
- // IPv6 IETF canonical format: left-most longest run of all zero fields, lower case
271
+ // IPv6 IETF canonical format: compress left-most longest run of two or more zero fields, lower case
239
272
int8_t longest_start = -1 ;
240
- int8_t longest_length = 0 ;
273
+ int8_t longest_length = 1 ;
241
274
int8_t current_start = -1 ;
242
275
int8_t current_length = 0 ;
243
276
for (int8_t f = 0 ; f < 8 ; f++) {
244
277
if (_address.bytes [f * 2 ] == 0 && _address.bytes [f * 2 + 1 ] == 0 ) {
245
278
if (current_start == -1 ) {
246
279
current_start = f;
247
- current_length = 0 ;
280
+ current_length = 1 ;
248
281
} else {
249
282
current_length++;
250
283
}
@@ -258,24 +291,27 @@ size_t IPAddress::printTo(Print& p) const
258
291
}
259
292
for (int f = 0 ; f < 8 ; f++) {
260
293
if (f < longest_start || f >= longest_start + longest_length) {
261
- uint8_t c1 = _address.bytes [f * 2 ] >> 1 ;
294
+ uint8_t c1 = _address.bytes [f * 2 ] >> 4 ;
262
295
uint8_t c2 = _address.bytes [f * 2 ] & 0xf ;
263
- uint8_t c3 = _address.bytes [f * 2 + 1 ] >> 1 ;
296
+ uint8_t c3 = _address.bytes [f * 2 + 1 ] >> 4 ;
264
297
uint8_t c4 = _address.bytes [f * 2 + 1 ] & 0xf ;
265
298
if (c1 > 0 ) {
266
- n += p.print (c1 < 10 ? ' 0' + c1 : ' a' + c1 - 10 );
299
+ n += p.print (( char )( c1 < 10 ? ' 0' + c1 : ' a' + c1 - 10 ) );
267
300
}
268
301
if (c1 > 0 || c2 > 0 ) {
269
- n += p.print (c2 < 10 ? ' 0' + c2 : ' a' + c2 - 10 );
302
+ n += p.print (( char )( c2 < 10 ? ' 0' + c2 : ' a' + c2 - 10 ) );
270
303
}
271
304
if (c1 > 0 || c2 > 0 || c3 > 0 ) {
272
- n += p.print (c3 < 10 ? ' 0' + c3 : ' a' + c3 - 10 );
305
+ n += p.print (( char )( c3 < 10 ? ' 0' + c3 : ' a' + c3 - 10 ) );
273
306
}
274
- n += p.print (c4 < 10 ? ' 0' + c4 : ' a' + c4 - 10 );
307
+ n += p.print (( char )( c4 < 10 ? ' 0' + c4 : ' a' + c4 - 10 ) );
275
308
if (f < 7 ) {
276
309
n += p.print (' :' );
277
310
}
278
311
} else if (f == longest_start) {
312
+ if (longest_start == 0 ) {
313
+ n += p.print (' :' );
314
+ }
279
315
n += p.print (' :' );
280
316
}
281
317
}
0 commit comments