diff options
Diffstat (limited to 'libc/inet')
-rw-r--r-- | libc/inet/ether_addr.c | 6 | ||||
-rw-r--r-- | libc/inet/getaddrinfo.c | 60 | ||||
-rw-r--r-- | libc/inet/resolv.c | 2 |
3 files changed, 37 insertions, 31 deletions
diff --git a/libc/inet/ether_addr.c b/libc/inet/ether_addr.c index 621c62989..9071d71de 100644 --- a/libc/inet/ether_addr.c +++ b/libc/inet/ether_addr.c @@ -38,10 +38,12 @@ struct ether_addr *ether_aton_r(const char *asc, struct ether_addr *addr) for (cnt = 0; cnt < 6; ++cnt) { unsigned char number; - char ch; + char ch = *asc++; + if (ch < 0x20) + return NULL; /* | 0x20 is cheap tolower(), valid for letters/numbers only */ - ch = (*asc++) | 0x20; + ch |= 0x20; if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f')) return NULL; number = !(ch > '9') ? (ch - '0') : (ch - 'a' + 10); diff --git a/libc/inet/getaddrinfo.c b/libc/inet/getaddrinfo.c index b3435a8b2..1a77c5199 100644 --- a/libc/inet/getaddrinfo.c +++ b/libc/inet/getaddrinfo.c @@ -395,9 +395,9 @@ gaih_inet(const char *name, const struct gaih_service *service, { struct gaih_servtuple nullserv; - const struct gaih_typeproto *tp = gaih_inet_typeproto; - struct gaih_servtuple *st = &nullserv; - struct gaih_addrtuple *at = NULL; + const struct gaih_typeproto *tp; + struct gaih_servtuple *st; + struct gaih_addrtuple *at; int rc; int v4mapped = (req->ai_family == PF_UNSPEC || req->ai_family == PF_INET6) && (req->ai_flags & AI_V4MAPPED); @@ -405,22 +405,24 @@ gaih_inet(const char *name, const struct gaih_service *service, memset(&nullserv, 0, sizeof(nullserv)); + tp = gaih_inet_typeproto; if (req->ai_protocol || req->ai_socktype) { ++tp; - while (tp->name[0] - && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype) - || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol) - ) - ) { + while (tp->name[0]) { + if ((req->ai_socktype == 0 || req->ai_socktype == tp->socktype) + && (req->ai_protocol == 0 || req->ai_protocol == tp->protocol || (tp->protoflag & GAI_PROTO_PROTOANY)) + ) { + goto found; + } ++tp; } - if (! tp->name[0]) { - if (req->ai_socktype) - return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - } + if (req->ai_socktype) + return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); + return (GAIH_OKIFUNSPEC | -EAI_SERVICE); + found: ; } + st = &nullserv; if (service != NULL) { if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) return (GAIH_OKIFUNSPEC | -EAI_SERVICE); @@ -495,6 +497,7 @@ gaih_inet(const char *name, const struct gaih_service *service, } } + at = NULL; if (name != NULL) { at = alloca(sizeof(struct gaih_addrtuple)); at->family = AF_UNSPEC; @@ -502,10 +505,9 @@ gaih_inet(const char *name, const struct gaih_service *service, at->next = NULL; if (inet_pton(AF_INET, name, at->addr) > 0) { - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped) - at->family = AF_INET; - else + if (req->ai_family != AF_UNSPEC && req->ai_family != AF_INET && !v4mapped) return -EAI_FAMILY; + at->family = AF_INET; } #if defined __UCLIBC_HAS_IPV6__ @@ -518,11 +520,9 @@ gaih_inet(const char *name, const struct gaih_service *service, *scope_delim = '\0'; if (inet_pton(AF_INET6, namebuf, at->addr) > 0) { - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) - at->family = AF_INET6; - else + if (req->ai_family != AF_UNSPEC && req->ai_family != AF_INET6) return -EAI_FAMILY; - + at->family = AF_INET6; if (scope_delim != NULL) { int try_numericscope = 0; uint32_t *a32 = (uint32_t*)at->addr; @@ -545,7 +545,7 @@ gaih_inet(const char *name, const struct gaih_service *service, } #endif - if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) { + if (at->family == AF_UNSPEC && !(req->ai_flags & AI_NUMERICHOST)) { struct hostent *h; struct gaih_addrtuple **pat = &at; int no_data = 0; @@ -649,7 +649,7 @@ gaih_inet(const char *name, const struct gaih_service *service, at2->family, &th, tmpbuf, tmpbuflen, &h, &herrno); - } while (rc == errno && herrno == NETDB_INTERNAL); + } while (rc == ERANGE && herrno == NETDB_INTERNAL); if (rc != 0 && herrno == NETDB_INTERNAL) { __set_h_errno(herrno); @@ -783,9 +783,9 @@ int getaddrinfo(const char *name, const char *service, const struct addrinfo *hints, struct addrinfo **pai) { - int i = 0, j, last_i = 0; - struct addrinfo *p = NULL, **end; - const struct gaih *g = gaih, *pg = NULL; + int i, j, last_i; + struct addrinfo *p, **end; + const struct gaih *g, *pg; struct gaih_service gaih_service, *pservice; struct addrinfo default_hints; @@ -800,7 +800,7 @@ getaddrinfo(const char *name, const char *service, if (hints == NULL) { memset(&default_hints, 0, sizeof(default_hints)); - if (AF_UNSPEC) + if (AF_UNSPEC != 0) default_hints.ai_family = AF_UNSPEC; hints = &default_hints; } @@ -832,10 +832,14 @@ getaddrinfo(const char *name, const char *service, } else pservice = NULL; + g = gaih; + pg = NULL; + p = NULL; end = NULL; if (pai) end = &p; - + i = 0; + last_i = 0; j = 0; while (g->gaih) { if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC) { @@ -851,7 +855,7 @@ getaddrinfo(const char *name, const char *service, last_i = i; if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC)) continue; - if (p) + /*if (p) - freeaddrinfo works ok on NULL too */ freeaddrinfo(p); return -(i & GAIH_EAI); } diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 47bab7519..021d5bf5d 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -3009,7 +3009,7 @@ void res_close(void) int m = 0; /* free nsaddrs[m] if they do not point to nsaddr_list[x] */ while (m < ARRAY_SIZE(_res._u._ext.nsaddrs)) { - char *p2 = (char*)(_res._u._ext.nsaddrs[m]); + char *p2 = (char*)(_res._u._ext.nsaddrs[m++]); if (p2 < p1 || (p2 - p1) > sizeof(_res.nsaddr_list)) free(p2); } |