Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-6]: src/dist/bind/lib/irs Pull up revisions 1.3-1.4 (requested ...
details: https://anonhg.NetBSD.org/src/rev/2dab2cef8187
branches: netbsd-1-6
changeset: 528206:2dab2cef8187
user: lukem <lukem%NetBSD.org@localhost>
date: Fri Jun 28 11:48:38 2002 +0000
description:
Pull up revisions 1.3-1.4 (requested by itojun in ticket #387):
Update to BIND 8.3.3. Fixes buffer overrun in resolver code.
diffstat:
dist/bind/lib/irs/getnameinfo.c | 266 +++++++++++++++++++++++++++------------
1 files changed, 183 insertions(+), 83 deletions(-)
diffs (truncated from 361 to 300 lines):
diff -r b4414dab911c -r 2dab2cef8187 dist/bind/lib/irs/getnameinfo.c
--- a/dist/bind/lib/irs/getnameinfo.c Fri Jun 28 11:48:28 2002 +0000
+++ b/dist/bind/lib/irs/getnameinfo.c Fri Jun 28 11:48:38 2002 +0000
@@ -1,10 +1,8 @@
-/* $NetBSD: getnameinfo.c,v 1.2 2001/01/27 07:22:03 itojun Exp $ */
+/* $NetBSD: getnameinfo.c,v 1.2.2.1 2002/06/28 11:48:38 lukem Exp $ */
/*
* Issues to be discussed:
* - Thread safe-ness must be checked
- * - Return values. There seems to be no standard for return value (RFC2133)
- * but INRIA implementation returns EAI_xxx defined for getaddrinfo().
*/
/*
@@ -52,13 +50,13 @@
#include <netdb.h>
#include <resolv.h>
#include <string.h>
+#include <stddef.h>
#include <port_after.h>
-#define SUCCESS 0
-#define ANY 0
-#define YES 1
-#define NO 0
+#ifdef USE_IFNAMELINKID
+#include <net/if.h>
+#endif
/*
* Note that a_off will be dynamically adjusted so that to be consistent
@@ -68,30 +66,30 @@
static struct afd {
int a_af;
int a_addrlen;
- int a_socklen;
+ size_t a_socklen;
int a_off;
} afdl [] = {
/* first entry is linked last... */
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
- 4 /*XXX*/},
+ offsetof(struct sockaddr_in, sin_addr)},
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
- 8 /*XXX*/},
- {0, 0, 0},
+ offsetof(struct sockaddr_in6, sin6_addr)},
+ {0, 0, 0, 0},
};
struct sockinet {
+#ifdef HAVE_SA_LEN
u_char si_len;
+#endif
u_char si_family;
u_short si_port;
};
-#define ENI_NOSOCKET 0
-#define ENI_NOSERVNAME 1
-#define ENI_NOHOSTNAME 2
-#define ENI_MEMORY 3
-#define ENI_SYSTEM 4
-#define ENI_FAMILY 5
-#define ENI_SALEN 6
+static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
+ size_t, int));
+#ifdef HAVE_SIN6_SCOPE_ID
+static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
+#endif
int
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
@@ -108,99 +106,89 @@
struct hostent *hp;
u_short port;
#ifdef HAVE_SA_LEN
- int len;
+ size_t len;
#endif
int family, i;
- char *addr, *p;
- u_char pfx;
- static int firsttime = 1;
- static char numserv[512];
- static char numaddr[512];
-
-
- /* dynamically adjust a_off */
- if (firsttime) {
- struct afd *p;
- u_char *q;
- struct sockaddr_in sin;
- struct sockaddr_in6 sin6;
-
- for (p = &afdl[0]; p->a_af; p++) {
- switch (p->a_af) {
- case PF_INET:
- q = (u_char *)&sin.sin_addr.s_addr;
- p->a_off = q - (u_char *)&sin;
- break;
- case PF_INET6:
- q = (u_char *)&sin6.sin6_addr.s6_addr;
- p->a_off = q - (u_char *)&sin6;
- break;
- default:
- break;
- }
- }
- firsttime = 0;
- }
+ const char *addr;
+ char *p;
+ char numserv[512];
+ char numaddr[512];
+ const struct sockaddr_in6 *sin6;
if (sa == NULL)
- return ENI_NOSOCKET;
+ return EAI_FAIL;
#ifdef HAVE_SA_LEN
len = sa->sa_len;
- if (len != salen) return ENI_SALEN;
+ if (len != salen) return EAI_FAIL;
#endif
-
+
family = sa->sa_family;
for (i = 0; afdl[i].a_af; i++)
if (afdl[i].a_af == family) {
afd = &afdl[i];
goto found;
}
- return ENI_FAMILY;
-
+ return EAI_FAMILY;
+
found:
- if (salen != afd->a_socklen) return ENI_SALEN;
-
- port = ((struct sockinet *)sa)->si_port; /* network byte order */
- addr = (char *)sa + afd->a_off;
+ if (salen != afd->a_socklen) return EAI_FAIL;
+
+ port = ((const struct sockinet *)sa)->si_port; /* network byte order */
+ addr = (const char *)sa + afd->a_off;
if (serv == NULL || servlen == 0) {
- /* what we should do? */
+ /*
+ * rfc2553bis says that serv == NULL or servlen == 0 means that
+ * the caller does not want the result.
+ */
} else if (flags & NI_NUMERICSERV) {
- snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
+ sprintf(numserv, "%d", ntohs(port));
if (strlen(numserv) > servlen)
- return ENI_MEMORY;
+ return EAI_MEMORY;
strcpy(serv, numserv);
} else {
sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
if (sp) {
if (strlen(sp->s_name) + 1 > servlen)
- return ENI_MEMORY;
+ return EAI_MEMORY;
strcpy(serv, sp->s_name);
} else
- return ENI_NOSERVNAME;
+ return EAI_NONAME;
}
switch (sa->sa_family) {
case AF_INET:
- if (ntohl(*(u_long *)addr) >> IN_CLASSA_NSHIFT == 0)
+ if (ntohl(*(const u_long *)addr) >> IN_CLASSA_NSHIFT == 0)
flags |= NI_NUMERICHOST;
break;
case AF_INET6:
- pfx = *addr;
- if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
- flags |= NI_NUMERICHOST;
+ sin6 = (const struct sockaddr_in6 *)sa;
+ switch (sin6->sin6_addr.s6_addr[0]) {
+ case 0x00:
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
+ ;
+ else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
+ ;
+ else
+ flags |= NI_NUMERICHOST;
+ break;
+ default:
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+ flags |= NI_NUMERICHOST;
+ else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
+ flags |= NI_NUMERICHOST;
+ break;
+ }
break;
}
if (host == NULL || hostlen == 0) {
- /* what should we do? */
+ /*
+ * rfc2553bis says that host == NULL or hostlen == 0 means that
+ * the caller does not want the result.
+ */
} else if (flags & NI_NUMERICHOST) {
- if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
- == NULL)
- return ENI_SYSTEM;
- if (strlen(numaddr) + 1 > hostlen)
- return ENI_MEMORY;
- strcpy(host, numaddr);
+ goto numeric;
} else {
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
@@ -210,18 +198,130 @@
if (p) *p = '\0';
}
if (strlen(hp->h_name) + 1 > hostlen)
- return ENI_MEMORY;
+ return EAI_MEMORY;
strcpy(host, hp->h_name);
} else {
if (flags & NI_NAMEREQD)
- return ENI_NOHOSTNAME;
- if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
- == NULL)
- return ENI_NOHOSTNAME;
- if (strlen(numaddr) + 1 > hostlen)
- return ENI_MEMORY;
- strcpy(host, numaddr);
+ return EAI_NONAME;
+ numeric:
+ switch(afd->a_af) {
+ case AF_INET6:
+ {
+ int error;
+
+ if ((error = ip6_parsenumeric(sa, addr, host,
+ hostlen,
+ flags)) != 0)
+ return(error);
+ break;
+ }
+
+ default:
+ if (inet_ntop(afd->a_af, addr, numaddr,
+ sizeof(numaddr)) == NULL)
+ return EAI_NONAME;
+ if (strlen(numaddr) + 1 > hostlen)
+ return EAI_MEMORY;
+ strcpy(host, numaddr);
+ }
}
}
- return SUCCESS;
+ return(0);
+}
+
+static int
+ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host,
+ size_t hostlen, int flags)
+{
+ size_t numaddrlen;
+ char numaddr[512];
+
+#ifndef HAVE_SIN6_SCOPE_ID
+ UNUSED(sa);
+ UNUSED(flags);
+#endif
+
+ if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ return EAI_SYSTEM;
+
+ numaddrlen = strlen(numaddr);
+ if (numaddrlen + 1 > hostlen) /* don't forget terminator */
+ return EAI_MEMORY;
+ strcpy(host, numaddr);
+
+#ifdef HAVE_SIN6_SCOPE_ID
+ if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
+ char scopebuf[MAXHOSTNAMELEN]; /* XXX */
+ int scopelen;
+
+ /* ip6_sa2str never fails */
+ scopelen = ip6_sa2str((const struct sockaddr_in6 *)sa,
+ scopebuf, sizeof(scopebuf), flags);
+
+ if (scopelen + 1 + numaddrlen + 1 > hostlen)
+ return EAI_MEMORY;
+
+ /* construct <numeric-addr><delim><scopeid> */
+ memcpy(host + numaddrlen + 1, scopebuf,
Home |
Main Index |
Thread Index |
Old Index