Skip to content

Commit 6aa2ee2

Browse files
committed
missing from build
1 parent db990d2 commit 6aa2ee2

File tree

1 file changed

+236
-0
lines changed

1 file changed

+236
-0
lines changed

openbsd-compat/inet_net_pton.c

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
/* $OpenBSD: inet_net_pton.c,v 1.8 2013/11/25 18:23:51 deraadt 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 "includes.h"
22+
#ifndef HAVE_INET_NET_PTON
23+
24+
#include <sys/types.h>
25+
#include <sys/socket.h>
26+
#include <netinet/in.h>
27+
#include <arpa/inet.h>
28+
29+
#include <assert.h>
30+
#include <ctype.h>
31+
#include <errno.h>
32+
#include <stdio.h>
33+
#include <string.h>
34+
#include <stdlib.h>
35+
36+
static int inet_net_pton_ipv4(const char *, u_char *, size_t);
37+
static int inet_net_pton_ipv6(const char *, u_char *, size_t);
38+
39+
/*
40+
* static int
41+
* inet_net_pton(af, src, dst, size)
42+
* convert network number from presentation to network format.
43+
* accepts hex octets, hex strings, decimal octets, and /CIDR.
44+
* "size" is in bytes and describes "dst".
45+
* return:
46+
* number of bits, either imputed classfully or specified with /CIDR,
47+
* or -1 if some failure occurred (check errno). ENOENT means it was
48+
* not a valid network specification.
49+
* author:
50+
* Paul Vixie (ISC), June 1996
51+
*/
52+
int
53+
inet_net_pton(int af, const char *src, void *dst, size_t size)
54+
{
55+
switch (af) {
56+
case AF_INET:
57+
return (inet_net_pton_ipv4(src, dst, size));
58+
case AF_INET6:
59+
return (inet_net_pton_ipv6(src, dst, size));
60+
default:
61+
errno = EAFNOSUPPORT;
62+
return (-1);
63+
}
64+
}
65+
66+
/*
67+
* static int
68+
* inet_net_pton_ipv4(src, dst, size)
69+
* convert IPv4 network number from presentation to network format.
70+
* accepts hex octets, hex strings, decimal octets, and /CIDR.
71+
* "size" is in bytes and describes "dst".
72+
* return:
73+
* number of bits, either imputed classfully or specified with /CIDR,
74+
* or -1 if some failure occurred (check errno). ENOENT means it was
75+
* not an IPv4 network specification.
76+
* note:
77+
* network byte order assumed. this means 192.5.5.240/28 has
78+
* 0x11110000 in its fourth octet.
79+
* author:
80+
* Paul Vixie (ISC), June 1996
81+
*/
82+
static int
83+
inet_net_pton_ipv4(const char *src, u_char *dst, size_t size)
84+
{
85+
static const char
86+
xdigits[] = "0123456789abcdef",
87+
digits[] = "0123456789";
88+
int n, ch, tmp, dirty, bits;
89+
const u_char *odst = dst;
90+
91+
ch = (unsigned char)*src++;
92+
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
93+
&& isascii((unsigned char)src[1]) && isxdigit((unsigned char)src[1])) {
94+
/* Hexadecimal: Eat nybble string. */
95+
if (size <= 0)
96+
goto emsgsize;
97+
*dst = 0, dirty = 0;
98+
src++; /* skip x or X. */
99+
while ((ch = (unsigned char)*src++) != '\0' &&
100+
isascii(ch) && isxdigit(ch)) {
101+
if (isupper(ch))
102+
ch = tolower(ch);
103+
n = strchr(xdigits, ch) - xdigits;
104+
assert(n >= 0 && n <= 15);
105+
*dst |= n;
106+
if (!dirty++)
107+
*dst <<= 4;
108+
else if (size-- > 0)
109+
*++dst = 0, dirty = 0;
110+
else
111+
goto emsgsize;
112+
}
113+
if (dirty)
114+
size--;
115+
} else if (isascii(ch) && isdigit(ch)) {
116+
/* Decimal: eat dotted digit string. */
117+
for (;;) {
118+
tmp = 0;
119+
do {
120+
n = strchr(digits, ch) - digits;
121+
assert(n >= 0 && n <= 9);
122+
tmp *= 10;
123+
tmp += n;
124+
if (tmp > 255)
125+
goto enoent;
126+
} while ((ch = (unsigned char)*src++) != '\0' &&
127+
isascii(ch) && isdigit(ch));
128+
if (size-- <= 0)
129+
goto emsgsize;
130+
*dst++ = (u_char) tmp;
131+
if (ch == '\0' || ch == '/')
132+
break;
133+
if (ch != '.')
134+
goto enoent;
135+
ch = (unsigned char)*src++;
136+
if (!isascii(ch) || !isdigit(ch))
137+
goto enoent;
138+
}
139+
} else
140+
goto enoent;
141+
142+
bits = -1;
143+
if (ch == '/' && isascii((unsigned char)src[0]) &&
144+
isdigit((unsigned char)src[0]) && dst > odst) {
145+
/* CIDR width specifier. Nothing can follow it. */
146+
ch = (unsigned char)*src++; /* Skip over the /. */
147+
bits = 0;
148+
do {
149+
n = strchr(digits, ch) - digits;
150+
assert(n >= 0 && n <= 9);
151+
bits *= 10;
152+
bits += n;
153+
if (bits > 32)
154+
goto emsgsize;
155+
} while ((ch = (unsigned char)*src++) != '\0' &&
156+
isascii(ch) && isdigit(ch));
157+
if (ch != '\0')
158+
goto enoent;
159+
}
160+
161+
/* Firey death and destruction unless we prefetched EOS. */
162+
if (ch != '\0')
163+
goto enoent;
164+
165+
/* If nothing was written to the destination, we found no address. */
166+
if (dst == odst)
167+
goto enoent;
168+
/* If no CIDR spec was given, infer width from net class. */
169+
if (bits == -1) {
170+
if (*odst >= 240) /* Class E */
171+
bits = 32;
172+
else if (*odst >= 224) /* Class D */
173+
bits = 4;
174+
else if (*odst >= 192) /* Class C */
175+
bits = 24;
176+
else if (*odst >= 128) /* Class B */
177+
bits = 16;
178+
else /* Class A */
179+
bits = 8;
180+
/* If imputed mask is narrower than specified octets, widen. */
181+
if (bits < ((dst - odst) * 8))
182+
bits = (dst - odst) * 8;
183+
}
184+
/* Extend network to cover the actual mask. */
185+
while (bits > ((dst - odst) * 8)) {
186+
if (size-- <= 0)
187+
goto emsgsize;
188+
*dst++ = '\0';
189+
}
190+
return (bits);
191+
192+
enoent:
193+
errno = ENOENT;
194+
return (-1);
195+
196+
emsgsize:
197+
errno = EMSGSIZE;
198+
return (-1);
199+
}
200+
201+
202+
static int
203+
inet_net_pton_ipv6(const char *src, u_char *dst, size_t size)
204+
{
205+
int ret;
206+
int bits;
207+
char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")];
208+
char *sep;
209+
const char *errstr;
210+
211+
if (strlcpy(buf, src, sizeof buf) >= sizeof buf) {
212+
errno = EMSGSIZE;
213+
return (-1);
214+
}
215+
216+
sep = strchr(buf, '/');
217+
if (sep != NULL)
218+
*sep++ = '\0';
219+
220+
ret = inet_pton(AF_INET6, buf, dst);
221+
if (ret != 1)
222+
return (-1);
223+
224+
if (sep == NULL)
225+
return 128;
226+
227+
bits = strtonum(sep, 0, 128, &errstr);
228+
if (errstr) {
229+
errno = EINVAL;
230+
return (-1);
231+
}
232+
233+
return bits;
234+
}
235+
236+
#endif

0 commit comments

Comments
 (0)