summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/inet_net_pton.c
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
committercvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
commiteb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch)
treeedb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libc/net/inet_net_pton.c
parent247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff)
downloadopenbsd-tb_20250414.tar.gz
openbsd-tb_20250414.tar.bz2
openbsd-tb_20250414.zip
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libc/net/inet_net_pton.c')
-rw-r--r--src/lib/libc/net/inet_net_pton.c246
1 files changed, 0 insertions, 246 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 c5baa4d6f4..0000000000
--- a/src/lib/libc/net/inet_net_pton.c
+++ /dev/null
@@ -1,246 +0,0 @@
1/* $OpenBSD: inet_net_pton.c,v 1.14 2022/12/27 17:10:06 jmc Exp $ */
2
3/*
4 * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org>
5 * Copyright (c) 1996,1999 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 = (unsigned char)*src++;
89 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
90 && isascii((unsigned char)src[1]) && isxdigit((unsigned char)src[1])) {
91 /* Hexadecimal: Eat nybble string. */
92 if (size == 0)
93 goto emsgsize;
94 tmp = 0, dirty = 0;
95 src++; /* skip x or X. */
96 while ((ch = (unsigned char)*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 if (dirty == 0)
103 tmp = n;
104 else
105 tmp = (tmp << 4) | n;
106 if (++dirty == 2) {
107 if (size-- == 0)
108 goto emsgsize;
109 *dst++ = (u_char) tmp;
110 dirty = 0;
111 }
112 }
113 if (dirty) { /* Odd trailing nybble? */
114 if (size-- == 0)
115 goto emsgsize;
116 *dst++ = (u_char) (tmp << 4);
117 }
118 } else if (isascii(ch) && isdigit(ch)) {
119 /* Decimal: eat dotted digit string. */
120 for (;;) {
121 tmp = 0;
122 do {
123 n = strchr(digits, ch) - digits;
124 assert(n >= 0 && n <= 9);
125 tmp *= 10;
126 tmp += n;
127 if (tmp > 255)
128 goto enoent;
129 } while ((ch = (unsigned char)*src++) != '\0' &&
130 isascii(ch) && isdigit(ch));
131 if (size-- == 0)
132 goto emsgsize;
133 *dst++ = (u_char) tmp;
134 if (ch == '\0' || ch == '/')
135 break;
136 if (ch != '.')
137 goto enoent;
138 ch = (unsigned char)*src++;
139 if (!isascii(ch) || !isdigit(ch))
140 goto enoent;
141 }
142 } else
143 goto enoent;
144
145 bits = -1;
146 if (ch == '/' && isascii((unsigned char)src[0]) &&
147 isdigit((unsigned char)src[0]) && dst > odst) {
148 /* CIDR width specifier. Nothing can follow it. */
149 ch = (unsigned char)*src++; /* Skip over the /. */
150 bits = 0;
151 do {
152 n = strchr(digits, ch) - digits;
153 assert(n >= 0 && n <= 9);
154 bits *= 10;
155 bits += n;
156 if (bits > 32)
157 goto emsgsize;
158 } while ((ch = (unsigned char)*src++) != '\0' &&
159 isascii(ch) && isdigit(ch));
160 if (ch != '\0')
161 goto enoent;
162 }
163
164 /* Fiery death and destruction unless we prefetched EOS. */
165 if (ch != '\0')
166 goto enoent;
167
168 /* If nothing was written to the destination, we found no address. */
169 if (dst == odst)
170 goto enoent;
171 /* If no CIDR spec was given, infer width from net class. */
172 if (bits == -1) {
173 if (*odst >= 240) /* Class E */
174 bits = 32;
175 else if (*odst >= 224) /* Class D */
176 bits = 4;
177 else if (*odst >= 192) /* Class C */
178 bits = 24;
179 else if (*odst >= 128) /* Class B */
180 bits = 16;
181 else /* Class A */
182 bits = 8;
183 /* If imputed mask is narrower than specified octets, widen. */
184 if (bits < ((dst - odst) * 8))
185 bits = (dst - odst) * 8;
186 }
187 /* Extend network to cover the actual mask. */
188 while (bits > ((dst - odst) * 8)) {
189 if (size-- == 0)
190 goto emsgsize;
191 *dst++ = '\0';
192 }
193 return (bits);
194
195 enoent:
196 errno = ENOENT;
197 return (-1);
198
199 emsgsize:
200 errno = EMSGSIZE;
201 return (-1);
202}
203
204
205static int
206inet_net_pton_ipv6(const char *src, u_char *dst, size_t size)
207{
208 struct in6_addr in6;
209 int ret;
210 int bits;
211 size_t bytes;
212 char buf[INET6_ADDRSTRLEN + sizeof("/128")];
213 char *sep;
214 const char *errstr;
215
216 if (strlcpy(buf, src, sizeof buf) >= sizeof buf) {
217 errno = EMSGSIZE;
218 return (-1);
219 }
220
221 sep = strchr(buf, '/');
222 if (sep != NULL)
223 *sep++ = '\0';
224
225 ret = inet_pton(AF_INET6, buf, &in6);
226 if (ret != 1)
227 return (-1);
228
229 if (sep == NULL)
230 bits = 128;
231 else {
232 bits = strtonum(sep, 0, 128, &errstr);
233 if (errstr) {
234 errno = EINVAL;
235 return (-1);
236 }
237 }
238
239 bytes = (bits + 7) / 8;
240 if (bytes > size) {
241 errno = EMSGSIZE;
242 return (-1);
243 }
244 memcpy(dst, &in6.s6_addr, bytes);
245 return (bits);
246}