OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "nacl_io/ossocket.h" | 5 #include "nacl_io/ossocket.h" |
6 #if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) | 6 #if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) |
7 | 7 |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <string.h> | 9 #include <string.h> |
10 | 10 |
11 #include <iostream> | 11 #include <iostream> |
12 #include <sstream> | 12 #include <sstream> |
13 #include <string> | 13 #include <string> |
14 | 14 |
15 #include "sdk_util/macros.h" | 15 #include "sdk_util/macros.h" |
16 | 16 |
17 | |
18 EXTERN_C_BEGIN | 17 EXTERN_C_BEGIN |
19 | 18 |
20 const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) { | 19 const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) { |
21 if (AF_INET == af) { | 20 if (AF_INET == af) { |
22 if (size < INET_ADDRSTRLEN) { | 21 if (size < INET_ADDRSTRLEN) { |
23 errno = ENOSPC; | 22 errno = ENOSPC; |
24 return NULL; | 23 return NULL; |
25 } | 24 } |
26 struct in_addr in; | 25 struct in_addr in; |
27 memcpy(&in, src, sizeof(in)); | 26 memcpy(&in, src, sizeof(in)); |
28 char* result = inet_ntoa(in); | 27 char* result = inet_ntoa(in); |
29 memcpy(dst, result, strlen(result) + 1); | 28 memcpy(dst, result, strlen(result) + 1); |
30 return dst; | 29 return dst; |
31 } | 30 } |
32 | 31 |
33 if (AF_INET6 == af) { | 32 if (AF_INET6 == af) { |
34 if (size < INET6_ADDRSTRLEN) { | 33 if (size < INET6_ADDRSTRLEN) { |
35 errno = ENOSPC; | 34 errno = ENOSPC; |
36 return NULL; | 35 return NULL; |
37 } | 36 } |
38 const uint8_t* tuples = static_cast<const uint8_t*>(src); | 37 |
39 std::stringstream output; | 38 // Convert to an arry of 8 host order shorts |
binji
2014/01/27 19:57:18
sp: array
| |
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; | |
40 for (int i = 0; i < 8; i++) { | 43 for (int i = 0; i < 8; i++) { |
41 uint16_t tuple = (tuples[2*i] << 8) + tuples[2*i+1]; | 44 host_tuples[i] = ntohs(tuples[i]); |
42 output << std::hex << tuple; | 45 if (host_tuples[i] == 0) { |
43 if (i < 7) { | 46 if (zero_run_start == -1) |
44 output << ":"; | 47 zero_run_start = i; |
48 } else if (zero_run_start != -1 && zero_run_end == -1) { | |
49 zero_run_end = i; | |
45 } | 50 } |
46 } | 51 } |
47 memcpy(dst, output.str().c_str(), output.str().size() + 1); | 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 && (zero_run_end == 6 || (zero_run_end == 5 && | |
binji
2014/01/27 19:57:18
might be clearer if you moved the condition after
Sam Clegg
2014/01/27 23:10:15
Done.
| |
65 host_tuples[zero_run_end] == 0xffff))) { | |
66 | |
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 } | |
48 return dst; | 88 return dst; |
49 } | 89 } |
50 | 90 |
51 errno = EAFNOSUPPORT; | 91 errno = EAFNOSUPPORT; |
52 return NULL; | 92 return NULL; |
53 } | 93 } |
54 | 94 |
55 EXTERN_C_END | 95 EXTERN_C_END |
56 | 96 |
57 #endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) | 97 #endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) |
58 | |
OLD | NEW |