1 /* vi: set sw=4 ts=4: */
3 * stolen from net-tools-1.59 and stripped down for busybox by
4 * Erik Andersen <andersen@codepoet.org>
6 * Heavily modified by Manuel Novoa III Mar 12, 2001
8 * Licensed under GPLv2, see file LICENSE in this source tree.
12 #include "inet_common.h"
14 int FAST_FUNC
INET_resolve(const char *name
, struct sockaddr_in
*s_in
, int hostfirst
)
17 #if ENABLE_FEATURE_ETC_NETWORKS
22 s_in
->sin_family
= AF_INET
;
25 /* Default is special, meaning 0.0.0.0. */
26 if (strcmp(name
, "default") == 0) {
27 s_in
->sin_addr
.s_addr
= INADDR_ANY
;
30 /* Look to see if it's a dotted quad. */
31 if (inet_aton(name
, &s_in
->sin_addr
)) {
34 /* If we expect this to be a hostname, try hostname database first */
37 bb_error_msg("gethostbyname(%s)", name
);
41 hp
= gethostbyname(name
);
43 memcpy(&s_in
->sin_addr
, hp
->h_addr_list
[0],
44 sizeof(struct in_addr
));
48 #if ENABLE_FEATURE_ETC_NETWORKS
49 /* Try the NETWORKS database to see if this is a known network. */
51 bb_error_msg("getnetbyname(%s)", name
);
53 np
= getnetbyname(name
);
55 s_in
->sin_addr
.s_addr
= htonl(np
->n_net
);
65 _res
.options
|= RES_DEBUG
;
66 bb_error_msg("gethostbyname(%s)", name
);
68 hp
= gethostbyname(name
);
72 memcpy(&s_in
->sin_addr
, hp
->h_addr_list
[0], sizeof(struct in_addr
));
77 /* numeric: & 0x8000: default instead of *,
78 * & 0x4000: host instead of net,
79 * & 0x0fff: don't resolve
81 char* FAST_FUNC
INET_rresolve(struct sockaddr_in
*s_in
, int numeric
, uint32_t netmask
)
83 /* addr-to-name cache */
86 struct sockaddr_in addr
;
90 static struct addr
*cache
= NULL
;
97 if (s_in
->sin_family
!= AF_INET
) {
99 bb_error_msg("rresolve: unsupported address family %d!",
102 errno
= EAFNOSUPPORT
;
105 ad
= s_in
->sin_addr
.s_addr
;
107 bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad
, netmask
, numeric
);
109 if (ad
== INADDR_ANY
) {
110 if ((numeric
& 0x0FFF) == 0) {
111 if (numeric
& 0x8000)
112 return xstrdup("default");
116 if (numeric
& 0x0FFF)
117 return xstrdup(inet_ntoa(s_in
->sin_addr
));
119 if ((ad
& (~netmask
)) != 0 || (numeric
& 0x4000))
123 if (pn
->addr
.sin_addr
.s_addr
== ad
&& pn
->host
== host
) {
125 bb_error_msg("rresolve: found %s %08x in cache",
126 (host
? "host" : "net"), (unsigned)ad
);
128 return xstrdup(pn
->name
);
138 bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad
);
140 ent
= gethostbyaddr((char *) &ad
, 4, AF_INET
);
142 name
= xstrdup(ent
->h_name
);
143 } else if (ENABLE_FEATURE_ETC_NETWORKS
) {
146 bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad
);
148 np
= getnetbyaddr(host_ad
, AF_INET
);
150 name
= xstrdup(np
->n_name
);
153 name
= xstrdup(inet_ntoa(s_in
->sin_addr
));
154 pn
= xmalloc(sizeof(*pn
) + strlen(name
)); /* no '+ 1', it's already accounted for */
158 strcpy(pn
->name
, name
);
163 #if ENABLE_FEATURE_IPV6
165 int FAST_FUNC
INET6_resolve(const char *name
, struct sockaddr_in6
*sin6
)
167 struct addrinfo req
, *ai
= NULL
;
170 memset(&req
, 0, sizeof(req
));
171 req
.ai_family
= AF_INET6
;
172 s
= getaddrinfo(name
, NULL
, &req
, &ai
);
174 bb_error_msg("getaddrinfo: %s: %d", name
, s
);
177 memcpy(sin6
, ai
->ai_addr
, sizeof(*sin6
));
183 #ifndef IN6_IS_ADDR_UNSPECIFIED
184 # define IN6_IS_ADDR_UNSPECIFIED(a) \
185 (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
186 ((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] == 0)
190 char* FAST_FUNC
INET6_rresolve(struct sockaddr_in6
*sin6
, int numeric
)
195 if (sin6
->sin6_family
!= AF_INET6
) {
197 bb_error_msg("rresolve: unsupported address family %d!",
200 errno
= EAFNOSUPPORT
;
203 if (numeric
& 0x7FFF) {
204 inet_ntop(AF_INET6
, &sin6
->sin6_addr
, name
, sizeof(name
));
205 return xstrdup(name
);
207 if (IN6_IS_ADDR_UNSPECIFIED(&sin6
->sin6_addr
)) {
208 if (numeric
& 0x8000)
209 return xstrdup("default");
213 s
= getnameinfo((struct sockaddr
*) sin6
, sizeof(*sin6
),
215 /*serv,servlen:*/ NULL
, 0,
218 bb_error_msg("getnameinfo failed");
221 return xstrdup(name
);
224 #endif /* CONFIG_FEATURE_IPV6 */