Skip to content

Commit 5706879

Browse files
committed
Add IPv6 tests, and fix issues
1 parent d7d6fe7 commit 5706879

File tree

5 files changed

+672
-16
lines changed

5 files changed

+672
-16
lines changed

api/IPAddress.cpp

+52-16
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_oc
4040
_address.bytes[15] = fourth_octet;
4141
}
4242

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+
4363
IPAddress::IPAddress(uint32_t address)
4464
{
4565
// IPv4 only
@@ -135,7 +155,7 @@ bool IPAddress::fromString6(const char *address) {
135155
while (*address)
136156
{
137157
char c = tolower(*address++);
138-
if (isalnum(c)) {
158+
if (isalnum(c) && c <= 'f') {
139159
if (c >= 'a')
140160
c -= 'a' - '0' - 10;
141161
acc = acc * 16 + (c - '0');
@@ -145,18 +165,26 @@ bool IPAddress::fromString6(const char *address) {
145165
}
146166
else if (c == ':') {
147167
if (*address == ':') {
148-
if (doubledots >= 0)
168+
if (doubledots >= 0) {
149169
// :: allowed once
150170
return false;
171+
}
172+
if (*address != '\0' && *(address + 1) == ':') {
173+
// ::: not allowed
174+
return false;
175+
}
151176
// remember location
152177
doubledots = dots + !!acc;
153178
address++;
179+
} else if (*address == '\0') {
180+
// can't end with a single colon
181+
return false;
154182
}
155183
if (dots == 7)
156184
// too many separators
157185
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;
160188
dots++;
161189
acc = 0;
162190
}
@@ -165,11 +193,16 @@ bool IPAddress::fromString6(const char *address) {
165193
return false;
166194
}
167195

168-
if (doubledots == -1 && dots != 7)
196+
if (doubledots == -1 && dots != 7) {
169197
// Too few separators
170198
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;
173206
dots++;
174207

175208
if (doubledots != -1) {
@@ -235,16 +268,16 @@ size_t IPAddress::printTo(Print& p) const
235268
size_t n = 0;
236269

237270
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
239272
int8_t longest_start = -1;
240-
int8_t longest_length = 0;
273+
int8_t longest_length = 1;
241274
int8_t current_start = -1;
242275
int8_t current_length = 0;
243276
for (int8_t f = 0; f < 8; f++) {
244277
if (_address.bytes[f * 2] == 0 && _address.bytes[f * 2 + 1] == 0) {
245278
if (current_start == -1) {
246279
current_start = f;
247-
current_length = 0;
280+
current_length = 1;
248281
} else {
249282
current_length++;
250283
}
@@ -258,24 +291,27 @@ size_t IPAddress::printTo(Print& p) const
258291
}
259292
for (int f = 0; f < 8; f++) {
260293
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;
262295
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;
264297
uint8_t c4 = _address.bytes[f * 2 + 1] & 0xf;
265298
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));
267300
}
268301
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));
270303
}
271304
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));
273306
}
274-
n += p.print(c4 < 10 ? '0' + c4 : 'a' + c4 - 10);
307+
n += p.print((char)(c4 < 10 ? '0' + c4 : 'a' + c4 - 10));
275308
if (f < 7) {
276309
n += p.print(':');
277310
}
278311
} else if (f == longest_start) {
312+
if (longest_start == 0) {
313+
n += p.print(':');
314+
}
279315
n += p.print(':');
280316
}
281317
}

test/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ set(TEST_SRCS
3030
src/Common/test_max.cpp
3131
src/Common/test_min.cpp
3232
src/IPAddress/test_fromString.cpp
33+
src/IPAddress/test_fromString6.cpp
3334
src/IPAddress/test_IPAddress.cpp
35+
src/IPAddress/test_IPAddress6.cpp
3436
src/IPAddress/test_operator_assignment.cpp
3537
src/IPAddress/test_operator_comparison.cpp
3638
src/IPAddress/test_operator_parentheses.cpp
3739
src/IPAddress/test_printTo.cpp
40+
src/IPAddress/test_printTo6.cpp
3841
src/Print/test_clearWriteError.cpp
3942
src/Print/test_getWriteError.cpp
4043
src/Print/test_print.cpp
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2020 Arduino. All rights reserved.
3+
*/
4+
5+
/**************************************************************************************
6+
* INCLUDE
7+
**************************************************************************************/
8+
9+
#include <catch.hpp>
10+
11+
#include <IPAddress.h>
12+
13+
/**************************************************************************************
14+
* TEST CODE
15+
**************************************************************************************/
16+
17+
TEST_CASE ("Testing IPAddress(type) constructor()", "[IPAddress6-Ctor-01]")
18+
{
19+
arduino::IPAddress ip (arduino::IPType::IPv6);
20+
21+
REQUIRE(ip.type() == arduino::IPType::IPv6);
22+
REQUIRE(ip[0] == 0);
23+
REQUIRE(ip[1] == 0);
24+
REQUIRE(ip[2] == 0);
25+
REQUIRE(ip[3] == 0);
26+
REQUIRE(ip[4] == 0);
27+
REQUIRE(ip[5] == 0);
28+
REQUIRE(ip[6] == 0);
29+
REQUIRE(ip[7] == 0);
30+
REQUIRE(ip[8] == 0);
31+
REQUIRE(ip[9] == 0);
32+
REQUIRE(ip[10] == 0);
33+
REQUIRE(ip[11] == 0);
34+
REQUIRE(ip[12] == 0);
35+
REQUIRE(ip[13] == 0);
36+
REQUIRE(ip[14] == 0);
37+
REQUIRE(ip[15] == 0);
38+
}
39+
40+
TEST_CASE ("Testing IPAddress(o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o) constructor", "[IPAddress-Ctor6-02]")
41+
{
42+
arduino::IPAddress ip(0x20,0x01, 0xd,0xb8, 1,2, 3,4, 5,6, 7,8, 9,0xa, 0xb,0xc);
43+
44+
REQUIRE(ip.type() == arduino::IPType::IPv6);
45+
REQUIRE(ip[0] == 0x20);
46+
REQUIRE(ip[1] == 0x01);
47+
REQUIRE(ip[2] == 0xd);
48+
REQUIRE(ip[3] == 0xb8);
49+
REQUIRE(ip[4] == 1);
50+
REQUIRE(ip[5] == 2);
51+
REQUIRE(ip[6] == 3);
52+
REQUIRE(ip[7] == 4);
53+
REQUIRE(ip[8] == 5);
54+
REQUIRE(ip[9] == 6);
55+
REQUIRE(ip[10] == 7);
56+
REQUIRE(ip[11] == 8);
57+
REQUIRE(ip[12] == 9);
58+
REQUIRE(ip[13] == 0xa);
59+
REQUIRE(ip[14] == 0xb);
60+
REQUIRE(ip[15] == 0xc);
61+
}
62+
63+
TEST_CASE ("Testing IPAddress(type, a *) constructor", "[IPAddress6-Ctor-03]")
64+
{
65+
uint8_t const ip_addr_array[] = {0x20,0x01, 0xd,0xb8, 1,2, 3,4, 5,6, 7,8, 9,0xa, 0xb,0xc};
66+
arduino::IPAddress ip(arduino::IPType::IPv6, ip_addr_array);
67+
68+
REQUIRE(ip.type() == arduino::IPType::IPv6);
69+
REQUIRE(ip[0] == 0x20);
70+
REQUIRE(ip[1] == 0x01);
71+
REQUIRE(ip[2] == 0xd);
72+
REQUIRE(ip[3] == 0xb8);
73+
REQUIRE(ip[4] == 1);
74+
REQUIRE(ip[5] == 2);
75+
REQUIRE(ip[6] == 3);
76+
REQUIRE(ip[7] == 4);
77+
REQUIRE(ip[8] == 5);
78+
REQUIRE(ip[9] == 6);
79+
REQUIRE(ip[10] == 7);
80+
REQUIRE(ip[11] == 8);
81+
REQUIRE(ip[12] == 9);
82+
REQUIRE(ip[13] == 0xa);
83+
REQUIRE(ip[14] == 0xb);
84+
REQUIRE(ip[15] == 0xc);
85+
}

0 commit comments

Comments
 (0)