]>
git.saurik.com Git - apple/libutil.git/blob - realhostname.c
2 * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
29 #include <sys/param.h>
30 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
47 void trimdomain(char *_fullhost
, size_t _hostsize
);
50 realhostname(char *host
, size_t hsize
, const struct in_addr
*ip
)
52 char trimmed
[MAXHOSTNAMELEN
];
56 result
= HOSTNAME_INVALIDADDR
;
57 hp
= gethostbyaddr((const char *)ip
, sizeof(*ip
), AF_INET
);
60 strlcpy(trimmed
, hp
->h_name
, sizeof(trimmed
));
61 trimdomain(trimmed
, strlen(trimmed
));
62 if (strlen(trimmed
) <= hsize
) {
63 char lookup
[MAXHOSTNAMELEN
];
65 strncpy(lookup
, hp
->h_name
, sizeof(lookup
) - 1);
66 lookup
[sizeof(lookup
) - 1] = '\0';
67 hp
= gethostbyname(lookup
);
69 result
= HOSTNAME_INVALIDNAME
;
70 else for (; ; hp
->h_addr_list
++) {
71 if (*hp
->h_addr_list
== NULL
) {
72 result
= HOSTNAME_INCORRECTNAME
;
75 if (!memcmp(*hp
->h_addr_list
, ip
, sizeof(*ip
))) {
76 strncpy(host
, trimmed
, hsize
);
77 return HOSTNAME_FOUND
;
83 strncpy(host
, inet_ntoa(*ip
), hsize
);
89 realhostname_sa(char *host
, size_t hsize
, struct sockaddr
*addr
, int addrlen
)
94 result
= HOSTNAME_INVALIDADDR
;
97 /* IPv4 mapped IPv6 addr consideraton, specified in rfc2373. */
98 if (addr
->sa_family
== AF_INET6
&&
99 addrlen
== sizeof(struct sockaddr_in6
) &&
100 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6
*)addr
)->sin6_addr
)) {
101 struct sockaddr_in6
*sin6
;
103 sin6
= (struct sockaddr_in6
*)addr
;
105 memset(&lsin
, 0, sizeof(lsin
));
106 lsin
.sin_len
= sizeof(struct sockaddr_in
);
107 lsin
.sin_family
= AF_INET
;
108 lsin
.sin_port
= sin6
->sin6_port
;
109 memcpy(&lsin
.sin_addr
, &sin6
->sin6_addr
.s6_addr
[12],
110 sizeof(struct in_addr
));
111 addr
= (struct sockaddr
*)&lsin
;
112 addrlen
= lsin
.sin_len
;
116 error
= getnameinfo(addr
, addrlen
, buf
, sizeof(buf
), NULL
, 0,
119 struct addrinfo hints
, *res
, *ores
;
122 memset(&hints
, 0, sizeof(struct addrinfo
));
123 hints
.ai_family
= addr
->sa_family
;
124 hints
.ai_flags
= AI_CANONNAME
| AI_PASSIVE
;
125 hints
.ai_socktype
= SOCK_STREAM
;
127 error
= getaddrinfo(buf
, NULL
, &hints
, &res
);
129 result
= HOSTNAME_INVALIDNAME
;
132 for (ores
= res
; ; res
= res
->ai_next
) {
135 result
= HOSTNAME_INCORRECTNAME
;
141 result
= HOSTNAME_INCORRECTNAME
;
144 if (sa
->sa_len
== addrlen
&&
145 sa
->sa_family
== addr
->sa_family
) {
146 ((struct sockinet
*)sa
)->si_port
= ((struct sockinet
*)addr
)->si_port
;
149 * XXX: sin6_socpe_id may not been
152 if (sa
->sa_family
== AF_INET6
&&
153 ((struct sockaddr_in6
*)sa
)->sin6_scope_id
== 0)
154 ((struct sockaddr_in6
*)sa
)->sin6_scope_id
= ((struct sockaddr_in6
*)addr
)->sin6_scope_id
;
156 if (!memcmp(sa
, addr
, sa
->sa_len
)) {
157 result
= HOSTNAME_FOUND
;
158 if (ores
->ai_canonname
== NULL
) {
162 strlcpy(buf
, ores
->ai_canonname
,
164 trimdomain(buf
, hsize
);
165 if (strlen(buf
) > hsize
&&
166 addr
->sa_family
== AF_INET
) {
170 strncpy(host
, buf
, hsize
);
178 if (getnameinfo(addr
, addrlen
, buf
, sizeof(buf
), NULL
, 0,
179 NI_NUMERICHOST
) == 0)
180 strncpy(host
, buf
, hsize
);