summaryrefslogtreecommitdiff
path: root/resolv/ns_name.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-10-26 08:34:38 +0000
committerUlrich Drepper <drepper@redhat.com>2003-10-26 08:34:38 +0000
commit5ae19a502312bac2403f8aaaf743a9e9e6b1fdf2 (patch)
tree1840b3f415fab01157e95fc22c69973f46a28bab /resolv/ns_name.c
parent4d54786a9b982820570e616c1b5669d5b169fd00 (diff)
downloadglibc-5ae19a502312bac2403f8aaaf743a9e9e6b1fdf2.tar.gz
Update.
2003-10-26 Ulrich Drepper <drepper@redhat.com> * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyaddr_r): Default reverse lookup format for IPv6 addresses is using bitfields and .ip6.arpa suffix. * resolv/ns_name.c: Implement encoding and decoding bitfields in hex format.
Diffstat (limited to 'resolv/ns_name.c')
-rw-r--r--resolv/ns_name.c99
1 files changed, 90 insertions, 9 deletions
diff --git a/resolv/ns_name.c b/resolv/ns_name.c
index cb6393527f..a4f066c9e2 100644
--- a/resolv/ns_name.c
+++ b/resolv/ns_name.c
@@ -24,6 +24,7 @@ static const char rcsid[] = "$BINDId: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie
#include <netinet/in.h>
#include <arpa/nameser.h>
+#include <ctype.h>
#include <errno.h>
#include <resolv.h>
#include <string.h>
@@ -64,7 +65,7 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
eom = dst + dstsiz;
while ((n = *cp++) != 0) {
- if ((n & NS_CMPRSFLGS) != 0) {
+ if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
/* Some kind of compression pointer. */
__set_errno (EMSGSIZE);
return (-1);
@@ -76,6 +77,29 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
}
*dn++ = '.';
}
+
+ if (n == 0x41) {
+ n = *cp++ / 8;
+ if (dn + n * 2 + 4 >= eom) {
+ __set_errno (EMSGSIZE);
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = '[';
+ *dn++ = 'x';
+
+ while (n-- > 0) {
+ c = *cp++;
+ unsigned u = c >> 4;
+ *dn++ = u > 9 ? 'a' + u - 10 : '0' + u;
+ u = c & 0xf;
+ *dn++ = u > 9 ? 'a' + u - 10 : '0' + u;
+ }
+
+ *dn++ = ']';
+ continue;
+ }
+
if (dn + n >= eom) {
__set_errno (EMSGSIZE);
return (-1);
@@ -165,6 +189,43 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
return (-1);
}
c = n;
+ } else if (c == '[' && label == bp - 1 && *src == 'x') {
+ /* Theoretically we would have to handle \[o
+ as well but we do not since we do not need
+ it internally. */
+ *label = 0x41;
+ label = bp++;
+ /* Another simplification: always assume
+ 128 bit number. */
+ if (bp + 16 >= eom) {
+ __set_errno (EMSGSIZE);
+ return (-1);
+ }
+ ++src;
+ while (isxdigit (*src)) {
+ n = *src > '9' ? *src - 'a' + 10 : *src - '0';
+ ++src;
+ if (! isxdigit(*src)) {
+ __set_errno (EMSGSIZE);
+ return (-1);
+ }
+ n <<= 4;
+ n += *src > '9' ? *src - 'a' + 10 : *src - '0';
+ *bp++ = n;
+ ++src;
+ }
+ *label = (bp - label - 1) * 8;
+ if (*src++ != ']' || *src++ != '.') {
+ __set_errno (EMSGSIZE);
+ return (-1);
+ }
+ escaped = 0;
+ label = bp++;
+ if (bp >= eom) {
+ __set_errno (EMSGSIZE);
+ return (-1);
+ }
+ continue;
}
escaped = 0;
} else if (c == '\\') {
@@ -303,6 +364,20 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
while ((n = *srcp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
+ case 0x40:
+ if (n == 0x41) {
+ if (dstp + 1 >= dstlim) {
+ __set_errno (EMSGSIZE);
+ return (-1);
+ }
+ *dstp++ = 0x41;
+ n = *srcp++ / 8;
+ ++checked;
+ } else {
+ __set_errno (EMSGSIZE);
+ return (-1); /* flag error */
+ }
+ /* FALLTHROUGH */
case 0:
/* Limit checks. */
if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
@@ -310,9 +385,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
return (-1);
}
checked += n + 1;
- *dstp++ = n;
- memcpy(dstp, srcp, n);
- dstp += n;
+ dstp = mempcpy(dstp, srcp - 1, n + 1);
srcp += n;
break;
@@ -394,10 +467,12 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
l = 0;
do {
n = *srcp;
- if ((n & NS_CMPRSFLGS) != 0) {
+ if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
__set_errno (EMSGSIZE);
return (-1);
}
+ if (n == 0x41)
+ n = *++srcp / 8;
l += n + 1;
if (l > MAXCDNAME) {
__set_errno (EMSGSIZE);
@@ -411,7 +486,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
do {
/* Look to see if we can use pointers. */
n = *srcp;
- if (n != 0 && msg != NULL) {
+ if (n != 0 && n != 0x41 && msg != NULL) {
l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
(const u_char * const *)lpp);
if (l >= 0) {
@@ -431,9 +506,15 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
}
}
/* copy label to buffer */
- if (n & NS_CMPRSFLGS) { /* Should not happen. */
+ if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) { /* Should not happen. */
goto cleanup;
}
+ if (n == 0x41) {
+ n = *++srcp / 8;
+ if (dstp + 1 >= eob)
+ goto cleanup;
+ *dstp++ = 0x41;
+ }
if (dstp + 1 + n >= eob) {
goto cleanup;
}
@@ -448,7 +529,7 @@ cleanup:
*lpp = NULL;
__set_errno (EMSGSIZE);
return (-1);
- }
+ }
return (dstp - dst);
}
@@ -466,7 +547,7 @@ ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
{
u_char tmp[NS_MAXCDNAME];
int n;
-
+
if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
return (-1);
if (ns_name_ntop(tmp, dst, dstsiz) == -1)