1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "nacl_io/ossocket.h"
6 #if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) && !defined(__BIONIC__)
15 #include "sdk_util/macros.h"
19 const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) {
21 if (size < INET_ADDRSTRLEN) {
26 memcpy(&in, src, sizeof(in));
27 char* result = inet_ntoa(in);
28 memcpy(dst, result, strlen(result) + 1);
33 if (size < INET6_ADDRSTRLEN) {
38 // Convert to an array of 8 host order shorts
39 const uint16_t* tuples = static_cast<const uint16_t*>(src);
40 uint16_t host_tuples[8];
41 int zero_run_start = -1;
42 int zero_run_end = -1;
43 for (int i = 0; i < 8; i++) {
44 host_tuples[i] = ntohs(tuples[i]);
45 if (host_tuples[i] == 0) {
46 if (zero_run_start == -1)
48 } else if (zero_run_start != -1 && zero_run_end == -1) {
53 if (zero_run_start != -1) {
54 if (zero_run_end == -1)
56 if (zero_run_end - zero_run_start < 2) {
62 // Mimick glibc's behaviour here and allow ipv4 address to be specified
63 // as either ::A.B.C.D or ::ffff:A.B.C.D.
64 if (zero_run_start == 0 &&
66 (zero_run_end == 5 && host_tuples[zero_run_end] == 0xffff))) {
67 if (zero_run_end == 5) {
68 strcpy(dst, "::ffff:");
72 inet_ntop(AF_INET, host_tuples + 6, dst + strlen(dst), INET_ADDRSTRLEN);
74 std::stringstream output;
75 for (int i = 0; i < 8; i++) {
76 if (i == zero_run_start) {
80 if (i > zero_run_start && i < zero_run_end)
82 output << std::hex << host_tuples[i];
83 if (i < 7 && i + 1 != zero_run_start)
86 memcpy(dst, output.str().c_str(), output.str().size() + 1);
97 #endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) ...