diff options
Diffstat (limited to 'lib/libc/net')
-rw-r--r-- | lib/libc/net/gai_strerror.c | 45 | ||||
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 576 | ||||
-rw-r--r-- | lib/libc/net/getnameinfo.c | 345 |
3 files changed, 8 insertions, 958 deletions
diff --git a/lib/libc/net/gai_strerror.c b/lib/libc/net/gai_strerror.c index a758b7449ba..37e0b55e8b0 100644 --- a/lib/libc/net/gai_strerror.c +++ b/lib/libc/net/gai_strerror.c @@ -30,33 +30,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Craig Metz and - * by other contributors. - * 4. Neither the name of the author nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ /* gai_strerror() v1.38 */ @@ -65,12 +38,6 @@ #include <netdb.h> #include <errno.h> -#define THREAD_SAFE 0 - -#if !THREAD_SAFE -static char buffer[256]; -#endif /* !THREAD_SAFE */ - char *gai_strerror(int errnum) { switch(errnum) { @@ -97,20 +64,8 @@ char *gai_strerror(int errnum) case EAI_MEMORY: return "memory allocation failure"; case EAI_SYSTEM: -#if THREAD_SAFE return "system error"; -#else /* THREAD_SAFE */ - snprintf(buffer, sizeof(buffer)-1, "system error: %s(%d)", strerror(errno), errno); - buffer[sizeof(buffer)-1] = 0; - return buffer; -#endif /* THREAD_SAFE */ default: -#if THREAD_SAFE return "unknown/invalid error"; -#else /* THREAD_SAFE */ - snprintf(buffer, sizeof(buffer)-1, "unknown/invalid error %d", errnum); - buffer[sizeof(buffer)-1] = 0; - return buffer; -#endif /* THREAD_SAFE */ }; }; diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index a572dbcde09..0e33aa13683 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -30,34 +30,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Craig Metz and - * by other contributors. - * 4. Neither the name of the author nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * */ /* getaddrinfo() v1.38 */ @@ -69,74 +41,17 @@ behavior and proposed changes). */ -/* - Someone merged an earlier version of this code into the GNU libc and - added support for getservbyname_r and gethostbyname2_r. The support for - those functions in this version of the code was written using that work - as a reference. I may have improved on it, or I may have broken it. -*/ - -/* To do what POSIX says, even when it's broken, define: */ -/* #define BROKEN_LIKE_POSIX 1 */ -/* Note: real apps will break if you define this, while nothing other than a - conformance test suite should have a problem with it undefined. */ - -/* If your C runtime library provides the POSIX p1003.1g D6.6 bit types - of the form u?int(16|32)_t, define: */ -/* #define HAVE_POSIX1G_TYPES 1 */ -/* Note: this implementation tries to guess what the correct values are for - your compiler+processor combination but might not always get it right. */ - -/* To enable debugging support (REQUIRES NRL support library), define: */ -/* #define DEBUG 1 */ - -#if FOR_GNULIBC -#define HAVE_POSIX1G_TYPES 1 -#define INET6 1 -#define LOCAL 1 -#define NETDB 1 -#undef RESOLVER -#undef HOSTTABLE -#undef DEBUG -#define HAVE_GETSERVBYNAME_R 1 -#define HAVE_GETHOSTBYNAME2_R 1 -#define getservbyname_r __getservbyname_r -#define gethostbyname2_r __gethostbyname2_r -#endif /* FOR_GNULIBC */ - -#ifdef __OpenBSD__ -#define HAVE_POSIX1G_TYPES 1 -#define INET6 1 -#define LOCAL 1 -#define NETDB 1 -#define SALEN 1 -#undef RESOLVER -#undef HOSTTABLE -#undef DEBUG -#undef HAVE_GETSERVBYNAME_R -#undef HAVE_GETHOSTBYNAME2_R -#endif /* __OpenBSD__ */ - #include <sys/types.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <string.h> -#if LOCAL #include <stdio.h> #include <sys/utsname.h> #include <sys/un.h> -#endif /* LOCAL */ #include <netinet/in.h> #include <netdb.h> #include <errno.h> -#if RESOLVER -#include <arpa/nameser.h> -#include <resolv.h> -#endif /* RESOLVER */ -#if DEBUG -#include <syslog.h> -#endif /* DEBUG */ #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX @@ -148,47 +63,6 @@ #define UNIX_PATH_MAX 108 #endif /* UNIX_PATH_MAX */ -#if !HAVE_POSIX1G_TYPES -#if (~0UL) == 0xffffffff -#define uint8_t unsigned char -#define int16_t short -#define uint16_t unsigned short -#define int32_t long -#define uint32_t unsigned long -#else /* (~0UL) == 0xffffffff */ -#if (~0UL) == 0xffffffffffffffff -#define uint8_t unsigned char -#define int16_t short -#define uint16_t unsigned short -#define int32_t int -#define uint32_t unsigned int -#else /* (~0UL) == 0xffffffffffffffff */ -#error Neither 32 bit nor 64 bit word size detected. -#error You need to define the bit types manually. -#endif /* (~0UL) == 0xffffffffffffffff */ -#endif /* (~0UL) == 0xffffffff */ -#endif /* !HAVE_POSIX1G_TYPES */ - -#if defined(INET6) && !defined(AF_INET6) -#error Without a definition of AF_INET6, this system cannot support IPv6 -#error addresses. -#endif /* defined(INET6) && !defined(AF_INET6) */ - -#if INET6 -#ifndef T_AAAA -#define T_AAAA 28 -#endif /* T_AAAA */ -#endif /* INET6 */ - -#if DEBUG -#if RESOLVER -#define DEBUG_MESSAGES (_res.options & RES_DEBUG) -#else /* RESOLVER */ -int __getaddrinfo_debug = 0; -#define DEBUG_MESSAGES (__getaddrinfo_debug) -#endif /* RESOLVER */ -#endif /* DEBUG */ - #define GAIH_OKIFUNSPEC 0x0100 #define GAIH_EAI ~(GAIH_OKIFUNSPEC) @@ -224,147 +98,21 @@ struct gaih_typeproto { char *name; }; -#if DEBUG #define RETURN_ERROR(x) do { \ - if (DEBUG_MESSAGES) \ - fprintf(stderr, "%s:%d: returning %s\n", __FILE__, __LINE__, #x); \ rval = (x); \ goto ret; \ } while(0) -#else /* DEBUG */ -#define RETURN_ERROR(x) do { \ - rval = (x); \ - goto ret; \ - } while(0) -#endif /* DEBUG */ -#if HOSTTABLE -static int hosttable_lookup_addr(const char *name, const struct addrinfo *req, struct gaih_addrtuple **pat) -{ - FILE *f; - char buffer[1024]; - char *c, *c2; - int rval = 1; - char *prevcname = NULL; - struct gaih_addrtuple at; - - if (!(f = fopen("/etc/hosts", "r"))) - RETURN_ERROR(-EAI_SYSTEM); - - while(fgets(buffer, sizeof(buffer), f)) { - if (c = strchr(buffer, '#')) - *c = 0; - - c = buffer; - while(*c && !isspace(*c)) c++; - if (!*c) - continue; - - *(c++) = 0; - - while(*c && isspace(*c)) c++; - if (!*c) - continue; - - if (!(c2 = strstr(c, name))) - continue; - - if (*(c2 - 1) && !isspace(*(c2 - 1))) - continue; - - c2 += strlen(name); - if (*c2 && !isspace(*c2)) - continue; - - c2 = c; - while(*c2 && !isspace(*c2)) c2++; - if (!*c2) - continue; - *c2 = 0; - - memset(&at, 0, sizeof(struct gaih_addrtuple)); - - if (!req->ai_family || (req->ai_family == AF_INET)) - if (inet_pton(AF_INET, buffer, (char *)&at.addr) > 0) { - at.family = AF_INET; - goto build; - }; - -#if INET6 - if (!req->ai_family || (req->ai_family == AF_INET6)) - if (inet_pton(AF_INET6, buffer, (char *)&at.addr) > 0) { - at.family = AF_INET6; - goto build; - }; -#endif /* INET6 */ - - continue; - -build: - if (!(*pat = malloc(sizeof(struct gaih_addrtuple)))) - RETURN_ERROR(-EAI_MEMORY); - - memcpy(*pat, &at, sizeof(struct gaih_addrtuple)); - - if (req->ai_flags & AI_CANONNAME) - if (prevcname && !strcmp(prevcname, c)) - (*pat)->cname = prevcname; - else - prevcname = (*pat)->cname = strdup(c); - - pat = &((*pat)->next); - - rval = 0; - }; - -ret: - if (f) - fclose(f); - return rval; -}; -#endif /* HOSTTABLE */ - -#if NETDB -int netdb_lookup_addr(const char *name, int af, const struct addrinfo *req, struct gaih_addrtuple **pat) +static int netdb_lookup_addr(const char *name, int af, const struct addrinfo *req, struct gaih_addrtuple **pat) { int rval, herrno, i; char *prevcname = NULL; struct hostent *h; -#if HAVE_GETHOSTBYNAME2_R - void *buf; - int buflen = 1024; - struct hostent th; - int herrno, j; - - do { - if (!(buf = malloc(buflen))) - RETURN_ERROR(-EAI_MEMORY); - - if (!gethostbyname2_r(name, af, &th, buf, buflen, &h, &herrno)) - break; - - free(buf); - buf = NULL; - - if ((herrno == NETDB_INTERNAL) && (errno == ERANGE)) { - if (buflen >= 65536) - RETURN_ERROR(-EAI_MEMORY); - - buflen = buflen << 1; - continue; - }; - } while(0); -#else /* HAVE_GETHOSTBYNAME2_R */ h = gethostbyname2(name, af); herrno = h_errno; -#endif /* HAVE_GETHOSTBYNAME2_R */ if (!h) { -#if DEBUG - if (DEBUG_MESSAGES) - fprintf(stderr, "getaddrinfo: gethostbyname2 failed, h_errno=%d\n", herrno); -#endif /* DEBUG */ switch(herrno) { case NETDB_INTERNAL: RETURN_ERROR(-EAI_SYSTEM); @@ -394,11 +142,9 @@ int netdb_lookup_addr(const char *name, int af, const struct addrinfo *req, stru case AF_INET: memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in_addr)); break; -#if INET6 case AF_INET6: memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in6_addr)); break; -#endif /* INET6 */ default: RETURN_ERROR(-EAI_FAIL); }; @@ -416,140 +162,9 @@ int netdb_lookup_addr(const char *name, int af, const struct addrinfo *req, stru rval = 0; ret: -#if HAVE_GETHOSTBYNAME2_R - free(buf); -#endif /* HAVE_GETHOSTBYNAME2_R */ return rval; }; -#endif /* NETDB */ - -#if RESOLVER -#define RRHEADER_SZ 10 -int resolver_lookup_addr(const char *name, int type, const struct addrinfo *req, struct gaih_addrtuple **pat) -{ - int rval; - char answer[PACKETSZ]; - int answerlen; - char dn[MAXDNAME]; - char *prevcname = NULL; - void *p, *ep; - int answers, i, j; - uint16_t rtype, rclass; - - if ((answerlen = res_search(name, C_IN, type, answer, sizeof(answer))) < 0) { -#if DEBUG - if (DEBUG_MESSAGES) - fprintf(stderr, "getaddrinfo: res_search failed, h_errno=%d\n", h_errno); -#endif /* DEBUG */ - switch(h_errno) { - case NETDB_INTERNAL: - RETURN_ERROR(-EAI_SYSTEM); - case HOST_NOT_FOUND: - RETURN_ERROR(1); - case TRY_AGAIN: - RETURN_ERROR(-EAI_AGAIN); - case NO_RECOVERY: - RETURN_ERROR(-EAI_FAIL); - case NO_DATA: - RETURN_ERROR(1); - default: - RETURN_ERROR(-EAI_FAIL); - }; - }; - - p = answer; - ep = answer + answerlen; - - if (answerlen < RRHEADER_SZ) - RETURN_ERROR(-EAI_FAIL); - - { - HEADER *h = (HEADER *)p; - if (!h->qr || (h->opcode != QUERY) || (h->qdcount != htons(1)) || - !h->ancount) - RETURN_ERROR(-EAI_FAIL); - answers = ntohs(h->ancount); - }; - p += sizeof(HEADER); - - if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0) - RETURN_ERROR(-EAI_FAIL); - p += i; - - if (p + 2*sizeof(uint16_t) >= ep) - RETURN_ERROR(-EAI_FAIL); - - GETSHORT(rtype, p); - GETSHORT(rclass, p); - - if ((rtype != type) || (rclass != C_IN)) - RETURN_ERROR(-EAI_FAIL); - - while(answers--) { - if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0) - RETURN_ERROR(-EAI_FAIL); - p += i; - - if (p + RRHEADER_SZ >= ep) - RETURN_ERROR(-EAI_FAIL); - - GETSHORT(rtype, p); - GETSHORT(rclass, p); - p += sizeof(uint32_t); - if (rclass != C_IN) - RETURN_ERROR(-EAI_FAIL); - GETSHORT(rclass, p); - i = rclass; - - if (p + i > ep) - RETURN_ERROR(-EAI_FAIL); - - if (rtype == type) { - while(*pat) - pat = &((*pat)->next); - - if (!(*pat = malloc(sizeof(struct gaih_addrtuple)))) - RETURN_ERROR(-EAI_MEMORY); - - memset(*pat, 0, sizeof(struct gaih_addrtuple)); - - switch(type) { - case T_A: - if (i != sizeof(struct in_addr)) - RETURN_ERROR(-EAI_FAIL); - (*pat)->family = AF_INET; - break; -#if INET6 - case T_AAAA: - if (i != sizeof(struct in6_addr)) - RETURN_ERROR(-EAI_FAIL); - (*pat)->family = AF_INET6; - break; -#endif /* INET6 */ - default: - RETURN_ERROR(-EAI_FAIL); - }; - - memcpy((*pat)->addr, p, i); - - if (req->ai_flags & AI_CANONNAME) - if (prevcname && !strcmp(prevcname, dn)) - (*pat)->cname = prevcname; - else - prevcname = (*pat)->cname = strdup(dn); - }; - p += i; - }; - - rval = 0; - -ret: - return rval; -}; -#endif /* RESOLVER */ - -#if LOCAL static int gaih_local(const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai) { @@ -574,9 +189,7 @@ static int gaih_local(const char *name, const struct gaih_service *service, (*pai)->ai_protocol = req->ai_protocol; (*pai)->ai_addrlen = sizeof(struct sockaddr_un); (*pai)->ai_addr = (void *)(*pai) + sizeof(struct addrinfo); -#if SALEN ((struct sockaddr_un *)(*pai)->ai_addr)->sun_len = sizeof(struct sockaddr_un); -#endif /* SALEN */ ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL; memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX); if (service) { @@ -610,7 +223,6 @@ static int gaih_local(const char *name, const struct gaih_service *service, ret: return rval; }; -#endif /* LOCAL */ static struct gaih_typeproto gaih_inet_typeproto[] = { { 0, 0, NULL }, @@ -623,34 +235,9 @@ static int gaih_inet_serv(char *servicename, struct gaih_typeproto *tp, struct g { int rval; struct servent *s; -#if HAVE_GETSERVBYNAME_R - int i; - void *buf; - int buflen = 1024; - struct servent ts; - do { - if (!(buf = malloc(buflen))) - RETURN_ERROR(-EAI_MEMORY); - - if (!getservbyname_r(servicename, tp->name, &ts, buf, buflen, &s)) - break; - - free(buf); - buf = NULL; - - if (errno != ERANGE) - RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE); - - if (buflen >= 65536) - RETURN_ERROR(-EAI_MEMORY); - - buflen = buflen << 1; - } while(1); -#else /* HAVE_GETSERVBYNAME_R */ if (!(s = getservbyname(servicename, tp->name))) RETURN_ERROR(GAIH_OKIFUNSPEC | -EAI_SERVICE); -#endif /* HAVE_GETSERVBYNAME_R */ if (!(*st = malloc(sizeof(struct gaih_servtuple)))) RETURN_ERROR(-EAI_MEMORY); @@ -663,10 +250,6 @@ static int gaih_inet_serv(char *servicename, struct gaih_typeproto *tp, struct g rval = 0; ret: -#if HAVE_GETSERVBYNAME_R - if (buf) - free(buf); -#endif /* HAVE_GETSERVBYNAME_R */ return rval; } @@ -727,7 +310,6 @@ static int gaih_inet(const char *name, const struct gaih_service *service, memset(at, 0, sizeof(struct gaih_addrtuple)); -#if INET6 if (req->ai_family) at->family = req->ai_family; else { @@ -739,9 +321,6 @@ static int gaih_inet(const char *name, const struct gaih_service *service, memset(at->next, 0, sizeof(struct gaih_addrtuple)); at->next->family = AF_INET; }; -#else /* INET6 */ - at->family = AF_INET; -#endif /* INET6 */ goto build; }; @@ -760,7 +339,6 @@ static int gaih_inet(const char *name, const struct gaih_service *service, }; }; -#if INET6 if (!req->ai_family || (req->ai_family == AF_INET6)) { struct in6_addr in6_addr; if (inet_pton(AF_INET6, name, &in6_addr) > 0) { @@ -774,56 +352,17 @@ static int gaih_inet(const char *name, const struct gaih_service *service, goto build; }; }; -#endif /* INET6 */ if (!(req->ai_flags & AI_NUMERICHOST)) { -#if NETDB -#if INET6 if (!req->ai_family || (req->ai_family == AF_INET6)) if ((rval = netdb_lookup_addr(name, AF_INET6, req, &at)) < 0) goto ret; -#endif /* INET6 */ if (!req->ai_family || (req->ai_family == AF_INET)) if ((rval = netdb_lookup_addr(name, AF_INET, req, &at)) < 0) goto ret; if (!rval) goto build; -#else /* NETDB */ -#if HOSTTABLE - if ((rval = hosttable_lookup_addr(name, req, &at)) < 0) - goto ret; - - if (!rval) - goto build; -#endif /* HOSTTABLE */ - -#if RESOLVER -#if INET6 - { - int rval2; - - if (!req->ai_family || (req->ai_family == AF_INET6)) - if ((rval2 = resolver_lookup_addr(name, T_AAAA, req, &at)) < 0) { - rval = rval2; - goto ret; - }; -#endif /* INET6 */ - - if (!req->ai_family || (req->ai_family == AF_INET)) - if ((rval = resolver_lookup_addr(name, T_A, req, &at)) < 0) - goto ret; - -#if INET6 - if (!rval || !rval2) - goto build; - }; -#else /* INET6 */ - if (!rval) - goto build; -#endif /* INET6 */ -#endif /* RESOLVER */ -#endif /* NETDB */ }; if (!at) @@ -848,11 +387,9 @@ build: } else j = 0; -#if INET6 if (at2->family == AF_INET6) i = sizeof(struct sockaddr_in6); else -#endif /* INET6 */ i = sizeof(struct sockaddr_in); st2 = st; @@ -868,17 +405,13 @@ build: (*pai)->ai_protocol = st2->protocol; (*pai)->ai_addrlen = i; (*pai)->ai_addr = (void *)(*pai) + sizeof(struct addrinfo); -#if SALEN ((struct sockaddr_in *)(*pai)->ai_addr)->sin_len = i; -#endif /* SALEN */ ((struct sockaddr_in *)(*pai)->ai_addr)->sin_family = at2->family; ((struct sockaddr_in *)(*pai)->ai_addr)->sin_port = st2->port; -#if INET6 if (at2->family == AF_INET6) memcpy(&((struct sockaddr_in6 *)(*pai)->ai_addr)->sin6_addr, at2->addr, sizeof(struct in6_addr)); else -#endif /* INET6 */ memcpy(&((struct sockaddr_in *)(*pai)->ai_addr)->sin_addr, at2->addr, sizeof(struct in_addr)); if (j) { @@ -933,86 +466,12 @@ struct gaih { }; static struct gaih gaih[] = { -#if INET6 { PF_INET6, "inet6", gaih_inet }, -#endif /* INET6 */ { PF_INET, "inet", gaih_inet }, -#if LOCAL { PF_LOCAL, "local", gaih_local }, -#endif /* LOCAL */ { -1, NULL, NULL } }; -#if DEBUG -static void dump_addrinfo(const struct addrinfo *ai, int follownext) -{ - char *c; - -loop: - fprintf(stderr, "addrinfo at "); - if (!ai) { - fprintf(stderr, "NULL\n"); - return; - }; - fprintf(stderr, "%08x:\n", (unsigned int)ai); - fprintf(stderr, " flags=%x(", ai->ai_flags); - c = ""; - if (ai->ai_flags & AI_PASSIVE) { - fprintf(stderr, "passive"); - c = " "; - }; - if (ai->ai_flags & AI_CANONNAME) { - fprintf(stderr, "%scanonname", c); - c = " "; - }; - if (ai->ai_flags & AI_NUMERICHOST) { - fprintf(stderr, "%snumerichost", c); - c = " "; - }; - if (ai->ai_flags & AI_EXT) { - fprintf(stderr, "%sext", c); - }; - fprintf(stderr, ")\n"); - fprintf(stderr, " family=%x(%s)\n", ai->ai_family, nrl_afnumtoname(ai->ai_family)); - fprintf(stderr, " socktype=%x(%s)\n", ai->ai_socktype, nrl_socktypenumtoname(ai->ai_socktype)); - fprintf(stderr, " protocol=%x\n", ai->ai_protocol); - fprintf(stderr, " addrlen=%x\n", ai->ai_addrlen); - fprintf(stderr, " addr=%08x", (unsigned int)ai->ai_addr); - if (ai->ai_addr) { - fprintf(stderr, ":\n"); -#if SALEN - fprintf(stderr, " len=%x\n", ai->ai_addr->sa_len); -#endif /* SALEN */ - fprintf(stderr, " family=%x(%s)\n", ai->ai_addr->sa_family, nrl_afnumtoname(ai->ai_addr->sa_family)); - fprintf(stderr, " data="); - -#if SALEN - if (ai->ai_addrlen != ai->ai_addr->sa_len) { - fprintf(stderr, " (addrlen != len, skipping)"); - } else -#endif /* SALEN */ - { - uint8_t *p; - int i; - - p = (uint8_t *)ai->ai_addr->sa_data; - i = ai->ai_addrlen - ((void *)ai->ai_addr->sa_data - (void *)ai->ai_addr); - while (i-- > 0) - fprintf(stderr, "%02x", *(p++)); - }; - }; - fprintf(stderr, "\n canonname=%08x", (unsigned int)ai->ai_canonname); - if (ai->ai_canonname) - fprintf(stderr, "(%s)", ai->ai_canonname); - fprintf(stderr, "\n next=%08x\n", (unsigned int)ai->ai_next); - - if (follownext && ai->ai_next) { - ai = ai->ai_next; - goto loop; - }; -}; -#endif /* DEBUG */ - int getaddrinfo(const char *name, const char *service, const struct addrinfo *req, struct addrinfo **pai) { @@ -1022,47 +481,24 @@ int getaddrinfo(const char *name, const char *service, struct gaih *g = gaih, *pg = NULL; struct gaih_service gaih_service, *pservice; -#if DEBUG - if (DEBUG_MESSAGES) { - fprintf(stderr, "getaddrinfo(name=%s, service=%s, req=%p, pai=%p)\n req: ", name ? name : "NULL", service ? service : "NULL", req, pai); - - dump_addrinfo(req, 0); - }; -#endif /* DEBUG */ - if (name && (name[0] == '*') && !name[1]) name = NULL; if (service && (service[0] == '*') && !service[1]) service = NULL; -#if BROKEN_LIKE_POSIX - if (!name && !service && !(req.ai_flags & AI_EXT)) - RETURN_ERROR(EAI_NONAME); -#endif /* BROKEN_LIKE_POSIX */ - if (!req) req = &nullreq; if (req->ai_flags & ~(AI_CANONNAME | AI_PASSIVE | AI_NUMERICHOST | AI_EXT)) RETURN_ERROR(EAI_BADFLAGS); -#if BROKEN_LIKE_POSIX - if ((req->ai_flags & AI_CANONNAME) && !name && !(req.ai_flags & AI_EXT)) - RETURN_ERROR(EAI_BADFLAGS); -#endif /* BROKEN_LIKE_POSIX */ - if (service && *service) { char *c; gaih_service.num = strtoul(gaih_service.name = (void *)service, &c, 10); if (*c) { gaih_service.num = -1; } -#if BROKEN_LIKE_POSIX - else - if (!req->ai_socktype && !(req.ai_flags & AI_EXT)) - RETURN_ERROR(EAI_SERVICE); -#endif /* BROKEN_LIKE_POSIX */ pservice = &gaih_service; } else @@ -1100,12 +536,6 @@ int getaddrinfo(const char *name, const char *service, if (p) { *pai = p; -#if DEBUG - if (DEBUG_MESSAGES) { - fprintf(stderr, "getaddrinfo: Success. *pai:\n"); - dump_addrinfo(p, 1); - }; -#endif /* DEBUG */ rval = 0; goto ret; } @@ -1118,10 +548,6 @@ int getaddrinfo(const char *name, const char *service, RETURN_ERROR(EAI_NONAME); ret: -#if DEBUG - if (DEBUG_MESSAGES) - fprintf(stderr, "getaddrinfo=%d\n", rval); -#endif /* DEBUG */ return rval; } diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c index 15aa67d4648..95b27a70062 100644 --- a/lib/libc/net/getnameinfo.c +++ b/lib/libc/net/getnameinfo.c @@ -30,98 +30,19 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Craig Metz and - * by other contributors. - * 4. Neither the name of the author nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Craig Metz and - * by other contributors. - * 4. Neither the name of the author nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ /* getnameinfo() v1.38 */ -/* To enable debugging support (REQUIRES NRL support library), define: */ -/* #define DEBUG 1 */ - -#ifdef __OpenBSD__ -#define HAVE_POSIX1G_TYPES 1 -#define INET6 1 -#define LOCAL 1 -#define NETDB 1 -#define SALEN 1 -#undef RESOLVER -#undef HOSTTABLE -#undef DEBUG -#undef HAVE_GETSERVBYNAME_R -#undef HAVE_GETHOSTBYNAME2_R -#endif /* __OpenBSD__ */ - #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> -#if LOCAL #include <sys/un.h> #include <sys/utsname.h> -#endif /* LOCAL */ #include <netdb.h> #include <errno.h> #include <string.h> -#if RESOLVER -#include <arpa/nameser.h> -#include <resolv.h> -#endif /* RESOLVER */ - -#include "support.h" #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX @@ -131,214 +52,11 @@ #define min(x,y) (((x) > (y)) ? (y) : (x)) #endif /* min */ -#if DEBUG -#if RESOLVER -#define DEBUG_MESSAGES (_res.options & RES_DEBUG) -#else /* RESOLVER */ -int __getnameinfo_debug = 0; -#define DEBUG_MESSAGES (__getnameinfo_debug) -#endif /* RESOLVER */ -#endif /* DEBUG */ - -#if DEBUG #define RETURN_ERROR(x) do { \ - if (DEBUG_MESSAGES) \ - fprintf(stderr, "%s:%d: returning %s\n", __FILE__, __LINE__, #x); \ rval = (x); \ goto ret; \ } while(0) -#else /* DEBUG */ -#define RETURN_ERROR(x) do { \ - rval = (x); \ - goto ret; \ - } while(0) -#endif /* DEBUG */ - -#if HOSTTABLE -static int hosttable_lookup_name(int family, void *addr, char *name, int namelen, int flags) -{ - int rval; - FILE *f; - char buffer[1024]; - char addrbuf[16]; - char *c, *c2; - int i; - char *prevcname = NULL; - - if (!(f = fopen("/etc/hosts", "r"))) - RETURN_ERROR(EAI_SYSTEM); - - while(fgets(buffer, sizeof(buffer), f)) { - if (c = strchr(buffer, '#')) - *c = 0; - - c = buffer; - while(*c && !isspace(*c)) c++; - if (!*c) - continue; - - *(c++) = 0; - - if (family == AF_INET) - if (inet_pton(AF_INET, buffer, addrbuf) > 0) - if (!memcmp(addrbuf, addr, sizeof(struct in_addr))) - goto build; - -#if INET6 - if (family == AF_INET6) - if (inet_pton(AF_INET6, buffer, addrbuf) > 0) - if (!memcmp(addrbuf, addr, sizeof(struct in6_addr))) - goto build; -#endif /* INET6 */ - - continue; - -build: - while(*c && isspace(*c)) c++; - if (!*c) - continue; - c2 = c; - while(*c2 && !isspace(*c2)) c2++; - if (!*c2) - continue; - *c2 = 0; - - if ((flags & NI_NOFQDN) && (_res.options & RES_INIT) && _res.defdname[0] && (c2 = strstr(c + 1, _res.defdname)) && (*(--c2) == '.')) { - *c2 = 0; - i = min(c2 - c, namelen) - 1; - strncpy(name, c, i); - } else - strncpy(name, c, namelen - 1); - - rval = 0; - goto ret; - }; - - RETURN_ERROR(1); - -ret: - fclose(f); - return rval; -}; -#endif /* HOSTTABLE */ - -#if RESOLVER -#if INET6 -static char hextab[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; -#endif /* INET6 */ - -struct rrheader { - int16_t type; - int16_t class; - u_int32_t ttl; - int16_t size; -}; -#define RRHEADER_SZ 10 - -int resolver_lookup_name(const char *ptrname, char *name, int namelen, int flags) -{ - int rval; - char answer[PACKETSZ]; - int answerlen; - char dn[MAXDNAME]; - char *prevcname = NULL; - void *p, *ep; - int answers, i; - uint16_t rtype, rclass; - - if ((answerlen = res_search(ptrname, C_IN, T_PTR, answer, sizeof(answer))) < 0) { - switch(h_errno) { - case NETDB_INTERNAL: - RETURN_ERROR(EAI_SYSTEM); - case HOST_NOT_FOUND: - RETURN_ERROR(1); - case TRY_AGAIN: - RETURN_ERROR(EAI_AGAIN); - case NO_RECOVERY: - RETURN_ERROR(EAI_FAIL); - case NO_DATA: - RETURN_ERROR(1); - default: - RETURN_ERROR(EAI_FAIL); - }; - }; - - p = answer; - ep = answer + answerlen; - - if (answerlen < sizeof(HEADER)) - RETURN_ERROR(EAI_FAIL); - - { - HEADER *h = (HEADER *)p; - if (!h->qr || (h->opcode != QUERY) || (h->qdcount != htons(1)) || !h->ancount) - RETURN_ERROR(EAI_FAIL); - - answers = ntohs(h->ancount); - }; - p += sizeof(HEADER); - - if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0) - RETURN_ERROR(EAI_FAIL); - - p += i; - - if (p + 2*sizeof(u_int16_t) >= ep) - RETURN_ERROR(EAI_FAIL); - - GETSHORT(rtype, p); - GETSHORT(rclass, p); - - if ((rtype != T_PTR) || (rclass != C_IN)) - RETURN_ERROR(EAI_FAIL); - - while(answers--) { - if ((i = dn_expand(answer, ep, p, dn, sizeof(dn))) < 0) - RETURN_ERROR(EAI_FAIL); - - p += i; - - if (p + RRHEADER_SZ >= ep) - RETURN_ERROR(EAI_FAIL); - - GETSHORT(rtype, p); - GETSHORT(rclass, p); - p += sizeof(uint32_t); - if (rclass != C_IN) - RETURN_ERROR(EAI_FAIL); - GETSHORT(rclass, p); - i = rclass; - - if (p + i > ep) - RETURN_ERROR(EAI_FAIL); - - if (rtype == T_PTR) { - if (dn_expand(answer, ep, p, dn, sizeof(dn)) != i) - RETURN_ERROR(EAI_FAIL); - - { - char *c2; - - if ((flags & NI_NOFQDN) && (_res.options & RES_INIT) && _res.defdname[0] && (c2 = strstr(dn + 1, _res.defdname)) && (*(--c2) == '.')) { - *c2 = 0; - strncpy(name, dn, min(c2 - dn, namelen) - 1); - } else - strncpy(name, dn, namelen - 1); - }; - }; - p += i; - }; - - rval = 0; - -ret: - return rval; -}; -#endif /* RESOLVER */ - -#if NETDB static int netdb_lookup_name(int family, void *addr, int addrlen, char *name, int namelen) { @@ -379,7 +97,6 @@ static int netdb_lookup_name(int family, void *addr, int addrlen, char *name, ret: return rval; } -#endif /* NETDB */ int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { @@ -391,7 +108,6 @@ int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t ho if (host && (hostlen > 0)) switch(sa->sa_family) { -#if INET6 case AF_INET6: if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)sa)->sin6_addr)) { if (flags & NI_NUMERICHOST) @@ -404,9 +120,7 @@ int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t ho if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) { struct sockaddr_in sin; memset(&sin, 0, sizeof(struct sockaddr_in)); -#if SALEN sin.sin_len = sizeof(struct sockaddr_in); -#endif /* SALEN */ sin.sin_family = AF_INET; sin.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port; sin.sin_addr.s_addr = ((u_int32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr)[3]; @@ -420,37 +134,13 @@ int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t ho if (flags & NI_NUMERICHOST) goto inet6_noname; -#if HOSTTABLE - if ((rval = hosttable_lookup_name(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr, host, hostlen, flags)) < 0) + if ((rval = netdb_lookup_name(AF_INET6, + &((struct sockaddr_in6 *)sa)->sin6_addr, sizeof(struct in6_addr), + host, hostlen, flags)) < 0) goto ret; - + if (!rval) break; -#endif /* HOSTTABLE */ -#if RESOLVER - { - char ptrname[sizeof("0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.int.")]; - { - int i; - char *c = ptrname; - u_int8_t *p = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr + sizeof(struct in6_addr) - 1; - - for (i = sizeof(struct in6_addr) / sizeof(u_int8_t); i > 0; i--, p--) { - *(c++) = hextab[*p & 0x0f]; - *(c++) = '.'; - *(c++) = hextab[(*p & 0xf0) >> 4]; - *(c++) = '.'; - }; - strcpy(c, "ip6.int."); - }; - - if ((rval = resolver_lookup_name(ptrname, host, hostlen, flags)) < 0) - goto ret; - - if (!rval) - break; - }; -#endif /* RESOLVER */ inet6_noname: if (flags & NI_NAMEREQD) @@ -460,7 +150,6 @@ inet6_noname: RETURN_ERROR(EAI_NONAME); break; -#endif /* INET6 */ case AF_INET: if (flags & NI_NUMERICHOST) goto inet_noname; @@ -470,27 +159,13 @@ inet6_noname: break; }; -#if HOSTTABLE - if ((rval = hosttable_lookup_name(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, host, hostlen, flags)) < 0) + if ((rval = netdb_lookup_name(AF_INET, + &((struct sockaddr_in *)sa)->sin_addr, sizeof(struct in_addr), + host, hostlen, flags)) < 0) goto ret; if (!rval) break; -#endif /* HOSTTABLE */ -#if RESOLVER - { - char ptrname[30]; - u_int8_t *p = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr; - sprintf(ptrname, "%d.%d.%d.%d.in-addr.arpa.", p[3], p[2], p[1], p[0]); - - if ((rval = resolver_lookup_name(ptrname, host, hostlen, flags)) < 0) - goto ret; - - if (!rval) - break; - }; -#endif /* RESOLVER */ - inet_noname: if (flags & NI_NAMEREQD) RETURN_ERROR(EAI_NONAME); @@ -499,7 +174,6 @@ inet_noname: RETURN_ERROR(EAI_NONAME); break; -#if LOCAL case AF_LOCAL: if (!(flags & NI_NUMERICHOST)) { struct utsname utsname; @@ -515,7 +189,6 @@ inet_noname: strncpy(host, "localhost", hostlen - 1); break; -#endif /* LOCAL */ default: RETURN_ERROR(EAI_FAMILY); }; @@ -523,9 +196,7 @@ inet_noname: if (serv && (servlen > 0)) switch(sa->sa_family) { case AF_INET: -#if INET6 case AF_INET6: -#endif /* INET6 */ if (!(flags & NI_NUMERICSERV)) { struct servent *s; if (s = getservbyport(((struct sockaddr_in *)sa)->sin_port, (flags & NI_DGRAM) ? "udp" : "tcp")) { @@ -539,11 +210,9 @@ inet_noname: }; snprintf(serv, servlen - 1, "%d", ntohs(((struct sockaddr_in *)sa)->sin_port)); break; -#if LOCAL case AF_LOCAL: strncpy(serv, ((struct sockaddr_un *)sa)->sun_path, servlen - 1); break; -#endif /* LOCAL */ }; if (host && (hostlen > 0)) |