summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authorsbc@chromium.org <sbc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-28 02:32:54 +0000
committersbc@chromium.org <sbc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-28 02:32:54 +0000
commit0b4d50f2d28c98246e81ee5c816699a884034092 (patch)
tree2241cc285142f13a93e9fd9887159c5e66700e43 /native_client_sdk
parent8853f012ca0047aa009afb94eb9a02875dc3c15d (diff)
downloadchromium_src-0b4d50f2d28c98246e81ee5c816699a884034092.zip
chromium_src-0b4d50f2d28c98246e81ee5c816699a884034092.tar.gz
chromium_src-0b4d50f2d28c98246e81ee5c816699a884034092.tar.bz2
[NaCl SDK] nacl_io: Fix inet_ntop to be consistent with glibc.
Update inet_ntop to output ipv4 address for ::A.B.C.D as well as ::ffff:A:B:C:D so that its consistent the glibc's implementation. Also, add two missing socket syscalls: inet_addr and inet_aton. Also, add test for this case and cleanup test code these socket utility function. Alos, rename some, .cc files to .c in nacl_io syscalls. R=binji@chromium.org Review URL: https://codereview.chromium.org/139283003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247394 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc18
-rw-r--r--native_client_sdk/src/libraries/nacl_io/library.dsc6
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.c31
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc54
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/inet_addr.c20
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/inet_aton.c54
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.c (renamed from native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc)12
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc58
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/inet_pton.c4
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/socket_test.cc239
10 files changed, 336 insertions, 160 deletions
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
index be052c0..edf1eb8 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
@@ -377,77 +377,95 @@ sighandler_t ki_sigset(int signum, sighandler_t handler) {
#ifdef PROVIDES_SOCKET_API
// Socket Functions
int ki_accept(int fd, struct sockaddr* addr, socklen_t* len) {
+ ON_NOSYS_RETURN(-1);
return s_kp->accept(fd, addr, len);
}
int ki_bind(int fd, const struct sockaddr* addr, socklen_t len) {
+ ON_NOSYS_RETURN(-1);
return s_kp->bind(fd, addr, len);
}
int ki_connect(int fd, const struct sockaddr* addr, socklen_t len) {
+ ON_NOSYS_RETURN(-1);
return s_kp->connect(fd, addr, len);
}
struct hostent* ki_gethostbyname(const char* name) {
+ ON_NOSYS_RETURN(NULL);
return s_kp->gethostbyname(name);
}
int ki_getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
+ ON_NOSYS_RETURN(-1);
return s_kp->getpeername(fd, addr, len);
}
int ki_getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
+ ON_NOSYS_RETURN(-1);
return s_kp->getsockname(fd, addr, len);
}
int ki_getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
+ ON_NOSYS_RETURN(-1);
return s_kp->getsockopt(fd, lvl, optname, optval, len);
}
int ki_listen(int fd, int backlog) {
+ ON_NOSYS_RETURN(-1);
return s_kp->listen(fd, backlog);
}
ssize_t ki_recv(int fd, void* buf, size_t len, int flags) {
+ ON_NOSYS_RETURN(-1);
return s_kp->recv(fd, buf, len, flags);
}
ssize_t ki_recvfrom(int fd, void* buf, size_t len, int flags,
struct sockaddr* addr, socklen_t* addrlen) {
+ ON_NOSYS_RETURN(-1);
return s_kp->recvfrom(fd, buf, len, flags, addr, addrlen);
}
ssize_t ki_recvmsg(int fd, struct msghdr* msg, int flags) {
+ ON_NOSYS_RETURN(-1);
return s_kp->recvmsg(fd, msg, flags);
}
ssize_t ki_send(int fd, const void* buf, size_t len, int flags) {
+ ON_NOSYS_RETURN(-1);
return s_kp->send(fd, buf, len, flags);
}
ssize_t ki_sendto(int fd, const void* buf, size_t len, int flags,
const struct sockaddr* addr, socklen_t addrlen) {
+ ON_NOSYS_RETURN(-1);
return s_kp->sendto(fd, buf, len, flags, addr, addrlen);
}
ssize_t ki_sendmsg(int fd, const struct msghdr* msg, int flags) {
+ ON_NOSYS_RETURN(-1);
return s_kp->sendmsg(fd, msg, flags);
}
int ki_setsockopt(int fd, int lvl, int optname, const void* optval,
socklen_t len) {
+ ON_NOSYS_RETURN(-1);
return s_kp->setsockopt(fd, lvl, optname, optval, len);
}
int ki_shutdown(int fd, int how) {
+ ON_NOSYS_RETURN(-1);
return s_kp->shutdown(fd, how);
}
int ki_socket(int domain, int type, int protocol) {
+ ON_NOSYS_RETURN(-1);
return s_kp->socket(domain, type, protocol);
}
int ki_socketpair(int domain, int type, int protocol, int* sv) {
+ ON_NOSYS_RETURN(-1);
return s_kp->socketpair(domain, type, protocol, sv);
}
#endif // PROVIDES_SOCKET_API
diff --git a/native_client_sdk/src/libraries/nacl_io/library.dsc b/native_client_sdk/src/libraries/nacl_io/library.dsc
index e76ecd8..0b74074 100644
--- a/native_client_sdk/src/libraries/nacl_io/library.dsc
+++ b/native_client_sdk/src/libraries/nacl_io/library.dsc
@@ -86,10 +86,12 @@
"syscalls/getsockopt.c",
"syscalls/getwd.c",
"syscalls/herror.c",
- "syscalls/hstrerror.cc",
+ "syscalls/hstrerror.c",
"syscalls/htonl.c",
"syscalls/htons.c",
- "syscalls/inet_ntoa.cc",
+ "syscalls/inet_addr.c",
+ "syscalls/inet_aton.c",
+ "syscalls/inet_ntoa.c",
"syscalls/inet_ntop.cc",
"syscalls/inet_pton.c",
"syscalls/ioctl.c",
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.c b/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.c
new file mode 100644
index 0000000..d250f3f
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.c
@@ -0,0 +1,31 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "nacl_io/ossocket.h"
+
+#ifdef PROVIDES_SOCKET_API
+
+#include <stdio.h>
+
+const char* hstrerror(int err) {
+ switch (err) {
+ case HOST_NOT_FOUND:
+ return "The specified host is unknown.";
+ case NO_ADDRESS:
+ return "The requested name is valid but does not have an IP address.";
+ case NO_RECOVERY:
+ return "A nonrecoverable name server error occurred.";
+ case TRY_AGAIN:
+ return "A temporary error occurred on an authoritative name server. "
+ "Try again later.";
+ case NETDB_INTERNAL:
+ return "Internal error in gethostbyname.";
+ }
+
+ static char rtn[128];
+ snprintf(rtn, sizeof(rtn), "Unknown error in gethostbyname: %d.", err);
+ return rtn;
+}
+
+#endif // PROVIDES_SOCKET_API
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc b/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc
deleted file mode 100644
index f1354d9..0000000
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "nacl_io/ossocket.h"
-
-#ifdef PROVIDES_SOCKET_API
-
-#include <sstream>
-#include <string>
-#include "sdk_util/macros.h"
-
-EXTERN_C_BEGIN
-
-const char* hstrerror(int err) {
- // These error message texts are taken straight from the man page
- const char* host_not_found_msg =
- "The specified host is unknown.";
- const char* no_address_msg =
- "The requested name is valid but does not have an IP address.";
- const char* no_recovery_msg =
- "A nonrecoverable name server error occurred.";
- const char* try_again_msg =
- "A temporary error occurred on an authoritative name server. "
- "Try again later.";
- const char* internal_msg =
- "Internal error in gethostbyname.";
- const char* unknown_msg_base =
- "Unknown error in gethostbyname: ";
-
- switch (err) {
- case HOST_NOT_FOUND:
- return host_not_found_msg;
- case NO_ADDRESS:
- return no_address_msg;
- case NO_RECOVERY:
- return no_recovery_msg;
- case TRY_AGAIN:
- return try_again_msg;
- case NETDB_INTERNAL:
- return internal_msg;
- default:
- std::stringstream msg;
- msg << unknown_msg_base << err << ".";
-
- static std::string unknown_msg;
- unknown_msg.assign(msg.str());
- return unknown_msg.c_str();
- }
-}
-
-EXTERN_C_END
-
-#endif // PROVIDES_SOCKET_API
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_addr.c b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_addr.c
new file mode 100644
index 0000000..98dbe8f
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_addr.c
@@ -0,0 +1,20 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "nacl_io/ossocket.h"
+
+#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
+
+#include <string.h>
+
+in_addr_t inet_addr(const char* addr) {
+ struct in_addr rtn = { 0 };
+ int ret = inet_aton(addr, &rtn);
+ // inet_ntoa returns zero if addr is not valid
+ if (ret == 0)
+ return INADDR_NONE;
+ return rtn.s_addr;
+}
+
+#endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_aton.c b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_aton.c
new file mode 100644
index 0000000..964587a
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_aton.c
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "nacl_io/ossocket.h"
+
+#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
+
+#include <string.h>
+#include <limits.h>
+
+int inet_aton(const char *cp, struct in_addr *inp) {
+ unsigned int p1 = 0, p2 = 0, p3 = 0, p4 = 0;
+ int consumed = 0;
+ int matched = sscanf(cp, "%u.%u.%u.%u%n", &p1, &p2, &p3, &p4,
+ &consumed);
+
+ if (strlen(cp) == consumed && matched == 4) {
+ if ((p1 | p2 | p3 | p4) <= UCHAR_MAX) {
+ in_addr_t host_order_addr = (p1 << 24) | (p2 << 16) | (p3 << 8) | p4;
+ inp->s_addr = htonl(host_order_addr);
+ return 1;
+ }
+ }
+
+ matched = sscanf(cp, "%u.%u.%u%n", &p1, &p2, &p3, &consumed);
+ if (strlen(cp) == consumed && matched == 3) {
+ if ((p1 | p2) <= UCHAR_MAX && p3 <= USHRT_MAX) {
+ in_addr_t host_order_addr = (p1 << 24) | (p2 << 16) | p3;
+ inp->s_addr = htonl(host_order_addr);
+ return 1;
+ }
+ }
+
+ matched = sscanf(cp, "%u.%u%n", &p1, &p2, &consumed);
+ if (strlen(cp) == consumed && matched == 2) {
+ if (p1 <= UCHAR_MAX && p1 <= 1 << 24) {
+ in_addr_t host_order_addr = (p1 << 24) | p2;
+ inp->s_addr = htonl(host_order_addr);
+ return 1;
+ }
+ }
+
+ matched = sscanf(cp, "%u%n", &p1, &consumed);
+ if (strlen(cp) == consumed && matched == 1) {
+ inp->s_addr = htonl(p1);
+ return 1;
+ }
+
+ // Failure
+ return 0;
+}
+
+#endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.c
index c6cf610..380cbc8 100644
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.c
@@ -3,18 +3,14 @@
// found in the LICENSE file.
#include "nacl_io/ossocket.h"
-#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
-#include <string.h>
-#include "sdk_util/macros.h"
+#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
static uint8_t GetByte(const void* addr, int byte) {
- const char* buf = static_cast<const char*>(addr);
- return static_cast<uint8_t>(buf[byte]);
+ const char* buf = (const char*)addr;
+ return (uint8_t)buf[byte];
}
-EXTERN_C_BEGIN
-
char* inet_ntoa(struct in_addr in) {
static char addr[INET_ADDRSTRLEN];
snprintf(addr, INET_ADDRSTRLEN, "%u.%u.%u.%u",
@@ -23,6 +19,4 @@ char* inet_ntoa(struct in_addr in) {
return addr;
}
-EXTERN_C_END
-
#endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc
index ceabae5..e9bde2b 100644
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc
@@ -14,7 +14,6 @@
#include "sdk_util/macros.h"
-
EXTERN_C_BEGIN
const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) {
@@ -35,16 +34,58 @@ const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) {
errno = ENOSPC;
return NULL;
}
- const uint8_t* tuples = static_cast<const uint8_t*>(src);
- std::stringstream output;
+
+ // Convert to an array of 8 host order shorts
+ const uint16_t* tuples = static_cast<const uint16_t*>(src);
+ uint16_t host_tuples[8];
+ int zero_run_start = -1;
+ int zero_run_end = -1;
for (int i = 0; i < 8; i++) {
- uint16_t tuple = (tuples[2*i] << 8) + tuples[2*i+1];
- output << std::hex << tuple;
- if (i < 7) {
- output << ":";
+ host_tuples[i] = ntohs(tuples[i]);
+ if (host_tuples[i] == 0) {
+ if (zero_run_start == -1)
+ zero_run_start = i;
+ } else if (zero_run_start != -1 && zero_run_end == -1) {
+ zero_run_end = i;
+ }
+ }
+
+ if (zero_run_start != -1) {
+ if (zero_run_end == -1)
+ zero_run_end = 8;
+ if (zero_run_end - zero_run_start < 2) {
+ zero_run_start = -1;
+ zero_run_end = -1;
}
}
- memcpy(dst, output.str().c_str(), output.str().size() + 1);
+
+ // Mimick glibc's behaviour here and allow ipv4 address to be specified
+ // as either ::A.B.C.D or ::ffff:A.B.C.D.
+ if (zero_run_start == 0 &&
+ (zero_run_end == 6 ||
+ (zero_run_end == 5 && host_tuples[zero_run_end] == 0xffff))) {
+
+ if (zero_run_end == 5) {
+ strcpy(dst, "::ffff:");
+ } else {
+ strcpy(dst, "::");
+ }
+ inet_ntop(AF_INET, host_tuples+6, dst+strlen(dst), INET_ADDRSTRLEN);
+ } else {
+ std::stringstream output;
+ for (int i = 0; i < 8; i++) {
+ if (i == zero_run_start) {
+ output << "::";
+ continue;
+ }
+ if (i > zero_run_start && i < zero_run_end)
+ continue;
+ output << std::hex << host_tuples[i];
+ if (i < 7 && i + 1 != zero_run_start)
+ output << ":";
+ }
+ memcpy(dst, output.str().c_str(), output.str().size() + 1);
+ }
return dst;
}
@@ -55,4 +96,3 @@ const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) {
EXTERN_C_END
#endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
-
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_pton.c b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_pton.c
index b1a2d7a..91d3c6c 100644
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_pton.c
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_pton.c
@@ -13,8 +13,8 @@
#include "sdk_util/macros.h"
enum {
-kIpv4AddressSize = 4,
-kIpv6AddressSize = 16,
+ kIpv4AddressSize = sizeof(in_addr_t),
+ kIpv6AddressSize = sizeof(struct in6_addr),
};
/* Helper function for inet_pton() for IPv4 addresses. */
diff --git a/native_client_sdk/src/tests/nacl_io_test/socket_test.cc b/native_client_sdk/src/tests/nacl_io_test/socket_test.cc
index fb13de9..70a02e0 100644
--- a/native_client_sdk/src/tests/nacl_io_test/socket_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/socket_test.cc
@@ -269,6 +269,8 @@ TEST(SocketUtilityFunctions, Hstrerror) {
"Unknown error in gethostbyname: 2718.");
}
+#endif // !defined(__GLIBC__)
+
TEST(SocketUtilityFunctions, Htonl) {
uint32_t host_long = 0x44332211;
uint32_t network_long = htonl(host_long);
@@ -289,151 +291,220 @@ TEST(SocketUtilityFunctions, Htons) {
EXPECT_EQ(network_bytes[1], 0x11);
}
-static struct in_addr generate_ipv4_addr(int tuple1, int tuple2,
- int tuple3, int tuple4) {
+static struct in_addr generate_ipv4_addr(uint8_t* tuple) {
unsigned char addr[4];
- addr[0] = static_cast<unsigned char>(tuple1);
- addr[1] = static_cast<unsigned char>(tuple2);
- addr[2] = static_cast<unsigned char>(tuple3);
- addr[3] = static_cast<unsigned char>(tuple4);
+ addr[0] = static_cast<unsigned char>(tuple[0]);
+ addr[1] = static_cast<unsigned char>(tuple[1]);
+ addr[2] = static_cast<unsigned char>(tuple[2]);
+ addr[3] = static_cast<unsigned char>(tuple[3]);
struct in_addr real_addr;
memcpy(&real_addr, addr, 4);
return real_addr;
}
-static struct in6_addr generate_ipv6_addr(int* tuples) {
+static struct in6_addr generate_ipv6_addr(uint16_t* tuple) {
unsigned char addr[16];
for (int i = 0; i < 8; i++) {
- addr[2*i] = (tuples[i] >> 8) & 0xFF;
- addr[2*i+1] = tuples[i] & 0xFF;
+ addr[2*i] = (tuple[i] >> 8) & 0xFF;
+ addr[2*i+1] = tuple[i] & 0xFF;
}
struct in6_addr real_addr;
memcpy(&real_addr, addr, 16);
return real_addr;
}
-TEST(SocketUtilityFunctions, Inet_ntoa) {
- char* stringified_addr = inet_ntoa(generate_ipv4_addr(0,0,0,0));
- ASSERT_TRUE(NULL != stringified_addr);
- EXPECT_STREQ("0.0.0.0", stringified_addr);
+TEST(SocketUtilityFunctions, Inet_addr) {
+ // Fails for if string contains non-integers.
+ ASSERT_EQ(INADDR_NONE, inet_addr("foobar"));
+
+ // Fails if there are too many quads
+ ASSERT_EQ(INADDR_NONE, inet_addr("0.0.0.0.0"));
+
+ // Fails if a single element is > 255
+ ASSERT_EQ(INADDR_NONE, inet_addr("999.0.0.0"));
+
+ // Fails if a single element is negative.
+ ASSERT_EQ(INADDR_NONE, inet_addr("-55.0.0.0"));
+
+ // In tripple, notation third integer cannot be larger
+ // and 16bit unsigned int.
+ ASSERT_EQ(INADDR_NONE, inet_addr("1.2.66000"));
+
+ // Success cases.
+ // Normal dotted-quad address.
+ uint32_t expected_addr = ntohl(0x07060504);
+ ASSERT_EQ(expected_addr, inet_addr("7.6.5.4"));
+ expected_addr = ntohl(0xffffffff);
+ ASSERT_EQ(expected_addr, inet_addr("255.255.255.255"));
+
+ // Tripple case
+ expected_addr = ntohl(1 << 24 | 2 << 16 | 3);
+ ASSERT_EQ(expected_addr, inet_addr("1.2.3"));
+ expected_addr = ntohl(1 << 24 | 2 << 16 | 300);
+ ASSERT_EQ(expected_addr, inet_addr("1.2.300"));
+
+ // Double case
+ expected_addr = ntohl(1 << 24 | 20000);
+ ASSERT_EQ(expected_addr, inet_addr("1.20000"));
+ expected_addr = ntohl(1 << 24 | 2);
+ ASSERT_EQ(expected_addr, inet_addr("1.2"));
+
+ // Single case
+ expected_addr = ntohl(255);
+ ASSERT_EQ(expected_addr, inet_addr("255"));
+ expected_addr = ntohl(4000000000U);
+ ASSERT_EQ(expected_addr, inet_addr("4000000000"));
+}
- stringified_addr = inet_ntoa(generate_ipv4_addr(127,0,0,1));
- ASSERT_TRUE(NULL != stringified_addr);
- EXPECT_STREQ("127.0.0.1", stringified_addr);
+TEST(SocketUtilityFunctions, Inet_aton) {
+ struct in_addr addr;
- stringified_addr = inet_ntoa(generate_ipv4_addr(255,255,255,255));
- ASSERT_TRUE(NULL != stringified_addr);
- EXPECT_STREQ("255.255.255.255", stringified_addr);
-}
+ // Failure cases
+ ASSERT_EQ(0, inet_aton("foobar", &addr));
+ ASSERT_EQ(0, inet_aton("0.0.0.0.0", &addr));
+ ASSERT_EQ(0, inet_aton("999.0.0.0", &addr));
-TEST(SocketUtilityFunctions, Inet_ntop_ipv4) {
- char stringified_addr[INET_ADDRSTRLEN];
+ // Success cases
+ uint32_t expected_addr = htonl(0xff020304);
+ ASSERT_NE(0, inet_aton("255.2.3.4", &addr));
+ ASSERT_EQ(expected_addr, addr.s_addr);
- struct in_addr real_addr = generate_ipv4_addr(0,0,0,0);
- EXPECT_TRUE(NULL != inet_ntop(AF_INET, &real_addr,
- stringified_addr, INET_ADDRSTRLEN));
- EXPECT_STREQ("0.0.0.0", stringified_addr);
+ expected_addr = htonl(0x01000002);
+ ASSERT_NE(0, inet_aton("1.2", &addr));
+ ASSERT_EQ(expected_addr, addr.s_addr);
- real_addr = generate_ipv4_addr(127,0,0,1);
- EXPECT_TRUE(NULL != inet_ntop(AF_INET, &real_addr,
- stringified_addr, INET_ADDRSTRLEN));
- EXPECT_STREQ("127.0.0.1", stringified_addr);
+ expected_addr = htonl(0x01020003);
+ ASSERT_NE(0, inet_aton("1.2.3", &addr));
+ ASSERT_EQ(expected_addr, addr.s_addr);
- real_addr = generate_ipv4_addr(255,255,255,255);
- EXPECT_TRUE(NULL != inet_ntop(AF_INET, &real_addr,
- stringified_addr, INET_ADDRSTRLEN));
- EXPECT_STREQ("255.255.255.255", stringified_addr);
+ expected_addr = htonl(0x0000100);
+ ASSERT_NE(0, inet_aton("256", &addr));
+ ASSERT_EQ(expected_addr, addr.s_addr);
}
-TEST(SocketUtilityFunctions, Inet_ntop_ipv6) {
- char stringified_addr[INET6_ADDRSTRLEN];
+TEST(SocketUtilityFunctions, Inet_ntoa) {
+ struct {
+ unsigned char addr_tuple[4];
+ const char* output;
+ } tests[] = {
+ { { 0, 0, 0, 0 }, "0.0.0.0" },
+ { { 127, 0, 0, 1 }, "127.0.0.1" },
+ { { 255, 255, 255, 255 }, "255.255.255.255" },
+ };
- {
- int addr_tuples[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- struct in6_addr real_addr = generate_ipv6_addr(addr_tuples);
- EXPECT_TRUE(NULL != inet_ntop(AF_INET6, &real_addr,
- stringified_addr, INET6_ADDRSTRLEN));
- EXPECT_STREQ("0:0:0:0:0:0:0:0", stringified_addr);
+ for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
+ char* stringified_addr = inet_ntoa(generate_ipv4_addr(tests[i].addr_tuple));
+ ASSERT_TRUE(NULL != stringified_addr);
+ EXPECT_STREQ(tests[i].output, stringified_addr);
}
+}
- {
- int addr_tuples[8] = { 0x1234, 0xa, 0x12, 0x0000,
- 0x5678, 0x9abc, 0xdef, 0xffff };
- struct in6_addr real_addr = generate_ipv6_addr(addr_tuples);
- EXPECT_TRUE(NULL != inet_ntop(AF_INET6, &real_addr,
- stringified_addr, INET6_ADDRSTRLEN));
- EXPECT_STREQ("1234:a:12:0:5678:9abc:def:ffff", stringified_addr);
+TEST(SocketUtilityFunctions, Inet_ntop_ipv4) {
+ struct {
+ unsigned char addr_tuple[4];
+ const char* output;
+ } tests[] = {
+ { { 0, 0, 0, 0 }, "0.0.0.0" },
+ { { 127, 0, 0, 1 }, "127.0.0.1" },
+ { { 255, 255, 255, 255 }, "255.255.255.255" },
+ };
+
+ for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
+ char stringified_addr[INET_ADDRSTRLEN];
+ struct in_addr real_addr = generate_ipv4_addr(tests[i].addr_tuple);
+ EXPECT_TRUE(NULL != inet_ntop(AF_INET, &real_addr,
+ stringified_addr, INET_ADDRSTRLEN));
+ EXPECT_STREQ(tests[i].output, stringified_addr);
}
+}
+
+TEST(SocketUtilityFunctions, Inet_ntop_ipv6) {
+ struct {
+ unsigned short addr_tuple[8];
+ const char* output;
+ } tests[] = {
+ { { 0, 0, 0, 0, 0, 0, 0, 0 }, "::" },
+ { { 1, 2, 3, 0, 0, 0, 0, 0 }, "1:2:3::" },
+ { { 0, 0, 0, 0, 0, 1, 2, 3 }, "::1:2:3" },
+ { { 0x1234, 0xa, 0x12, 0x0000, 0x5678, 0x9abc, 0xdef, 0xffff },
+ "1234:a:12:0:5678:9abc:def:ffff" },
+ { { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" },
+ { { 0, 0, 0, 0, 0, 0xffff, 0x101, 0x101 }, "::ffff:1.1.1.1" },
+ { { 0, 0, 0, 0, 0, 0, 0x101, 0x101 }, "::1.1.1.1" },
+ };
- {
- int addr_tuples[8] = { 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff };
- struct in6_addr real_addr = generate_ipv6_addr(addr_tuples);
+ for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
+ char stringified_addr[INET6_ADDRSTRLEN];
+ struct in6_addr real_addr = generate_ipv6_addr(tests[i].addr_tuple);
EXPECT_TRUE(NULL != inet_ntop(AF_INET6, &real_addr,
stringified_addr, INET6_ADDRSTRLEN));
- EXPECT_STREQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", stringified_addr);
+ EXPECT_STREQ(tests[i].output, stringified_addr);
}
}
TEST(SocketUtilityFunctions, Inet_ntop_failure) {
char addr_name[INET6_ADDRSTRLEN];
- int addr_tuples[8] = { 0xffff, 0xffff, 0xffff, 0xffff,
+ uint16_t addr6_tuple[8] = { 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff };
- struct in6_addr ipv6_addr = generate_ipv6_addr(addr_tuples);
- struct in_addr ipv4_addr = generate_ipv4_addr(255,255,255,255);
+ uint8_t addr_tuple[4] = { 255, 255, 255, 255 };
+ struct in6_addr ipv6_addr = generate_ipv6_addr(addr6_tuple);
+ struct in_addr ipv4_addr = generate_ipv4_addr(addr_tuple);
- EXPECT_TRUE(NULL == inet_ntop(AF_UNIX, &ipv6_addr,
- addr_name, INET6_ADDRSTRLEN));
- EXPECT_EQ(errno, EAFNOSUPPORT);
+ EXPECT_EQ(NULL, inet_ntop(AF_UNIX, &ipv6_addr,
+ addr_name, INET6_ADDRSTRLEN));
+ EXPECT_EQ(EAFNOSUPPORT, errno);
- EXPECT_TRUE(NULL == inet_ntop(AF_INET, &ipv4_addr,
- addr_name, INET_ADDRSTRLEN - 1));
- EXPECT_EQ(errno, ENOSPC);
+ EXPECT_EQ(NULL, inet_ntop(AF_INET, &ipv4_addr,
+ addr_name, INET_ADDRSTRLEN - 1));
+ EXPECT_EQ(ENOSPC, errno);
- EXPECT_TRUE(NULL == inet_ntop(AF_INET6, &ipv6_addr,
- addr_name, INET6_ADDRSTRLEN - 1));
- EXPECT_EQ(errno, ENOSPC);
+ EXPECT_EQ(NULL, inet_ntop(AF_INET6, &ipv6_addr,
+ addr_name, INET6_ADDRSTRLEN / 2));
+ EXPECT_EQ(ENOSPC, errno);
}
TEST(SocketUtilityFunctions, Inet_pton) {
struct {
int family;
const char* input;
- const char* output;
+ const char* output; // NULL means output should match input
} tests[] = {
{ AF_INET, "127.127.12.0", NULL },
{ AF_INET, "0.0.0.0", NULL },
- { AF_INET6, "0:0:0:0:0:0:0:0", NULL },
+ { AF_INET6, "0:0:0:0:0:0:0:0", "::" },
{ AF_INET6, "1234:5678:9abc:def0:1234:5678:9abc:def0", NULL },
{ AF_INET6, "1:2:3:4:5:6:7:8", NULL },
{ AF_INET6, "a:b:c:d:e:f:1:2", NULL },
{ AF_INET6, "A:B:C:D:E:F:1:2", "a:b:c:d:e:f:1:2" },
- { AF_INET6, "::", "0:0:0:0:0:0:0:0" },
- { AF_INET6, "::12", "0:0:0:0:0:0:0:12" },
- { AF_INET6, "::1:2:3", "0:0:0:0:0:1:2:3" },
- { AF_INET6, "12::", "12:0:0:0:0:0:0:0" },
- { AF_INET6, "1:2::", "1:2:0:0:0:0:0:0" },
- { AF_INET6, "::12:0:0:0:0:0:0:0", "12:0:0:0:0:0:0:0" },
- { AF_INET6, "1:2:3::4:5", "1:2:3:0:0:0:4:5" },
- { AF_INET6, "::1.1.1.1", "0:0:0:0:0:0:101:101" },
- { AF_INET6, "::ffff:1.1.1.1", "0:0:0:0:0:ffff:101:101" },
- { AF_INET6, "ffff::1.1.1.1", "ffff:0:0:0:0:0:101:101" },
- { AF_INET6, "::1.1.1.1", "0:0:0:0:0:0:101:101" },
+ { AF_INET6, "::", "::" },
+ { AF_INET6, "::12", "::12" },
+ { AF_INET6, "::1:2:3", "::1:2:3" },
+ { AF_INET6, "12::", "12::" },
+ { AF_INET6, "1:2::", "1:2::" },
+ { AF_INET6, "12:0:0:0:0:0:0:0", "12::" },
+ { AF_INET6, "1:2:3::4:5", "1:2:3::4:5" },
+ { AF_INET6, "::ffff:1.1.1.1", "::ffff:1.1.1.1" },
+ { AF_INET6, "ffff::1.1.1.1", "ffff::101:101" },
+ { AF_INET6, "::1.1.1.1", "::1.1.1.1" },
};
for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
uint8_t addr[16];
- EXPECT_TRUE(inet_pton(tests[i].family, tests[i].input, addr));
+ ASSERT_TRUE(inet_pton(tests[i].family, tests[i].input, addr))
+ << "inet_pton failed for " << tests[i].input;
const char* expected = tests[i].output ? tests[i].output : tests[i].input;
char out_buffer[256];
- EXPECT_TRUE(
- inet_ntop(tests[i].family, addr, out_buffer, sizeof(out_buffer)));
- EXPECT_EQ(std::string(expected), std::string(out_buffer));
+ ASSERT_EQ(out_buffer,
+ inet_ntop(tests[i].family, addr, out_buffer, sizeof(out_buffer)));
+ ASSERT_STREQ(expected, out_buffer);
}
}
TEST(SocketUtilityFunctions, Inet_pton_failure) {
+ // All these are examples of strings that do not map
+ // to IP address. inet_pton returns 0 on failure.
uint8_t addr[16];
EXPECT_EQ(0, inet_pton(AF_INET, "127.127.12.24312", &addr));
EXPECT_EQ(0, inet_pton(AF_INET, "127.127.12.24 ", &addr));
@@ -455,6 +526,7 @@ TEST(SocketUtilityFunctions, Inet_pton_failure) {
EXPECT_EQ(0, inet_pton(AF_INET6, "0:0:0:0:0:0:1:0.0.0.0", &addr));
EXPECT_EQ(0, inet_pton(AF_INET6, "::0.0.0.0:1", &addr));
EXPECT_EQ(0, inet_pton(AF_INET6, "::0.0.0.0.0", &addr));
+ EXPECT_EQ(0, inet_pton(AF_INET6, "::1.2.3.4.5.6.7.8", &addr));
}
TEST(SocketUtilityFunctions, Ntohs) {
@@ -473,5 +545,4 @@ TEST(SocketUtilityFunctions, Ntohl) {
EXPECT_EQ(host_long, 0x44332211);
}
-#endif // !defined(__GLIBC__)
#endif // PROVIDES_SOCKETPAIR_API