1570af302Sopenharmony_ci#include <sys/socket.h> 2570af302Sopenharmony_ci#include <netinet/in.h> 3570af302Sopenharmony_ci#include <netdb.h> 4570af302Sopenharmony_ci#include <net/if.h> 5570af302Sopenharmony_ci#include <arpa/inet.h> 6570af302Sopenharmony_ci#include <limits.h> 7570af302Sopenharmony_ci#include <stdlib.h> 8570af302Sopenharmony_ci#include <string.h> 9570af302Sopenharmony_ci#include <ctype.h> 10570af302Sopenharmony_ci#include "lookup.h" 11570af302Sopenharmony_ci 12570af302Sopenharmony_ciint __lookup_ipliteral(struct address buf[static 1], const char *name, int family) 13570af302Sopenharmony_ci{ 14570af302Sopenharmony_ci struct in_addr a4; 15570af302Sopenharmony_ci struct in6_addr a6; 16570af302Sopenharmony_ci if (__inet_aton(name, &a4) > 0) { 17570af302Sopenharmony_ci /* wrong family */ 18570af302Sopenharmony_ci if (family == AF_INET6) { 19570af302Sopenharmony_ci#ifndef __LITEOS__ 20570af302Sopenharmony_ci MUSL_LOGE("%{public}s: %{public}d: wrong family AF_INET6: %{public}d", __func__, __LINE__, EAI_NONAME); 21570af302Sopenharmony_ci#endif 22570af302Sopenharmony_ci return EAI_NONAME; 23570af302Sopenharmony_ci } 24570af302Sopenharmony_ci memcpy(&buf[0].addr, &a4, sizeof a4); 25570af302Sopenharmony_ci buf[0].family = AF_INET; 26570af302Sopenharmony_ci buf[0].scopeid = 0; 27570af302Sopenharmony_ci return 1; 28570af302Sopenharmony_ci } 29570af302Sopenharmony_ci 30570af302Sopenharmony_ci char tmp[64]; 31570af302Sopenharmony_ci char *p = strchr(name, '%'), *z; 32570af302Sopenharmony_ci unsigned long long scopeid = 0; 33570af302Sopenharmony_ci if (p && p-name < 64) { 34570af302Sopenharmony_ci memcpy(tmp, name, p-name); 35570af302Sopenharmony_ci tmp[p-name] = 0; 36570af302Sopenharmony_ci name = tmp; 37570af302Sopenharmony_ci } 38570af302Sopenharmony_ci 39570af302Sopenharmony_ci if (inet_pton(AF_INET6, name, &a6) <= 0) 40570af302Sopenharmony_ci return 0; 41570af302Sopenharmony_ci if (family == AF_INET) /* wrong family */ { 42570af302Sopenharmony_ci#ifndef __LITEOS__ 43570af302Sopenharmony_ci MUSL_LOGE("%{public}s: %{public}d: wrong family AF_INET: %{public}d", __func__, __LINE__, EAI_NONAME); 44570af302Sopenharmony_ci#endif 45570af302Sopenharmony_ci return EAI_NONAME; 46570af302Sopenharmony_ci } 47570af302Sopenharmony_ci 48570af302Sopenharmony_ci memcpy(&buf[0].addr, &a6, sizeof a6); 49570af302Sopenharmony_ci buf[0].family = AF_INET6; 50570af302Sopenharmony_ci if (p) { 51570af302Sopenharmony_ci if (isdigit(*++p)) scopeid = strtoull(p, &z, 10); 52570af302Sopenharmony_ci else z = p-1; 53570af302Sopenharmony_ci if (*z) { 54570af302Sopenharmony_ci if (!IN6_IS_ADDR_LINKLOCAL(&a6) && 55570af302Sopenharmony_ci !IN6_IS_ADDR_MC_LINKLOCAL(&a6)) { 56570af302Sopenharmony_ci#ifndef __LITEOS__ 57570af302Sopenharmony_ci MUSL_LOGE("%{public}s: %{public}d: illegal ipv6 address: %{public}d", __func__, __LINE__, EAI_NONAME); 58570af302Sopenharmony_ci#endif 59570af302Sopenharmony_ci return EAI_NONAME; 60570af302Sopenharmony_ci } 61570af302Sopenharmony_ci scopeid = if_nametoindex(p); 62570af302Sopenharmony_ci if (!scopeid) { 63570af302Sopenharmony_ci#ifndef __LITEOS__ 64570af302Sopenharmony_ci MUSL_LOGE("%{public}s: %{public}d: scopeid is zero: %{public}d", __func__, __LINE__, EAI_NONAME); 65570af302Sopenharmony_ci#endif 66570af302Sopenharmony_ci return EAI_NONAME; 67570af302Sopenharmony_ci } 68570af302Sopenharmony_ci } 69570af302Sopenharmony_ci if (scopeid > UINT_MAX) { 70570af302Sopenharmony_ci#ifndef __LITEOS__ 71570af302Sopenharmony_ci MUSL_LOGE("%{public}s: %{public}d: scopeid is over than UINT_MAX: %{public}d", __func__, __LINE__, EAI_NONAME); 72570af302Sopenharmony_ci#endif 73570af302Sopenharmony_ci return EAI_NONAME; 74570af302Sopenharmony_ci } 75570af302Sopenharmony_ci } 76570af302Sopenharmony_ci buf[0].scopeid = scopeid; 77570af302Sopenharmony_ci return 1; 78570af302Sopenharmony_ci} 79