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

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.
Sam Clegg 2013/12/06 20:57:03 C style comments here and below.
Sergey Ulanov 2013/12/06 21:15:44 Done.
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 for (int i = 0; i < kIpv4AddressSize; ++i) {
26 // strtol() won't treat whitespace characters in the beginning as an error,
27 // so check to ensure this is started with digit before passing to strtol().
28 if (isspace((int)(*pos)))
29 return 0;
30 char* end_pos;
31 unsigned long value = strtoul(pos, &end_pos, 10);
32 if (value > 255 || pos == end_pos)
33 return 0;
34 result[i] = (unsigned char)value;
35 pos = end_pos;
36
37 if (i < (kIpv4AddressSize - 1)) {
38 if (*pos != '.')
39 return 0;
40 ++pos;
41 }
42 }
43 if (*pos != '\0')
44 return 0;
45 memcpy(dst, result, sizeof(result));
46 return 1;
47 }
48
49 // Helper function for inet_pton() for IPv6 addresses.
50 int inet_pton_v6(const char* src, void* dst) {
51 // strtol() skips 0x in from of a number, while it's not allowed in IPv6
52 // addresses. Check that there is no 'x' in the string.
53 const char* pos = src;
54 while (*pos != '\0') {
55 if (*pos == 'x')
56 return 0;
57 pos++;
58 }
59 pos = src;
60
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((int)(*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 + kIpv4AddressSize > 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 int inet_pton(int af, const char *src, void *dst) {
132 if (!src || !dst) {
133 return 0;
134 }
135 if (af == AF_INET) {
136 return inet_pton_v4(src, dst);
137 } else if (af == AF_INET6) {
138 return inet_pton_v6(src, dst);
139 }
140 errno = EAFNOSUPPORT;
141 return -1;
142 }
143
144 #endif // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
145
Sam Clegg 2013/12/06 20:57:03 Remove trailing line
Sergey Ulanov 2013/12/06 21:15:44 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698