1
/* Copyright (c) 1996 by Internet Software Consortium.
3
* Permission to use, copy, modify, and distribute this software for any
4
* purpose with or without fee is hereby granted, provided that the above
5
* copyright notice and this permission notice appear in all copies.
7
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
8
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
9
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
10
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
11
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
12
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
13
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17
#include "apr_private.h"
18
#include "apr_arch_networkio.h"
20
#if APR_HAVE_SYS_TYPES_H
21
#include <sys/types.h>
23
#if APR_HAVE_SYS_SOCKET_H
24
#include <sys/socket.h>
26
#if APR_HAVE_NETINET_IN_H
27
#include <netinet/in.h>
29
#if APR_HAVE_ARPA_INET_H
30
#include <arpa/inet.h>
42
#define INT16SZ sizeof(apr_int16_t)
53
#if !defined(EAFNOSUPPORT) && defined(WSAEAFNOSUPPORT)
54
#define EAFNOSUPPORT WSAEAFNOSUPPORT
58
* WARNING: Don't even consider trying to compile this on a system where
59
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
62
static int inet_pton4 __P((const char *src, unsigned char *dst));
64
static int inet_pton6 __P((const char *src, unsigned char *dst));
68
* inet_pton(af, src, dst)
69
* convert from presentation format (which usually means ASCII printable)
70
* to network format (which is usually some kind of binary format).
72
* 1 if the address was valid for the specified address family
73
* 0 if the address wasn't valid (`dst' is untouched in this case)
74
* -1 if some other error occurred (`dst' is untouched in this case, too)
79
apr_inet_pton(int af, const char *src, void *dst)
83
return (inet_pton4(src, dst));
86
return (inet_pton6(src, dst));
96
* inet_pton4(src, dst)
97
* like inet_aton() but without all the hexadecimal and shorthand.
99
* 1 if `src' is a valid dotted quad, else 0.
101
* does not touch `dst' unless it's returning 1.
106
inet_pton4(const char *src, unsigned char *dst)
108
static const char digits[] = "0123456789";
109
int saw_digit, octets, ch;
110
unsigned char tmp[INADDRSZ], *tp;
115
while ((ch = *src++) != '\0') {
118
if ((pch = strchr(digits, ch)) != NULL) {
119
unsigned int new = *tp * 10 + (unsigned int)(pch - digits);
129
} else if (ch == '.' && saw_digit) {
140
memcpy(dst, tmp, INADDRSZ);
146
* inet_pton6(src, dst)
147
* convert presentation level address to network order binary form.
149
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
151
* (1) does not touch `dst' unless it's returning 1.
152
* (2) :: in a full address is silently ignored.
154
* inspired by Mark Andrews.
159
inet_pton6(const char *src, unsigned char *dst)
161
static const char xdigits_l[] = "0123456789abcdef",
162
xdigits_u[] = "0123456789ABCDEF";
163
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
164
const char *xdigits, *curtok;
168
memset((tp = tmp), '\0', IN6ADDRSZ);
169
endp = tp + IN6ADDRSZ;
171
/* Leading :: requires some special handling. */
178
while ((ch = *src++) != '\0') {
181
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
182
pch = strchr((xdigits = xdigits_u), ch);
185
val |= (pch - xdigits);
199
if (tp + INT16SZ > endp)
201
*tp++ = (unsigned char) (val >> 8) & 0xff;
202
*tp++ = (unsigned char) val & 0xff;
207
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
208
inet_pton4(curtok, tp) > 0) {
211
break; /* '\0' was seen by inet_pton4(). */
216
if (tp + INT16SZ > endp)
218
*tp++ = (unsigned char) (val >> 8) & 0xff;
219
*tp++ = (unsigned char) val & 0xff;
221
if (colonp != NULL) {
223
* Since some memmove()'s erroneously fail to handle
224
* overlapping regions, we'll do the shift by hand.
226
const int n = tp - colonp;
229
for (i = 1; i <= n; i++) {
230
endp[- i] = colonp[n - i];
237
memcpy(dst, tmp, IN6ADDRSZ);