1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 15:48:49 -05:00

indented source to look more like other ares code,

added (somewhat ugly) typecasts to build warning-free on 64bit platforms (the
result of a (char *) - (char *) cannot be stored in an int universally)
This commit is contained in:
Daniel Stenberg 2005-04-19 23:36:21 +00:00
parent e78ddf0a95
commit b3a8f438fc

View File

@ -54,380 +54,386 @@
/* /*
* static int * static int
* inet_net_pton_ipv4(src, dst, size) * inet_net_pton_ipv4(src, dst, size)
* convert IPv4 network number from presentation to network format. * convert IPv4 network number from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR. * accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst". * "size" is in bytes and describes "dst".
* return: * return:
* number of bits, either imputed classfully or specified with /CIDR, * number of bits, either imputed classfully or specified with /CIDR,
* or -1 if some failure occurred (check errno). ENOENT means it was * or -1 if some failure occurred (check errno). ENOENT means it was
* not an IPv4 network specification. * not an IPv4 network specification.
* note: * note:
* network byte order assumed. this means 192.5.5.240/28 has * network byte order assumed. this means 192.5.5.240/28 has
* 0b11110000 in its fourth octet. * 0b11110000 in its fourth octet.
* author: * author:
* Paul Vixie (ISC), June 1996 * Paul Vixie (ISC), June 1996
*/ */
static int static int
inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) { inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
static const char xdigits[] = "0123456789abcdef"; {
static const char digits[] = "0123456789"; static const char xdigits[] = "0123456789abcdef";
int n, ch, tmp = 0, dirty, bits; static const char digits[] = "0123456789";
const unsigned char *odst = dst; int n, ch, tmp = 0, dirty, bits;
const unsigned char *odst = dst;
ch = *src++; ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X') if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
&& isascii((unsigned char)(src[1])) && isascii((unsigned char)(src[1]))
&& isxdigit((unsigned char)(src[1]))) { && isxdigit((unsigned char)(src[1]))) {
/* Hexadecimal: Eat nybble string. */ /* Hexadecimal: Eat nybble string. */
if (size <= 0U) if (size <= 0U)
goto emsgsize; goto emsgsize;
dirty = 0; dirty = 0;
src++; /* skip x or X. */ src++; /* skip x or X. */
while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) { while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
if (isupper(ch)) if (isupper(ch))
ch = tolower(ch); ch = tolower(ch);
n = strchr(xdigits, ch) - xdigits; n = (int)(strchr(xdigits, ch) - xdigits);
if (dirty == 0) if (dirty == 0)
tmp = n; tmp = n;
else else
tmp = (tmp << 4) | n; tmp = (tmp << 4) | n;
if (++dirty == 2) { if (++dirty == 2) {
if (size-- <= 0U) if (size-- <= 0U)
goto emsgsize; goto emsgsize;
*dst++ = (unsigned char) tmp; *dst++ = (unsigned char) tmp;
dirty = 0; dirty = 0;
} }
} }
if (dirty) { /* Odd trailing nybble? */ if (dirty) { /* Odd trailing nybble? */
if (size-- <= 0U) if (size-- <= 0U)
goto emsgsize; goto emsgsize;
*dst++ = (unsigned char) (tmp << 4); *dst++ = (unsigned char) (tmp << 4);
} }
} else if (isascii(ch) && isdigit(ch)) { } else if (isascii(ch) && isdigit(ch)) {
/* Decimal: eat dotted digit string. */ /* Decimal: eat dotted digit string. */
for (;;) { for (;;) {
tmp = 0; tmp = 0;
do { do {
n = strchr(digits, ch) - digits; n = (int)(strchr(digits, ch) - digits);
tmp *= 10; tmp *= 10;
tmp += n; tmp += n;
if (tmp > 255) if (tmp > 255)
goto enoent; goto enoent;
} while ((ch = *src++) != '\0' && } while ((ch = *src++) != '\0' &&
isascii(ch) && isdigit(ch)); isascii(ch) && isdigit(ch));
if (size-- <= 0U) if (size-- <= 0U)
goto emsgsize; goto emsgsize;
*dst++ = (unsigned char) tmp; *dst++ = (unsigned char) tmp;
if (ch == '\0' || ch == '/') if (ch == '\0' || ch == '/')
break; break;
if (ch != '.') if (ch != '.')
goto enoent; goto enoent;
ch = *src++; ch = *src++;
if (!isascii(ch) || !isdigit(ch)) if (!isascii(ch) || !isdigit(ch))
goto enoent; goto enoent;
} }
} else } else
goto enoent; goto enoent;
bits = -1; bits = -1;
if (ch == '/' && isascii((unsigned char)(src[0])) && if (ch == '/' && isascii((unsigned char)(src[0])) &&
isdigit((unsigned char)(src[0])) && dst > odst) { isdigit((unsigned char)(src[0])) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */ /* CIDR width specifier. Nothing can follow it. */
ch = *src++; /* Skip over the /. */ ch = *src++; /* Skip over the /. */
bits = 0; bits = 0;
do { do {
n = strchr(digits, ch) - digits; n = (int)(strchr(digits, ch) - digits);
bits *= 10; bits *= 10;
bits += n; bits += n;
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
if (ch != '\0') if (ch != '\0')
goto enoent; goto enoent;
if (bits > 32) if (bits > 32)
goto emsgsize; goto emsgsize;
} }
/* Firey death and destruction unless we prefetched EOS. */ /* Firey death and destruction unless we prefetched EOS. */
if (ch != '\0') if (ch != '\0')
goto enoent; goto enoent;
/* If nothing was written to the destination, we found no address. */ /* If nothing was written to the destination, we found no address. */
if (dst == odst) if (dst == odst)
goto enoent; goto enoent;
/* If no CIDR spec was given, infer width from net class. */ /* If no CIDR spec was given, infer width from net class. */
if (bits == -1) { if (bits == -1) {
if (*odst >= 240) /* Class E */ if (*odst >= 240) /* Class E */
bits = 32; bits = 32;
else if (*odst >= 224) /* Class D */ else if (*odst >= 224) /* Class D */
bits = 8; bits = 8;
else if (*odst >= 192) /* Class C */ else if (*odst >= 192) /* Class C */
bits = 24; bits = 24;
else if (*odst >= 128) /* Class B */ else if (*odst >= 128) /* Class B */
bits = 16; bits = 16;
else /* Class A */ else /* Class A */
bits = 8; bits = 8;
/* If imputed mask is narrower than specified octets, widen. */ /* If imputed mask is narrower than specified octets, widen. */
if (bits < ((dst - odst) * 8)) if (bits < ((dst - odst) * 8))
bits = (dst - odst) * 8; bits = (int)(dst - odst) * 8;
/* /*
* If there are no additional bits specified for a class D * If there are no additional bits specified for a class D
* address adjust bits to 4. * address adjust bits to 4.
*/ */
if (bits == 8 && *odst == 224) if (bits == 8 && *odst == 224)
bits = 4; bits = 4;
} }
/* Extend network to cover the actual mask. */ /* Extend network to cover the actual mask. */
while (bits > ((dst - odst) * 8)) { while (bits > ((dst - odst) * 8)) {
if (size-- <= 0U) if (size-- <= 0U)
goto emsgsize; goto emsgsize;
*dst++ = '\0'; *dst++ = '\0';
} }
return (bits); return (bits);
enoent: enoent:
errno = ENOENT; errno = ENOENT;
return (-1); return (-1);
emsgsize: emsgsize:
errno = EMSGSIZE; errno = EMSGSIZE;
return (-1); return (-1);
} }
static int static int
getbits(const char *src, int *bitsp) { getbits(const char *src, int *bitsp)
static const char digits[] = "0123456789"; {
int n; static const char digits[] = "0123456789";
int val; int n;
char ch; int val;
char ch;
val = 0; val = 0;
n = 0; n = 0;
while ((ch = *src++) != '\0') { while ((ch = *src++) != '\0') {
const char *pch; const char *pch;
pch = strchr(digits, ch); pch = strchr(digits, ch);
if (pch != NULL) { if (pch != NULL) {
if (n++ != 0 && val == 0) /* no leading zeros */ if (n++ != 0 && val == 0) /* no leading zeros */
return (0); return (0);
val *= 10; val *= 10;
val += (pch - digits); val += (pch - digits);
if (val > 128) /* range */ if (val > 128) /* range */
return (0); return (0);
continue; continue;
} }
return (0); return (0);
} }
if (n == 0) if (n == 0)
return (0); return (0);
*bitsp = val; *bitsp = val;
return (1); return (1);
} }
static int static int
getv4(const char *src, unsigned char *dst, int *bitsp) { getv4(const char *src, unsigned char *dst, int *bitsp)
static const char digits[] = "0123456789"; {
unsigned char *odst = dst; static const char digits[] = "0123456789";
int n; unsigned char *odst = dst;
unsigned int val; int n;
char ch; unsigned int val;
char ch;
val = 0; val = 0;
n = 0; n = 0;
while ((ch = *src++) != '\0') { while ((ch = *src++) != '\0') {
const char *pch; const char *pch;
pch = strchr(digits, ch); pch = strchr(digits, ch);
if (pch != NULL) { if (pch != NULL) {
if (n++ != 0 && val == 0) /* no leading zeros */ if (n++ != 0 && val == 0) /* no leading zeros */
return (0); return (0);
val *= 10; val *= 10;
val += (pch - digits); val += (pch - digits);
if (val > 255) /* range */ if (val > 255) /* range */
return (0); return (0);
continue; continue;
} }
if (ch == '.' || ch == '/') { if (ch == '.' || ch == '/') {
if (dst - odst > 3) /* too many octets? */ if (dst - odst > 3) /* too many octets? */
return (0); return (0);
*dst++ = val; *dst++ = val;
if (ch == '/') if (ch == '/')
return (getbits(src, bitsp)); return (getbits(src, bitsp));
val = 0; val = 0;
n = 0; n = 0;
continue; continue;
} }
return (0); return (0);
} }
if (n == 0) if (n == 0)
return (0); return (0);
if (dst - odst > 3) /* too many octets? */ if (dst - odst > 3) /* too many octets? */
return (0); return (0);
*dst++ = val; *dst++ = val;
return (1); return (1);
} }
static int static int
inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size) { inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
static const char xdigits_l[] = "0123456789abcdef", {
xdigits_u[] = "0123456789ABCDEF"; static const char xdigits_l[] = "0123456789abcdef",
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; xdigits_u[] = "0123456789ABCDEF";
const char *xdigits, *curtok; unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
int ch, saw_xdigit; const char *xdigits, *curtok;
unsigned int val; int ch, saw_xdigit;
int digits; unsigned int val;
int bits; int digits;
size_t bytes; int bits;
int words; size_t bytes;
int ipv4; int words;
int ipv4;
memset((tp = tmp), '\0', NS_IN6ADDRSZ); memset((tp = tmp), '\0', NS_IN6ADDRSZ);
endp = tp + NS_IN6ADDRSZ; endp = tp + NS_IN6ADDRSZ;
colonp = NULL; colonp = NULL;
/* Leading :: requires some special handling. */ /* Leading :: requires some special handling. */
if (*src == ':') if (*src == ':')
if (*++src != ':') if (*++src != ':')
goto enoent; goto enoent;
curtok = src; curtok = src;
saw_xdigit = 0; saw_xdigit = 0;
val = 0; val = 0;
digits = 0; digits = 0;
bits = -1; bits = -1;
ipv4 = 0; ipv4 = 0;
while ((ch = *src++) != '\0') { while ((ch = *src++) != '\0') {
const char *pch; const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch); pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) { if (pch != NULL) {
val <<= 4; val <<= 4;
val |= (pch - xdigits); val |= (pch - xdigits);
if (++digits > 4) if (++digits > 4)
goto enoent; goto enoent;
saw_xdigit = 1; saw_xdigit = 1;
continue; continue;
} }
if (ch == ':') { if (ch == ':') {
curtok = src; curtok = src;
if (!saw_xdigit) { if (!saw_xdigit) {
if (colonp) if (colonp)
goto enoent; goto enoent;
colonp = tp; colonp = tp;
continue; continue;
} else if (*src == '\0') } else if (*src == '\0')
goto enoent; goto enoent;
if (tp + NS_INT16SZ > endp) if (tp + NS_INT16SZ > endp)
return (0); return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff; *tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0; saw_xdigit = 0;
digits = 0; digits = 0;
val = 0; val = 0;
continue; continue;
} }
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
getv4(curtok, tp, &bits) > 0) { getv4(curtok, tp, &bits) > 0) {
tp += NS_INADDRSZ; tp += NS_INADDRSZ;
saw_xdigit = 0; saw_xdigit = 0;
ipv4 = 1; ipv4 = 1;
break; /* '\0' was seen by inet_pton4(). */ break; /* '\0' was seen by inet_pton4(). */
} }
if (ch == '/' && getbits(src, &bits) > 0) if (ch == '/' && getbits(src, &bits) > 0)
break; break;
goto enoent; goto enoent;
} }
if (saw_xdigit) { if (saw_xdigit) {
if (tp + NS_INT16SZ > endp) if (tp + NS_INT16SZ > endp)
goto enoent; goto enoent;
*tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff; *tp++ = (unsigned char) val & 0xff;
} }
if (bits == -1) if (bits == -1)
bits = 128; bits = 128;
words = (bits + 15) / 16; words = (bits + 15) / 16;
if (words < 2) if (words < 2)
words = 2; words = 2;
if (ipv4) if (ipv4)
words = 8; words = 8;
endp = tmp + 2 * words; endp = tmp + 2 * words;
if (colonp != NULL) { if (colonp != NULL) {
/* /*
* Since some memmove()'s erroneously fail to handle * Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand. * overlapping regions, we'll do the shift by hand.
*/ */
const int n = tp - colonp; const int n = (int)(tp - colonp);
int i; int i;
if (tp == endp) if (tp == endp)
goto enoent; goto enoent;
for (i = 1; i <= n; i++) { for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i]; endp[- i] = colonp[n - i];
colonp[n - i] = 0; colonp[n - i] = 0;
} }
tp = endp; tp = endp;
} }
if (tp != endp) if (tp != endp)
goto enoent; goto enoent;
bytes = (bits + 7) / 8; bytes = (bits + 7) / 8;
if (bytes > size) if (bytes > size)
goto emsgsize; goto emsgsize;
memcpy(dst, tmp, bytes); memcpy(dst, tmp, bytes);
return (bits); return (bits);
enoent: enoent:
errno = ENOENT; errno = ENOENT;
return (-1); return (-1);
emsgsize: emsgsize:
errno = EMSGSIZE; errno = EMSGSIZE;
return (-1); return (-1);
} }
/* /*
* int * int
* inet_net_pton(af, src, dst, size) * inet_net_pton(af, src, dst, size)
* convert network number from presentation to network format. * convert network number from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR. * accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst". * "size" is in bytes and describes "dst".
* return: * return:
* number of bits, either imputed classfully or specified with /CIDR, * number of bits, either imputed classfully or specified with /CIDR,
* or -1 if some failure occurred (check errno). ENOENT means it was * or -1 if some failure occurred (check errno). ENOENT means it was
* not a valid network specification. * not a valid network specification.
* author: * author:
* Paul Vixie (ISC), June 1996 * Paul Vixie (ISC), June 1996
*/ */
int int
ares_inet_net_pton(int af, const char *src, void *dst, size_t size) { ares_inet_net_pton(int af, const char *src, void *dst, size_t size)
switch (af) { {
case AF_INET: switch (af) {
return (inet_net_pton_ipv4(src, dst, size)); case AF_INET:
case AF_INET6: return (inet_net_pton_ipv4(src, dst, size));
return (inet_net_pton_ipv6(src, dst, size)); case AF_INET6:
default: return (inet_net_pton_ipv6(src, dst, size));
errno = EAFNOSUPPORT; default:
return (-1); errno = EAFNOSUPPORT;
} return (-1);
}
} }
#endif #endif
#if !defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6) #if !defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6)
int ares_inet_pton(int af, const char *src, void *dst) { int ares_inet_pton(int af, const char *src, void *dst)
int size, result; {
int size, result;
if (af == AF_INET)
size = sizeof(struct in_addr); if (af == AF_INET)
else if (af == AF_INET6) size = sizeof(struct in_addr);
size = sizeof(struct in6_addr); else if (af == AF_INET6)
else size = sizeof(struct in6_addr);
{ else
errno = EAFNOSUPPORT; {
return -1; errno = EAFNOSUPPORT;
} return -1;
result = ares_inet_net_pton(af, src, dst, size); }
if (result == -1 && errno == ENOENT) result = ares_inet_net_pton(af, src, dst, size);
return 0; if (result == -1 && errno == ENOENT)
return (result > -1 ? 1 : -1); return 0;
return (result > -1 ? 1 : -1);
} }
#endif #endif