Compare commits

...

5 Commits

Author SHA1 Message Date
William Skellenger
95c7c731c0 fix typos, test runs 2024-06-07 16:00:09 -04:00
William Skellenger
21c970c1b5 fix c++ comments 2024-06-07 15:44:44 -04:00
William Skellenger
748cd807c7 more broken test cases for ipv6 2024-06-07 15:40:31 -04:00
William Skellenger
2a29247081 test passing 2024-06-07 13:54:46 -04:00
William Skellenger
5da7e95fa9 block with five characters is now handled correctly 2024-06-07 13:40:15 -04:00
2 changed files with 74 additions and 1 deletions

View File

@ -57,6 +57,8 @@
/* used by IP6_ADDR_ANY(6) in ip6_addr.h */ /* used by IP6_ADDR_ANY(6) in ip6_addr.h */
const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul); const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul);
#define SMALLEST_POSSIBLE_IPV6_STRLEN 2 /* "::" is the smallest possible ipv6 address */
#define lwip_xchar(i) ((char)((i) < 10 ? '0' + (i) : 'A' + (i) - 10)) #define lwip_xchar(i) ((char)((i) < 10 ? '0' + (i) : 'A' + (i) - 10))
/** /**
@ -71,18 +73,40 @@ const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul);
int int
ip6addr_aton(const char *cp, ip6_addr_t *addr) ip6addr_aton(const char *cp, ip6_addr_t *addr)
{ {
u32_t addr_index, zero_blocks, current_block_index, current_block_value; u32_t addr_index, current_block_index, current_block_value, double_colon_found;
s32_t zero_blocks;
size_t len;
const char *s; const char *s;
int block_length;
#if LWIP_IPV4 #if LWIP_IPV4
int check_ipv4_mapped = 0; int check_ipv4_mapped = 0;
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
if (!cp) {
return 0;
}
len = strlen(cp);
if (len < SMALLEST_POSSIBLE_IPV6_STRLEN) {
return 0;
}
/* if last character is a colon but not a double colon, invalid */
if ((cp[len-1] == ':') && (cp[len-2] != ':')) {
return 0;
}
/* Count the number of colons, to count the number of blocks in a "::" sequence /* Count the number of colons, to count the number of blocks in a "::" sequence
zero_blocks may be 1 even if there are no :: sequences */ zero_blocks may be 1 even if there are no :: sequences */
zero_blocks = 8; zero_blocks = 8;
double_colon_found = 0;
for (s = cp; *s != 0; s++) { for (s = cp; *s != 0; s++) {
if (*s == ':') { if (*s == ':') {
zero_blocks--; zero_blocks--;
if (s[1] == ':') {
double_colon_found = 1;
}
#if LWIP_IPV4 #if LWIP_IPV4
} else if (*s == '.') { } else if (*s == '.') {
if ((zero_blocks == 5) ||(zero_blocks == 2)) { if ((zero_blocks == 5) ||(zero_blocks == 2)) {
@ -100,12 +124,21 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
} }
} }
/* we found a double colon but it is impossible to populate it */
if (double_colon_found && zero_blocks <= 0) {
return 0;
}
/* parse each block */ /* parse each block */
addr_index = 0; addr_index = 0;
current_block_index = 0; current_block_index = 0;
current_block_value = 0; current_block_value = 0;
block_length = 0;
for (s = cp; *s != 0; s++) { for (s = cp; *s != 0; s++) {
if (*s == ':') { if (*s == ':') {
if (block_length > 4) {
return 0; /* invalid block length */
}
if (addr) { if (addr) {
if (current_block_index & 0x1) { if (current_block_index & 0x1) {
addr->addr[addr_index++] |= current_block_value; addr->addr[addr_index++] |= current_block_value;
@ -132,6 +165,7 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
} }
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
current_block_value = 0; current_block_value = 0;
block_length = 0;
if (current_block_index > 7) { if (current_block_index > 7) {
/* address too long! */ /* address too long! */
return 0; return 0;
@ -160,6 +194,10 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
} }
} }
} else if (lwip_isxdigit(*s)) { } else if (lwip_isxdigit(*s)) {
if (block_length == 4) {
return 0; /* invalid block length */
}
block_length++;
/* add current digit */ /* add current digit */
current_block_value = (current_block_value << 4) + current_block_value = (current_block_value << 4) +
(lwip_isdigit(*s) ? (u32_t)(*s - '0') : (lwip_isdigit(*s) ? (u32_t)(*s - '0') :
@ -170,6 +208,10 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
} }
} }
if (block_length > 4) {
return 0; /* invalid block length */
}
if (addr) { if (addr) {
if (current_block_index & 0x1) { if (current_block_index & 0x1) {
addr->addr[addr_index++] |= current_block_value; addr->addr[addr_index++] |= current_block_value;

View File

@ -203,6 +203,12 @@ START_TEST(test_ip6_aton_ipv4mapped)
const char *full_ipv4_mapped_addr = "0:0:0:0:0:FFFF:212.204.101.210"; const char *full_ipv4_mapped_addr = "0:0:0:0:0:FFFF:212.204.101.210";
const char *shortened_ipv4_mapped_addr = "::FFFF:212.204.101.210"; const char *shortened_ipv4_mapped_addr = "::FFFF:212.204.101.210";
const char *bogus_ipv4_mapped_addr = "::FFFF:212.204.101.2101"; const char *bogus_ipv4_mapped_addr = "::FFFF:212.204.101.2101";
const char *ipv6_block_too_long = "1234:5678:9aBc:acDef:1122:3344:5566:7788";
const char *ipv6_trailing_single_colon = "fE80::1:";
const char *ipv6_impossible_compression1 = "1234:5678:9aBc::cDef:1122:3344:5566:7788";
const char *ipv6_impossible_compression2 = "1234:5678:9aBc:cDef:1122:3344:5566:7788::";
const char *ipv6_valid_compression = "fE80::1:1";
LWIP_UNUSED_ARG(_i); LWIP_UNUSED_ARG(_i);
/* check IPv6 representation */ /* check IPv6 representation */
@ -262,6 +268,31 @@ START_TEST(test_ip6_aton_ipv4mapped)
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
ret = ipaddr_aton(bogus_ipv4_mapped_addr, &addr); ret = ipaddr_aton(bogus_ipv4_mapped_addr, &addr);
fail_unless(ret == 0); fail_unless(ret == 0);
/* checking incorrect representation with a block containing 5 characters */
memset(&addr6, 0, sizeof(addr6));
ret = ip6addr_aton(ipv6_block_too_long, &addr6);
fail_unless(ret == 0);
/* trailing single colon, invalid */
memset(&addr6, 0, sizeof(addr6));
ret = ip6addr_aton(ipv6_trailing_single_colon, &addr6);
fail_unless(ret == 0);
/* impossible to support compression, already enough blocks, invalid */
memset(&addr6, 0, sizeof(addr6));
ret = ip6addr_aton(ipv6_impossible_compression1, &addr6);
fail_unless(ret == 0);
/* impossible to support compression at the end of the address, already enough blocks, invalid */
memset(&addr6, 0, sizeof(addr6));
ret = ip6addr_aton(ipv6_impossible_compression2, &addr6);
fail_unless(ret == 0);
/* valid ipv6 with compression */
memset(&addr6, 0, sizeof(addr6));
ret = ip6addr_aton(ipv6_valid_compression, &addr6);
fail_unless(ret == 1);
} }
END_TEST END_TEST