mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-09-28 23:00:50 +00:00
Merge 95c7c731c0
into 86c9f79991
This commit is contained in:
commit
da5f0531ef
@ -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)) {
|
||||||
@ -96,16 +120,25 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
|
|||||||
break;
|
break;
|
||||||
#endif /* LWIP_IPV4 */
|
#endif /* LWIP_IPV4 */
|
||||||
} else if (!lwip_isxdigit(*s)) {
|
} else if (!lwip_isxdigit(*s)) {
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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,16 +194,24 @@ 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') :
|
||||||
(u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A')));
|
(u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A')));
|
||||||
} else {
|
} else {
|
||||||
/* unexpected digit, space? CRLF? */
|
/* unexpected digit, space? CRLF? */
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -198,9 +198,17 @@ START_TEST(test_ip6_aton_ipv4mapped)
|
|||||||
const ip_addr_t addr_expected = IPADDR6_INIT_HOST(0, 0, 0xFFFF, 0xD4CC65D2);
|
const ip_addr_t addr_expected = IPADDR6_INIT_HOST(0, 0, 0xFFFF, 0xD4CC65D2);
|
||||||
const char *full_ipv6_addr = "0:0:0:0:0:FFFF:D4CC:65D2";
|
const char *full_ipv6_addr = "0:0:0:0:0:FFFF:D4CC:65D2";
|
||||||
const char *shortened_ipv6_addr = "::FFFF:D4CC:65D2";
|
const char *shortened_ipv6_addr = "::FFFF:D4CC:65D2";
|
||||||
|
const char *shortened_ipv6_addr_unexpected_char = "::FFFF:D4CC:65DZ";
|
||||||
|
const char *shortened_ipv6_addr_invalid = "::GGGGGGGG";
|
||||||
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 */
|
||||||
@ -223,6 +231,16 @@ START_TEST(test_ip6_aton_ipv4mapped)
|
|||||||
fail_unless(ret == 1);
|
fail_unless(ret == 1);
|
||||||
fail_unless(memcmp(&addr, &addr_expected, 16) == 0);
|
fail_unless(memcmp(&addr, &addr_expected, 16) == 0);
|
||||||
|
|
||||||
|
/* check shortened IPv6 with unexpected char */
|
||||||
|
memset(&addr6, 0, sizeof(addr6));
|
||||||
|
ret = ip6addr_aton(shortened_ipv6_addr_unexpected_char, &addr6);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* check shortened IPv6 that is clearly invalid */
|
||||||
|
memset(&addr6, 0, sizeof(addr6));
|
||||||
|
ret = ip6addr_aton(shortened_ipv6_addr_invalid, &addr6);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
/* checked shortened mixed representation */
|
/* checked shortened mixed representation */
|
||||||
memset(&addr6, 0, sizeof(addr6));
|
memset(&addr6, 0, sizeof(addr6));
|
||||||
ret = ip6addr_aton(shortened_ipv4_mapped_addr, &addr6);
|
ret = ip6addr_aton(shortened_ipv4_mapped_addr, &addr6);
|
||||||
@ -250,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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user