| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "nacl_io/ossocket.h" | |
| 6 #if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) && !defined(__BIONIC__) | |
| 7 | |
| 8 #include <errno.h> | |
| 9 #include <string.h> | |
| 10 | |
| 11 #include <iostream> | |
| 12 #include <sstream> | |
| 13 #include <string> | |
| 14 | |
| 15 #include "sdk_util/macros.h" | |
| 16 | |
| 17 EXTERN_C_BEGIN | |
| 18 | |
| 19 const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) { | |
| 20 if (AF_INET == af) { | |
| 21 if (size < INET_ADDRSTRLEN) { | |
| 22 errno = ENOSPC; | |
| 23 return NULL; | |
| 24 } | |
| 25 struct in_addr in; | |
| 26 memcpy(&in, src, sizeof(in)); | |
| 27 char* result = inet_ntoa(in); | |
| 28 memcpy(dst, result, strlen(result) + 1); | |
| 29 return dst; | |
| 30 } | |
| 31 | |
| 32 if (AF_INET6 == af) { | |
| 33 if (size < INET6_ADDRSTRLEN) { | |
| 34 errno = ENOSPC; | |
| 35 return NULL; | |
| 36 } | |
| 37 | |
| 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) | |
| 47 zero_run_start = i; | |
| 48 } else if (zero_run_start != -1 && zero_run_end == -1) { | |
| 49 zero_run_end = i; | |
| 50 } | |
| 51 } | |
| 52 | |
| 53 if (zero_run_start != -1) { | |
| 54 if (zero_run_end == -1) | |
| 55 zero_run_end = 8; | |
| 56 if (zero_run_end - zero_run_start < 2) { | |
| 57 zero_run_start = -1; | |
| 58 zero_run_end = -1; | |
| 59 } | |
| 60 } | |
| 61 | |
| 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 && | |
| 65 (zero_run_end == 6 || | |
| 66 (zero_run_end == 5 && host_tuples[zero_run_end] == 0xffff))) { | |
| 67 if (zero_run_end == 5) { | |
| 68 strcpy(dst, "::ffff:"); | |
| 69 } else { | |
| 70 strcpy(dst, "::"); | |
| 71 } | |
| 72 inet_ntop(AF_INET, host_tuples + 6, dst + strlen(dst), INET_ADDRSTRLEN); | |
| 73 } else { | |
| 74 std::stringstream output; | |
| 75 for (int i = 0; i < 8; i++) { | |
| 76 if (i == zero_run_start) { | |
| 77 output << "::"; | |
| 78 continue; | |
| 79 } | |
| 80 if (i > zero_run_start && i < zero_run_end) | |
| 81 continue; | |
| 82 output << std::hex << host_tuples[i]; | |
| 83 if (i < 7 && i + 1 != zero_run_start) | |
| 84 output << ":"; | |
| 85 } | |
| 86 memcpy(dst, output.str().c_str(), output.str().size() + 1); | |
| 87 } | |
| 88 return dst; | |
| 89 } | |
| 90 | |
| 91 errno = EAFNOSUPPORT; | |
| 92 return NULL; | |
| 93 } | |
| 94 | |
| 95 EXTERN_C_END | |
| 96 | |
| 97 #endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) ... | |
| OLD | NEW |