int inet_aton(const char *cp, struct in_addr *addr) { return _inet_aton_check(cp, addr, 0); }
/* * _gai_numerichost * Determines whether the given host name is a numeric IPv4 or IPv6 address, * based on the address family input value. If the input addres family is * unspecified, a more specific value will be provided on output if possible. * Returns 1 if host name is numeric or 0 if not, or -1 on error. */ static int _gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_addr *a4, struct in6_addr *a6, int *scope) { int numerichost, passive; numerichost = 0; if (nodename == NULL) { /* return loopback or passive addresses */ passive = (flags & AI_PASSIVE); if (((*family == AF_UNSPEC) || (*family == AF_INET)) || ((*family == AF_INET6) && (flags & AI_V4MAPPED) && (flags & AI_ALL))) { if (passive) a4->s_addr = 0; else a4->s_addr = htonl(INADDR_LOOPBACK); } if ((*family == AF_UNSPEC) || (*family == AF_INET6)) { memset(a6, 0, sizeof(*a6)); if (!passive) a6->__u6_addr.__u6_addr32[3] = htonl(1); } numerichost = 1; } else { /* * numeric IPv4 host valid for AF_UNSPEC and AF_INET * also valid for AF_INET6 with AI_V4MAPPED */ numerichost = inet_pton(AF_INET, nodename, a4); if (numerichost == 0) { /* inet_pton doesn't allow "a", "a.b", or "a.b.c" forms, so we re-check */ numerichost = _inet_aton_check(nodename, a4, 1); } if (numerichost == 1) { if (*family == AF_UNSPEC) { *family = AF_INET; } else if (*family == AF_INET6) { if (flags & AI_V4MAPPED) { memset(a6, 0, sizeof(struct in6_addr)); memset(&(a6->__u6_addr.__u6_addr8[10]), 0xff, 2); memcpy(&(a6->__u6_addr.__u6_addr8[12]), a4, sizeof(struct in_addr)); } else { numerichost = -1; } } return numerichost; } /* numeric IPv6 host valid for AF_UNSPEC and AF_INET6 */ numerichost = inet_pton(AF_INET6, nodename, a6); if (numerichost == 1) { /* check for scope/zone id */ char *p = strrchr(nodename, SCOPE_DELIMITER); if (p != NULL) { int i, d; char *x; p++; d = 1; for (x = p; (*x != '\0') && (d == 1); x++) { i = *x; d = isdigit(i); } if (d == 1) *scope = atoi(p); else *scope = if_nametoindex(p); } if (*family == AF_UNSPEC) *family = AF_INET6; else if (*family == AF_INET) numerichost = -1; return numerichost; } } return numerichost; }