summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/inet_net_pton.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/net/inet_net_pton.c')
-rw-r--r--src/lib/libc/net/inet_net_pton.c230
1 files changed, 0 insertions, 230 deletions
diff --git a/src/lib/libc/net/inet_net_pton.c b/src/lib/libc/net/inet_net_pton.c
deleted file mode 100644
index 74261399f7..0000000000
--- a/src/lib/libc/net/inet_net_pton.c
+++ /dev/null
@@ -1,230 +0,0 @@
1/* $OpenBSD: inet_net_pton.c,v 1.7 2012/06/22 19:13:37 gilles Exp $ */
2
3/*
4 * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org>
5 * Copyright (c) 1996 by Internet Software Consortium.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
12 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
13 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
14 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
17 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
18 * SOFTWARE.
19 */
20
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <arpa/inet.h>
25
26#include <assert.h>
27#include <ctype.h>
28#include <errno.h>
29#include <stdio.h>
30#include <string.h>
31#include <stdlib.h>
32
33static int inet_net_pton_ipv4(const char *, u_char *, size_t);
34static int inet_net_pton_ipv6(const char *, u_char *, size_t);
35
36/*
37 * static int
38 * inet_net_pton(af, src, dst, size)
39 * convert network number from presentation to network format.
40 * accepts hex octets, hex strings, decimal octets, and /CIDR.
41 * "size" is in bytes and describes "dst".
42 * return:
43 * number of bits, either imputed classfully or specified with /CIDR,
44 * or -1 if some failure occurred (check errno). ENOENT means it was
45 * not a valid network specification.
46 * author:
47 * Paul Vixie (ISC), June 1996
48 */
49int
50inet_net_pton(int af, const char *src, void *dst, size_t size)
51{
52 switch (af) {
53 case AF_INET:
54 return (inet_net_pton_ipv4(src, dst, size));
55 case AF_INET6:
56 return (inet_net_pton_ipv6(src, dst, size));
57 default:
58 errno = EAFNOSUPPORT;
59 return (-1);
60 }
61}
62
63/*
64 * static int
65 * inet_net_pton_ipv4(src, dst, size)
66 * convert IPv4 network number from presentation to network format.
67 * accepts hex octets, hex strings, decimal octets, and /CIDR.
68 * "size" is in bytes and describes "dst".
69 * return:
70 * number of bits, either imputed classfully or specified with /CIDR,
71 * or -1 if some failure occurred (check errno). ENOENT means it was
72 * not an IPv4 network specification.
73 * note:
74 * network byte order assumed. this means 192.5.5.240/28 has
75 * 0x11110000 in its fourth octet.
76 * author:
77 * Paul Vixie (ISC), June 1996
78 */
79static int
80inet_net_pton_ipv4(const char *src, u_char *dst, size_t size)
81{
82 static const char
83 xdigits[] = "0123456789abcdef",
84 digits[] = "0123456789";
85 int n, ch, tmp, dirty, bits;
86 const u_char *odst = dst;
87
88 ch = *src++;
89 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
90 && isascii(src[1]) && isxdigit(src[1])) {
91 /* Hexadecimal: Eat nybble string. */
92 if (size <= 0)
93 goto emsgsize;
94 *dst = 0, dirty = 0;
95 src++; /* skip x or X. */
96 while ((ch = *src++) != '\0' &&
97 isascii(ch) && isxdigit(ch)) {
98 if (isupper(ch))
99 ch = tolower(ch);
100 n = strchr(xdigits, ch) - xdigits;
101 assert(n >= 0 && n <= 15);
102 *dst |= n;
103 if (!dirty++)
104 *dst <<= 4;
105 else if (size-- > 0)
106 *++dst = 0, dirty = 0;
107 else
108 goto emsgsize;
109 }
110 if (dirty)
111 size--;
112 } else if (isascii(ch) && isdigit(ch)) {
113 /* Decimal: eat dotted digit string. */
114 for (;;) {
115 tmp = 0;
116 do {
117 n = strchr(digits, ch) - digits;
118 assert(n >= 0 && n <= 9);
119 tmp *= 10;
120 tmp += n;
121 if (tmp > 255)
122 goto enoent;
123 } while ((ch = *src++) != '\0' &&
124 isascii(ch) && isdigit(ch));
125 if (size-- <= 0)
126 goto emsgsize;
127 *dst++ = (u_char) tmp;
128 if (ch == '\0' || ch == '/')
129 break;
130 if (ch != '.')
131 goto enoent;
132 ch = *src++;
133 if (!isascii(ch) || !isdigit(ch))
134 goto enoent;
135 }
136 } else
137 goto enoent;
138
139 bits = -1;
140 if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
141 /* CIDR width specifier. Nothing can follow it. */
142 ch = *src++; /* Skip over the /. */
143 bits = 0;
144 do {
145 n = strchr(digits, ch) - digits;
146 assert(n >= 0 && n <= 9);
147 bits *= 10;
148 bits += n;
149 if (bits > 32)
150 goto emsgsize;
151 } while ((ch = *src++) != '\0' &&
152 isascii(ch) && isdigit(ch));
153 if (ch != '\0')
154 goto enoent;
155 }
156
157 /* Firey death and destruction unless we prefetched EOS. */
158 if (ch != '\0')
159 goto enoent;
160
161 /* If nothing was written to the destination, we found no address. */
162 if (dst == odst)
163 goto enoent;
164 /* If no CIDR spec was given, infer width from net class. */
165 if (bits == -1) {
166 if (*odst >= 240) /* Class E */
167 bits = 32;
168 else if (*odst >= 224) /* Class D */
169 bits = 4;
170 else if (*odst >= 192) /* Class C */
171 bits = 24;
172 else if (*odst >= 128) /* Class B */
173 bits = 16;
174 else /* Class A */
175 bits = 8;
176 /* If imputed mask is narrower than specified octets, widen. */
177 if (bits < ((dst - odst) * 8))
178 bits = (dst - odst) * 8;
179 }
180 /* Extend network to cover the actual mask. */
181 while (bits > ((dst - odst) * 8)) {
182 if (size-- <= 0)
183 goto emsgsize;
184 *dst++ = '\0';
185 }
186 return (bits);
187
188 enoent:
189 errno = ENOENT;
190 return (-1);
191
192 emsgsize:
193 errno = EMSGSIZE;
194 return (-1);
195}
196
197
198static int
199inet_net_pton_ipv6(const char *src, u_char *dst, size_t size)
200{
201 int ret;
202 int bits;
203 char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")];
204 char *sep;
205 const char *errstr;
206
207 if (strlcpy(buf, src, sizeof buf) >= sizeof buf) {
208 errno = EMSGSIZE;
209 return (-1);
210 }
211
212 sep = strchr(buf, '/');
213 if (sep != NULL)
214 *sep++ = '\0';
215
216 ret = inet_pton(AF_INET6, buf, dst);
217 if (ret != 1)
218 return (-1);
219
220 if (sep == NULL)
221 return 128;
222
223 bits = strtonum(sep, 0, 128, &errstr);
224 if (errstr) {
225 errno = EINVAL;
226 return (-1);
227 }
228
229 return bits;
230}