Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/syscalls/inet_pton.cc

Issue 105943006: nacl_io: Add inet_pton() and ip6addr_* consts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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__)
7
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include <iostream>
13 #include <sstream>
14 #include <string>
Sam Clegg 2013/12/06 02:31:36 Are you using any of these C++ headers? If not ca
Sergey Ulanov 2013/12/06 20:20:22 No, removed.
15
16 #include "sdk_util/macros.h"
17
18 // Helper function for inet_pton() for IPv4 addresses.
19 static int inet_pton_v4(const char* src, void* dst) {
20 const int kIpv4AddressSize = 4;
21 const char* pos = src;
22 uint8_t result[kIpv4AddressSize] = {0};
23
24 for (int i = 0; i < kIpv4AddressSize; ++i) {
25 // strtol() won't treat whitespace characters in the beginning as an error,
26 // so check to ensure this is started with digit before passing to strtol().
27 if (isspace(*pos))
28 return 0;
29 char* end_pos;
30 unsigned long value = strtoul(pos, &end_pos, 10);
31 if (value > 255 || pos == end_pos)
32 return 0;
33 result[i] = static_cast<unsigned char>(value);
34 pos = end_pos;
35
36 if (i < (kIpv4AddressSize - 1)) {
37 if (*pos != '.')
38 return 0;
39 ++pos;
40 }
41 }
42 if (*pos != '\0')
43 return 0;
44 memcpy(dst, result, sizeof(result));
45 return 1;
46 }
47
48 // Helper function for inet_pton() for IPv6 addresses.
49 int inet_pton_v6(const char* src, void* dst) {
50 // strtol() skips 0x in from of a number, while it's not allowed in IPv6
51 // addresses. Check that there is no 'x' in the string.
52 const char* pos = src;
53 while (*pos != '\0') {
54 if (*pos == 'x')
55 return 0;
56 pos++;
57 }
58 pos = src;
59
60 int kIpv6AddressSize = 16;
61 uint8_t result[kIpv6AddressSize];
62 memset(&result, 0, sizeof(result));
63 int double_colon_pos = -1;
64 int result_pos = 0;
65
66 if (*pos == ':') {
67 if (*(pos + 1) != ':')
68 return 0;
69 pos += 2;
70 double_colon_pos = 0;
71 }
72
73 while (*pos != '\0') {
74 // strtol() won't treat whitespace characters in the beginning as an error,
75 // so check to ensure this is started with digit before passing to strtol().
76 if (isspace(*pos))
77 return 0;
78 char* end_pos;
79 unsigned long word = strtoul(pos, &end_pos, 16);
80 if (word > 0xffff || pos == end_pos)
81 return 0;
82
83 if (*end_pos == '.') {
84 if (result_pos + 4 > kIpv6AddressSize)
85 return 0;
86 // Parse rest of address as IPv4 address.
87 if (!inet_pton_v4(pos, result + result_pos))
88 return 0;
89 result_pos += 4;
90 break;
91 }
92
93 if (result_pos > kIpv6AddressSize - 2)
94 return 0;
95 result[result_pos] = (word & 0xFF00) >> 8;
96 result[result_pos + 1] = word & 0xFF;
97 result_pos += 2;
98
99 if (*end_pos == '\0')
100 break;
101
102 if (*end_pos != ':')
103 return 0;
104
105 pos = end_pos + 1;
106 if (*pos == ':') {
107 if (double_colon_pos != -1)
108 return 0;
109 double_colon_pos = result_pos;
110 ++pos;
111 }
112 }
113
114 // Finally move the data to the end in case the address contained '::'.
115 if (result_pos < kIpv6AddressSize) {
116 if (double_colon_pos == -1)
117 return 0;
118 int move_size = result_pos - double_colon_pos;
119 int gap_size = kIpv6AddressSize - result_pos;
120 memmove(result + kIpv6AddressSize - move_size,
121 result + double_colon_pos, move_size);
122 memset(result + double_colon_pos, 0, gap_size);
123 }
124
125 // Finally copy the result to the output buffer.
126 memcpy(dst, result, sizeof(result));
127
128 return 1;
129 }
130
131 EXTERN_C_BEGIN
132
133 int inet_pton(int af, const char *src, void *dst) {
134 if (!src || !dst) {
135 return 0;
136 }
137 if (af == AF_INET) {
138 return inet_pton_v4(src, dst);
139 } else if (af == AF_INET6) {
140 return inet_pton_v6(src, dst);
141 }
142 errno = EAFNOSUPPORT;
143 return -1;
144 }
145
146 EXTERN_C_END
147
148 #endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
149
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698