fixed some byte order and parsing problems

(cherry picked from commit 1d45f35a4a)
This commit is contained in:
Ariel Manzur 2016-10-19 18:32:36 -03:00 committed by Fabio Alessandrelli
parent fd1022fd29
commit 53fea7f196
3 changed files with 52 additions and 21 deletions

View file

@ -32,6 +32,7 @@
#include <stdio.h> #include <stdio.h>
#include "os/os.h" #include "os/os.h"
#include "drivers/nrex/regex.h" #include "drivers/nrex/regex.h"
#include "core/io/ip_address.h"
#include "test_string.h" #include "test_string.h"
@ -843,6 +844,23 @@ bool test_28() {
return state; return state;
} }
bool test_29() {
IP_Address ip0("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
printf("ip0 is %ls\n", String(ip0).c_str());
IP_Address ip(0x0123, 0x4567, 0x89ab, 0xcdef, IP_Address::TYPE_IPV6);
printf("ip6 is %ls\n", String(ip).c_str());
IP_Address ip2("fe80::52e5:49ff:fe93:1baf");
printf("ip6 is %ls\n", String(ip2).c_str());
IP_Address ip3("::ffff:192.168.0.1");
printf("ip6 is %ls\n", String(ip3).c_str());
return true;
};
typedef bool (*TestFunc)(void); typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = { TestFunc test_funcs[] = {
@ -875,6 +893,7 @@ TestFunc test_funcs[] = {
test_26, test_26,
test_27, test_27,
test_28, test_28,
test_29,
0 0
}; };

View file

@ -34,6 +34,7 @@ IP_Address::operator Variant() const {
}*/ }*/
#include <string.h> #include <string.h>
#include <stdio.h>
IP_Address::operator String() const { IP_Address::operator String() const {
@ -41,21 +42,23 @@ IP_Address::operator String() const {
return "0.0.0.0"; return "0.0.0.0";
if (type == TYPE_IPV4) if (type == TYPE_IPV4)
return itos(field8[0])+"."+itos(field8[1])+"."+itos(field8[2])+"."+itos(field8[3]); return itos(field8[0])+"."+itos(field8[1])+"."+itos(field8[2])+"."+itos(field8[3]);
else else {
return String::num_int64(field16[0], 16) + String ret;
":" + String::num_int64(field16[1], 16) + for (int i=0; i<8; i++) {
":" + String::num_int64(field16[2], 16) + if (i > 0)
":" + String::num_int64(field16[3], 16) + ret = ret + ":";
":" + String::num_int64(field16[4], 16) + uint16_t num = (field8[i*2] << 8) + field8[i*2+1];
":" + String::num_int64(field16[5], 16) + ret = ret + String::num_int64(num, 16);
":" + String::num_int64(field16[6], 16) + };
":" + String::num_int64(field16[7], 16);
return ret;
};
} }
static uint16_t _parse_hex(const String& p_string, int p_start) { static void _parse_hex(const String& p_string, int p_start, uint8_t* p_dst) {
uint16_t ret = 0; uint16_t ret = 0;
for (int i=p_start; i<4; i++) { for (int i=p_start; i<p_start + 4; i++) {
if (i >= p_string.length()) { if (i >= p_string.length()) {
break; break;
@ -70,15 +73,18 @@ static uint16_t _parse_hex(const String& p_string, int p_start) {
n = 10 + (c - 'a'); n = 10 + (c - 'a');
} else if (c >= 'A' && c <= 'F') { } else if (c >= 'A' && c <= 'F') {
n = 10 + (c - 'A'); n = 10 + (c - 'A');
} else if (c == ':') {
break;
} else { } else {
ERR_EXPLAIN("Invalid character in ipv6 address: " + p_string); ERR_EXPLAIN("Invalid character in ipv6 address: " + p_string);
ERR_FAIL_V(0); ERR_FAIL();
}; };
ret = ret << 4; ret = ret << 4;
ret += n; ret += n;
}; };
return ret; p_dst[0] = ret >> 8;
p_dst[1] = ret & 0xff;
}; };
void IP_Address::_parse_ipv6(const String& p_string) { void IP_Address::_parse_ipv6(const String& p_string) {
@ -140,8 +146,7 @@ void IP_Address::_parse_ipv6(const String& p_string) {
if (part_ipv4 && i == parts_idx - 1) { if (part_ipv4 && i == parts_idx - 1) {
_parse_ipv4(p_string, parts[i], (uint8_t*)&field16[idx]); // should be the last one _parse_ipv4(p_string, parts[i], (uint8_t*)&field16[idx]); // should be the last one
} else { } else {
_parse_hex(p_string, parts[i], (uint8_t*)&(field16[idx++]));
field16[idx++] = _parse_hex(p_string, parts[i]);
}; };
}; };
@ -162,7 +167,6 @@ void IP_Address::_parse_ipv4(const String& p_string, int p_start, uint8_t* p_ret
ERR_FAIL(); ERR_FAIL();
} }
for(int i=0;i<4;i++) { for(int i=0;i<4;i++) {
p_ret[i]=ip.get_slicec('.',i).to_int(); p_ret[i]=ip.get_slicec('.',i).to_int();
} }
}; };
@ -186,6 +190,14 @@ IP_Address::IP_Address(const String& p_string) {
}; };
} }
_FORCE_INLINE_ static void _32_to_buf(uint8_t* p_dst, uint32_t p_n) {
p_dst[0] = (p_n >> 24) & 0xff;
p_dst[1] = (p_n >> 16) & 0xff;
p_dst[2] = (p_n >> 8) & 0xff;
p_dst[3] = (p_n >> 0) & 0xff;
};
IP_Address::IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, IP_Address::AddrType p_type) { IP_Address::IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, IP_Address::AddrType p_type) {
type = p_type; type = p_type;
@ -197,10 +209,10 @@ IP_Address::IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, IP_A
field8[3]=p_d; field8[3]=p_d;
} else if (type == TYPE_IPV6) { } else if (type == TYPE_IPV6) {
field32[0]=p_a; _32_to_buf(&field8[0], p_a);
field32[1]=p_b; _32_to_buf(&field8[4], p_b);
field32[2]=p_c; _32_to_buf(&field8[8], p_c);
field32[3]=p_d; _32_to_buf(&field8[12], p_d);
} else { } else {
type = TYPE_NONE; type = TYPE_NONE;
ERR_EXPLAIN("Invalid type specified for IP_Address (use TYPE_IPV4 or TYPE_IPV6"); ERR_EXPLAIN("Invalid type specified for IP_Address (use TYPE_IPV4 or TYPE_IPV6");

View file

@ -68,7 +68,7 @@ static IP_Address _sockaddr2ip(struct sockaddr* p_addr) {
IP_Address ip; IP_Address ip;
if (p_addr->sa_family == AF_INET) { if (p_addr->sa_family == AF_INET) {
struct sockaddr_in* addr = (struct sockaddr_in*)p_addr; struct sockaddr_in* addr = (struct sockaddr_in*)p_addr;
ip.field32[0] = ntohl(addr->sin_addr.s_addr); ip.field32[0] = *((unsigned long*)&addr->sin_addr);
ip.type = IP_Address::TYPE_IPV4; ip.type = IP_Address::TYPE_IPV4;
} else { } else {
struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr;