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

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

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 <ctype.h>
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "sdk_util/macros.h"
14
15 enum {
16 kIpv4AddressSize = 4,
17 kIpv6AddressSize = 16,
18 };
19
20 /* Helper function for inet_pton() for IPv4 addresses. */
21 static int inet_pton_v4(const char* src, void* dst) {
22 const char* pos = src;
23 uint8_t result[kIpv4AddressSize] = {0};
24
25 int i;
26 for (i = 0; i < kIpv4AddressSize; ++i) {
27 /* strtol() won't treat whitespace characters in the beginning as an error,
28 * so check to ensure this is started with digit before passing to strtol().
29 */
30 if (isspace((int)(*pos)))
31 return 0;
32 char* end_pos;
33 unsigned long value = strtoul(pos, &end_pos, 10);
34 if (value > 255 || pos == end_pos)
35 return 0;
36 result[i] = (unsigned char)value;
37 pos = end_pos;
38
39 if (i < (kIpv4AddressSize - 1)) {
40 if (*pos != '.')
41 return 0;
42 ++pos;
43 }
44 }
45 if (*pos != '\0')
46 return 0;
47 memcpy(dst, result, sizeof(result));
48 return 1;
49 }
50
51 /* Helper function for inet_pton() for IPv6 addresses. */
52 int inet_pton_v6(const char* src, void* dst) {
53 /* strtol() skips 0x in from of a number, while it's not allowed in IPv6
54 * addresses. Check that there is no 'x' in the string. */
55 const char* pos = src;
56 while (*pos != '\0') {
57 if (*pos == 'x')
58 return 0;
59 pos++;
60 }
61 pos = src;
62
63 uint8_t result[kIpv6AddressSize];
64 memset(&result, 0, sizeof(result));
65 int double_colon_pos = -1;
66 int result_pos = 0;
67
68 if (*pos == ':') {
69 if (*(pos + 1) != ':')
70 return 0;
71 pos += 2;
72 double_colon_pos = 0;
73 }
74
75 while (*pos != '\0') {
76 /* strtol() won't treat whitespace characters in the beginning as an error,
77 * so check to ensure this is started with digit before passing to strtol().
78 */
79 if (isspace((int)(*pos)))
80 return 0;
81 char* end_pos;
82 unsigned long word = strtoul(pos, &end_pos, 16);
83 if (word > 0xffff || pos == end_pos)
84 return 0;
85
86 if (*end_pos == '.') {
87 if (result_pos + kIpv4AddressSize > kIpv6AddressSize)
88 return 0;
89 /* Parse rest of address as IPv4 address. */
90 if (!inet_pton_v4(pos, result + result_pos))
91 return 0;
92 result_pos += 4;
93 break;
94 }
95
96 if (result_pos > kIpv6AddressSize - 2)
97 return 0;
98 result[result_pos] = (word & 0xFF00) >> 8;
99 result[result_pos + 1] = word & 0xFF;
100 result_pos += 2;
101
102 if (*end_pos == '\0')
103 break;
104
105 if (*end_pos != ':')
106 return 0;
107
108 pos = end_pos + 1;
109 if (*pos == ':') {
110 if (double_colon_pos != -1)
111 return 0;
112 double_colon_pos = result_pos;
113 ++pos;
114 }
115 }
116
117 /* Finally move the data to the end in case the address contained '::'. */
118 if (result_pos < kIpv6AddressSize) {
119 if (double_colon_pos == -1)
120 return 0;
121 int move_size = result_pos - double_colon_pos;
122 int gap_size = kIpv6AddressSize - result_pos;
123 memmove(result + kIpv6AddressSize - move_size,
124 result + double_colon_pos, move_size);
125 memset(result + double_colon_pos, 0, gap_size);
126 }
127
128 /* Finally copy the result to the output buffer. */
129 memcpy(dst, result, sizeof(result));
130
131 return 1;
132 }
133
134 int inet_pton(int af, const char *src, void *dst) {
135 if (!src || !dst) {
136 return 0;
137 }
138 if (af == AF_INET) {
139 return inet_pton_v4(src, dst);
140 } else if (af == AF_INET6) {
141 return inet_pton_v6(src, dst);
142 }
143 errno = EAFNOSUPPORT;
144 return -1;
145 }
146
147 #endif /* defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698