+
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996,1999 by Internet Software Consortium.
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "setup.h"
-
-
-#include <sys/types.h>
+#include "ares_setup.h"
-#if defined(WIN32) && !defined(WATT32)
-#include "nameser.h"
-#else
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
#endif
-#endif
+#include "ares.h"
+#include "ares_ipv6.h"
+#include "ares_nowarn.h"
+#include "ares_inet_net_pton.h"
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "ares_ipv6.h"
-#include "inet_net_pton.h"
+const struct ares_in6_addr ares_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
+
-#if !defined(HAVE_INET_NET_PTON) || !defined(HAVE_INET_NET_PTON_IPV6) || \
- !defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6)
+#ifndef HAVE_INET_NET_PTON
/*
* static int
* note:
* network byte order assumed. this means 192.5.5.240/28 has
* 0b11110000 in its fourth octet.
+ * note:
+ * On Windows we store the error in the thread errno, not
+ * in the winsock error code. This is to avoid loosing the
+ * actual last winsock error. So use macro ERRNO to fetch the
+ * errno this funtion sets when returning (-1), not SOCKERRNO.
* author:
* Paul Vixie (ISC), June 1996
*/
ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
- && isascii((unsigned char)(src[1]))
- && isxdigit((unsigned char)(src[1]))) {
+ && ISASCII(src[1])
+ && ISXDIGIT(src[1])) {
/* Hexadecimal: Eat nybble string. */
- if (size <= 0U)
+ if (!size)
goto emsgsize;
dirty = 0;
src++; /* skip x or X. */
- while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
- if (isupper(ch))
+ while ((ch = *src++) != '\0' && ISASCII(ch) && ISXDIGIT(ch)) {
+ if (ISUPPER(ch))
ch = tolower(ch);
- n = (int)(strchr(xdigits, ch) - xdigits);
+ n = aresx_sztosi(strchr(xdigits, ch) - xdigits);
if (dirty == 0)
tmp = n;
else
tmp = (tmp << 4) | n;
if (++dirty == 2) {
- if (size-- <= 0U)
+ if (!size--)
goto emsgsize;
*dst++ = (unsigned char) tmp;
dirty = 0;
}
}
if (dirty) { /* Odd trailing nybble? */
- if (size-- <= 0U)
+ if (!size--)
goto emsgsize;
*dst++ = (unsigned char) (tmp << 4);
}
- } else if (isascii(ch) && isdigit(ch)) {
+ } else if (ISASCII(ch) && ISDIGIT(ch)) {
/* Decimal: eat dotted digit string. */
for (;;) {
tmp = 0;
do {
- n = (int)(strchr(digits, ch) - digits);
+ n = aresx_sztosi(strchr(digits, ch) - digits);
tmp *= 10;
tmp += n;
if (tmp > 255)
goto enoent;
} while ((ch = *src++) != '\0' &&
- isascii(ch) && isdigit(ch));
- if (size-- <= 0U)
+ ISASCII(ch) && ISDIGIT(ch));
+ if (!size--)
goto emsgsize;
*dst++ = (unsigned char) tmp;
if (ch == '\0' || ch == '/')
if (ch != '.')
goto enoent;
ch = *src++;
- if (!isascii(ch) || !isdigit(ch))
+ if (!ISASCII(ch) || !ISDIGIT(ch))
goto enoent;
}
} else
goto enoent;
bits = -1;
- if (ch == '/' && isascii((unsigned char)(src[0])) &&
- isdigit((unsigned char)(src[0])) && dst > odst) {
+ if (ch == '/' && ISASCII(src[0]) &&
+ ISDIGIT(src[0]) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */
ch = *src++; /* Skip over the /. */
bits = 0;
do {
- n = (int)(strchr(digits, ch) - digits);
+ n = aresx_sztosi(strchr(digits, ch) - digits);
bits *= 10;
bits += n;
- } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
+ if (bits > 32)
+ goto enoent;
+ } while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch));
if (ch != '\0')
goto enoent;
- if (bits > 32)
- goto emsgsize;
}
/* Firey death and destruction unless we prefetched EOS. */
bits = 8;
/* If imputed mask is narrower than specified octets, widen. */
if (bits < ((dst - odst) * 8))
- bits = (int)(dst - odst) * 8;
+ bits = aresx_sztosi(dst - odst) * 8;
/*
* If there are no additional bits specified for a class D
* address adjust bits to 4.
}
/* Extend network to cover the actual mask. */
while (bits > ((dst - odst) * 8)) {
- if (size-- <= 0U)
+ if (!size--)
goto emsgsize;
*dst++ = '\0';
}
return (bits);
enoent:
- errno = ENOENT;
+ SET_ERRNO(ENOENT);
return (-1);
emsgsize:
- errno = EMSGSIZE;
+ SET_ERRNO(EMSGSIZE);
return (-1);
}
if (n++ != 0 && val == 0) /* no leading zeros */
return (0);
val *= 10;
- val += (pch - digits);
+ val += aresx_sztosi(pch - digits);
if (val > 128) /* range */
return (0);
continue;
if (n++ != 0 && val == 0) /* no leading zeros */
return (0);
val *= 10;
- val += (pch - digits);
+ val += aresx_sztoui(pch - digits);
if (val > 255) /* range */
return (0);
continue;
if (ch == '.' || ch == '/') {
if (dst - odst > 3) /* too many octets? */
return (0);
- *dst++ = val;
+ *dst++ = (unsigned char)val;
if (ch == '/')
return (getbits(src, bitsp));
val = 0;
return (0);
if (dst - odst > 3) /* too many octets? */
return (0);
- *dst++ = val;
- return (1);
+ *dst = (unsigned char)val;
+ return 1;
}
static int
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
- val |= (pch - xdigits);
+ val |= aresx_sztoui(pch - xdigits);
if (++digits > 4)
goto enoent;
saw_xdigit = 1;
goto enoent;
if (tp + NS_INT16SZ > endp)
return (0);
- *tp++ = (unsigned char) (val >> 8) & 0xff;
- *tp++ = (unsigned char) val & 0xff;
+ *tp++ = (unsigned char)((val >> 8) & 0xff);
+ *tp++ = (unsigned char)(val & 0xff);
saw_xdigit = 0;
digits = 0;
val = 0;
if (saw_xdigit) {
if (tp + NS_INT16SZ > endp)
goto enoent;
- *tp++ = (unsigned char) (val >> 8) & 0xff;
- *tp++ = (unsigned char) val & 0xff;
+ *tp++ = (unsigned char)((val >> 8) & 0xff);
+ *tp++ = (unsigned char)(val & 0xff);
}
if (bits == -1)
bits = 128;
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
- const int n = (int)(tp - colonp);
- int i;
+ const ssize_t n = tp - colonp;
+ ssize_t i;
if (tp == endp)
goto enoent;
for (i = 1; i <= n; i++) {
- endp[- i] = colonp[n - i];
- colonp[n - i] = 0;
+ *(endp - i) = *(colonp + n - i);
+ *(colonp + n - i) = 0;
}
tp = endp;
}
return (bits);
enoent:
- errno = ENOENT;
+ SET_ERRNO(ENOENT);
return (-1);
emsgsize:
- errno = EMSGSIZE;
+ SET_ERRNO(EMSGSIZE);
return (-1);
}
* number of bits, either imputed classfully or specified with /CIDR,
* or -1 if some failure occurred (check errno). ENOENT means it was
* not a valid network specification.
+ * note:
+ * On Windows we store the error in the thread errno, not
+ * in the winsock error code. This is to avoid loosing the
+ * actual last winsock error. So use macro ERRNO to fetch the
+ * errno this funtion sets when returning (-1), not SOCKERRNO.
* author:
* Paul Vixie (ISC), June 1996
*/
case AF_INET6:
return (inet_net_pton_ipv6(src, dst, size));
default:
- errno = EAFNOSUPPORT;
+ SET_ERRNO(EAFNOSUPPORT);
return (-1);
}
}
-#endif
+#endif /* HAVE_INET_NET_PTON */
-#if !defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6)
+#ifndef HAVE_INET_PTON
int ares_inet_pton(int af, const char *src, void *dst)
{
- int size, result;
+ int result;
+ size_t size;
if (af == AF_INET)
size = sizeof(struct in_addr);
else if (af == AF_INET6)
- size = sizeof(struct in6_addr);
+ size = sizeof(struct ares_in6_addr);
else
{
- errno = EAFNOSUPPORT;
+ SET_ERRNO(EAFNOSUPPORT);
return -1;
}
result = ares_inet_net_pton(af, src, dst, size);
- if (result == -1 && errno == ENOENT)
+ if (result == -1 && ERRNO == ENOENT)
return 0;
return (result > -1 ? 1 : -1);
}
+#else /* HAVE_INET_PTON */
+int ares_inet_pton(int af, const char *src, void *dst)
+{
+ /* just relay this to the underlying function */
+ return inet_pton(af, src, dst);
+}
+
#endif