summaryrefslogtreecommitdiff
path: root/core/io/ip_address.cpp
diff options
context:
space:
mode:
authorFabio Alessandrelli <fabio.alessandrelli@gmail.com>2016-12-05 16:32:38 +0100
committerFabio Alessandrelli <fabio.alessandrelli@gmail.com>2016-12-09 18:24:59 +0100
commit1aff508dd9713abf0db0d0436fa7f7c4788c5a4a (patch)
treed3213c170d4e6aa90bf0bf2e62673728f2cac58c /core/io/ip_address.cpp
parenta77a0118f6b0d0878a53e2c963d91763b311163d (diff)
IP_Address now handle IPv4 and IPv6 transparently
IP_Address changes: - Converts to and from String transparently while handling IPv4 as IPv6 mapped (::ffff:[IP]) address internally. - Completely remove AddrType enum. - Setting/Getting of ip array is now only possible through dedicated functions (ie. set_ipv4, get_ipv4, set_ipv6, get_ipv6) - Add function to know if the address is a valid IPv4 (for IP implementation and enet)
Diffstat (limited to 'core/io/ip_address.cpp')
-rw-r--r--core/io/ip_address.cpp82
1 files changed, 50 insertions, 32 deletions
diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp
index 9887cd132b..7df5fe79ec 100644
--- a/core/io/ip_address.cpp
+++ b/core/io/ip_address.cpp
@@ -38,21 +38,18 @@ IP_Address::operator Variant() const {
IP_Address::operator String() const {
- if (type == TYPE_NONE)
- return "0.0.0.0";
- if (type == TYPE_IPV4)
- return itos(field8[0])+"."+itos(field8[1])+"."+itos(field8[2])+"."+itos(field8[3]);
- else {
- String ret;
- for (int i=0; i<8; i++) {
- if (i > 0)
- ret = ret + ":";
- uint16_t num = (field8[i*2] << 8) + field8[i*2+1];
- ret = ret + String::num_int64(num, 16);
- };
-
- return ret;
+ if(is_ipv4())
+ // IPv4 address mapped to IPv6
+ return itos(field8[12])+"."+itos(field8[13])+"."+itos(field8[14])+"."+itos(field8[15]);
+ String ret;
+ for (int i=0; i<8; i++) {
+ if (i > 0)
+ ret = ret + ":";
+ uint16_t num = (field8[i*2] << 8) + field8[i*2+1];
+ ret = ret + String::num_int64(num, 16);
};
+
+ return ret;
}
static void _parse_hex(const String& p_string, int p_start, uint8_t* p_dst) {
@@ -176,17 +173,41 @@ void IP_Address::clear() {
memset(&field8[0], 0, sizeof(field8));
};
+bool IP_Address::is_ipv4() const{
+ return (field32[0]==0 && field32[1]==0 && field16[4]==0 && field16[5]==0xffff);
+}
+
+const uint8_t *IP_Address::get_ipv4() const{
+ ERR_FAIL_COND_V(!is_ipv4(),0);
+ return &(field8[12]);
+}
+
+void IP_Address::set_ipv4(const uint8_t *p_ip) {
+ clear();
+ field16[5]=0xffff;
+ field32[3]=*((const uint32_t *)p_ip);
+}
+
+const uint8_t *IP_Address::get_ipv6() const{
+ return field8;
+}
+
+void IP_Address::set_ipv6(const uint8_t *p_buf) {
+ clear();
+ for (int i=0; i<16; i++)
+ field8[i] = p_buf[i];
+}
+
IP_Address::IP_Address(const String& p_string) {
clear();
if (p_string.find(":") >= 0) {
_parse_ipv6(p_string);
- type = TYPE_IPV6;
} else {
-
- _parse_ipv4(p_string, 0, &field8[0]);
- type = TYPE_IPV4;
+ // Mapped to IPv6
+ field16[5] = 0xffff;
+ _parse_ipv4(p_string, 0, &field8[12]);
};
}
@@ -198,25 +219,22 @@ _FORCE_INLINE_ static void _32_to_buf(uint8_t* p_dst, uint32_t p_n) {
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, bool is_v6) {
- type = p_type;
- memset(&field8[0], 0, sizeof(field8));
- if (p_type == TYPE_IPV4) {
- field8[0]=p_a;
- field8[1]=p_b;
- field8[2]=p_c;
- field8[3]=p_d;
- } else if (type == TYPE_IPV6) {
+ clear();
+ if (!is_v6) {
+ // Mapped to IPv6
+ field16[5]=0xffff;
+ field8[12]=p_a;
+ field8[13]=p_b;
+ field8[14]=p_c;
+ field8[15]=p_d;
+ } else {
_32_to_buf(&field8[0], p_a);
_32_to_buf(&field8[4], p_b);
_32_to_buf(&field8[8], p_c);
_32_to_buf(&field8[12], p_d);
- } else {
- type = TYPE_NONE;
- ERR_EXPLAIN("Invalid type specified for IP_Address (use TYPE_IPV4 or TYPE_IPV6");
- ERR_FAIL();
- };
+ }
}