diff options
| author | Hajimu UMEMOTO <ume@FreeBSD.org> | 2001-07-28 22:24:46 +0000 |
|---|---|---|
| committer | Hajimu UMEMOTO <ume@FreeBSD.org> | 2001-07-28 22:24:46 +0000 |
| commit | 87be3a7ac92b7a0f52cccf0e3736fab79bab3a08 (patch) | |
| tree | 428cd5409a2a47f18f59ca4f8228c23bcfc10659 /lib/libutil | |
| parent | c8509cc8deb8d3732f3d80a7fcb2bfbc59c5689e (diff) | |
Notes
Diffstat (limited to 'lib/libutil')
| -rw-r--r-- | lib/libutil/realhostname.c | 106 |
1 files changed, 43 insertions, 63 deletions
diff --git a/lib/libutil/realhostname.c b/lib/libutil/realhostname.c index 26bd5e6174ea..c41b896166e7 100644 --- a/lib/libutil/realhostname.c +++ b/lib/libutil/realhostname.c @@ -52,7 +52,7 @@ struct sockinet { int realhostname(char *host, size_t hsize, const struct in_addr *ip) { - char trimmed[MAXHOSTNAMELEN+1]; + char trimmed[MAXHOSTNAMELEN]; int result; struct hostent *hp; @@ -93,24 +93,47 @@ realhostname_sa(char *host, size_t hsize, struct sockaddr *addr, int addrlen) { int result, error; char buf[NI_MAXHOST]; + struct sockaddr_in sin; result = HOSTNAME_INVALIDADDR; - error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, 0); +#ifdef INET6 + /* IPv4 mapped IPv6 addr consideraton, specified in rfc2373. */ + if (addr->sa_family == AF_INET6 && + addrlen == sizeof(struct sockaddr_in6) && + IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)addr)->sin6_addr)) { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)addr; + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + sin.sin_port = sin6->sin6_port; + memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], + sizeof(struct in_addr)); + addr = (struct sockaddr *)&sin; + addrlen = sin.sin_len; + } +#endif + + error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, + NI_WITHSCOPEID); if (error == 0) { struct addrinfo hints, *res, *ores; struct sockaddr *sa; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = - (addr->sa_family == AF_INET) ? AF_INET : AF_UNSPEC; - hints.ai_flags = AI_CANONNAME; + hints.ai_family = addr->sa_family; + hints.ai_flags = AI_CANONNAME | AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(buf, NULL, &hints, &res); if (error) { result = HOSTNAME_INVALIDNAME; goto numeric; - } else for (ores = res; ; res = res->ai_next) { + } + for (ores = res; ; res = res->ai_next) { if (res == NULL) { freeaddrinfo(ores); result = HOSTNAME_INCORRECTNAME; @@ -124,81 +147,38 @@ realhostname_sa(char *host, size_t hsize, struct sockaddr *addr, int addrlen) } if (sa->sa_len == addrlen && sa->sa_family == addr->sa_family) { - u_int16_t port; - - port = ((struct sockinet *)addr)->si_port; - ((struct sockinet *)addr)->si_port = 0; + ((struct sockinet *)sa)->si_port = ((struct sockinet *)addr)->si_port; +#ifdef INET6 + /* + * XXX: sin6_socpe_id may not been + * filled by DNS + */ + if (sa->sa_family == AF_INET6 && + ((struct sockaddr_in6 *)sa)->sin6_scope_id == 0) + ((struct sockaddr_in6 *)sa)->sin6_scope_id = ((struct sockaddr_in6 *)addr)->sin6_scope_id; +#endif if (!memcmp(sa, addr, sa->sa_len)) { result = HOSTNAME_FOUND; - ((struct sockinet *)addr)->si_port = - port; - if (ores->ai_canonname == 0) { + if (ores->ai_canonname == NULL) { freeaddrinfo(ores); goto numeric; } - strncpy(buf, ores->ai_canonname, + strlcpy(buf, ores->ai_canonname, sizeof(buf)); trimdomain(buf, hsize); - strncpy(host, buf, hsize); - if (strlen(host) > hsize && + if (strlen(buf) > hsize && addr->sa_family == AF_INET) { freeaddrinfo(ores); goto numeric; } - break; - } - ((struct sockinet *)addr)->si_port = port; - } -#ifdef INET6 - /* - * XXX IPv4 mapped IPv6 addr consideraton, - * specified in rfc2373. - */ - if (sa->sa_family == AF_INET && - addr->sa_family == AF_INET6) { - struct in_addr *in; - struct in6_addr *in6; - - in = &((struct sockaddr_in *)sa)->sin_addr; - in6 = &((struct sockaddr_in6 *)addr)->sin6_addr; - if (IN6_IS_ADDR_V4MAPPED(in6) && - !memcmp(&in6->s6_addr[12], in, - sizeof(*in))) { - result = HOSTNAME_FOUND; - if (ores->ai_canonname == 0 || - strlen(ores->ai_canonname) > hsize) { - freeaddrinfo(ores); - goto numeric; - } - strncpy(host, ores->ai_canonname, - hsize); + strncpy(host, buf, hsize); break; } } -#endif } freeaddrinfo(ores); } else { - struct sockaddr_in sin; numeric: -#ifdef INET6 - if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6; - - sin6 = (struct sockaddr_in6 *)addr; - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_family = AF_INET; - sin.sin_port = sin6->sin6_port; - memcpy(&sin.sin_addr, - &sin6->sin6_addr.s6_addr[12], - sizeof(struct in_addr)); - addr = (struct sockaddr *)&sin; - addrlen = sin.sin_len; - } - } -#endif if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST|NI_WITHSCOPEID) == 0) strncpy(host, buf, hsize); |
