source: MondoRescue/branches/3.3/mindi-busybox/libbb/inet_common.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 4.6 KB
RevLine 
[1765]1/* vi: set sw=4 ts=4: */
[821]2/*
3 * stolen from net-tools-1.59 and stripped down for busybox by
4 * Erik Andersen <andersen@codepoet.org>
5 *
6 * Heavily modified by Manuel Novoa III Mar 12, 2001
7 *
[2725]8 * Licensed under GPLv2, see file LICENSE in this source tree.
[821]9 */
10
11#include "libbb.h"
12#include "inet_common.h"
13
[2725]14int FAST_FUNC INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)
[821]15{
16 struct hostent *hp;
[1765]17#if ENABLE_FEATURE_ETC_NETWORKS
[821]18 struct netent *np;
[1765]19#endif
[821]20
21 /* Grmpf. -FvK */
22 s_in->sin_family = AF_INET;
23 s_in->sin_port = 0;
24
25 /* Default is special, meaning 0.0.0.0. */
[2725]26 if (strcmp(name, "default") == 0) {
[821]27 s_in->sin_addr.s_addr = INADDR_ANY;
[1765]28 return 1;
[821]29 }
30 /* Look to see if it's a dotted quad. */
31 if (inet_aton(name, &s_in->sin_addr)) {
32 return 0;
33 }
34 /* If we expect this to be a hostname, try hostname database first */
[3621]35 if (hostfirst) {
[821]36#ifdef DEBUG
[1765]37 bb_error_msg("gethostbyname(%s)", name);
[821]38#endif
[1765]39 hp = gethostbyname(name);
[3621]40 if (hp) {
[1765]41 memcpy(&s_in->sin_addr, hp->h_addr_list[0],
42 sizeof(struct in_addr));
43 return 0;
44 }
[821]45 }
[1765]46#if ENABLE_FEATURE_ETC_NETWORKS
[821]47 /* Try the NETWORKS database to see if this is a known network. */
48#ifdef DEBUG
[1765]49 bb_error_msg("getnetbyname(%s)", name);
[821]50#endif
[1765]51 np = getnetbyname(name);
[3621]52 if (np) {
[821]53 s_in->sin_addr.s_addr = htonl(np->n_net);
54 return 1;
55 }
[1765]56#endif
[821]57 if (hostfirst) {
58 /* Don't try again */
59 return -1;
60 }
61#ifdef DEBUG
62 res_init();
63 _res.options |= RES_DEBUG;
[1765]64 bb_error_msg("gethostbyname(%s)", name);
[821]65#endif
[1765]66 hp = gethostbyname(name);
[3621]67 if (!hp) {
[821]68 return -1;
69 }
[1765]70 memcpy(&s_in->sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
[821]71 return 0;
72}
73
74
[3621]75/* numeric: & 0x8000: "default" instead of "*",
[821]76 * & 0x4000: host instead of net,
77 * & 0x0fff: don't resolve
78 */
[2725]79char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t netmask)
[821]80{
[1765]81 /* addr-to-name cache */
82 struct addr {
83 struct addr *next;
[3621]84 uint32_t nip;
85 smallint is_host;
[1765]86 char name[1];
87 };
88 static struct addr *cache = NULL;
89
[821]90 struct addr *pn;
[1765]91 char *name;
[3621]92 uint32_t nip;
93 smallint is_host;
[821]94
95 if (s_in->sin_family != AF_INET) {
96#ifdef DEBUG
[1765]97 bb_error_msg("rresolve: unsupported address family %d!",
[3232]98 s_in->sin_family);
[821]99#endif
100 errno = EAFNOSUPPORT;
[1765]101 return NULL;
[821]102 }
[3621]103 nip = s_in->sin_addr.s_addr;
[821]104#ifdef DEBUG
[3621]105 bb_error_msg("rresolve: %08x mask:%08x num:%08x", (unsigned)nip, netmask, numeric);
[821]106#endif
[3621]107 if (numeric & 0x0FFF)
108 return xmalloc_sockaddr2dotted_noport((void*)s_in);
109 if (nip == INADDR_ANY) {
110 if (numeric & 0x8000)
111 return xstrdup("default");
112 return xstrdup("*");
[821]113 }
114
[3621]115 is_host = ((nip & (~netmask)) != 0 || (numeric & 0x4000));
116
[1765]117 pn = cache;
118 while (pn) {
[3621]119 if (pn->nip == nip && pn->is_host == is_host) {
[821]120#ifdef DEBUG
[1765]121 bb_error_msg("rresolve: found %s %08x in cache",
[3621]122 (is_host ? "host" : "net"), (unsigned)nip);
[821]123#endif
[1765]124 return xstrdup(pn->name);
[821]125 }
126 pn = pn->next;
127 }
128
[1765]129 name = NULL;
[3621]130 if (is_host) {
[821]131#ifdef DEBUG
[3621]132 bb_error_msg("sockaddr2host_noport(%08x)", (unsigned)nip);
[821]133#endif
[3621]134 name = xmalloc_sockaddr2host_noport((void*)s_in);
[1765]135 } else if (ENABLE_FEATURE_ETC_NETWORKS) {
136 struct netent *np;
[821]137#ifdef DEBUG
[3621]138 bb_error_msg("getnetbyaddr(%08x)", (unsigned)ntohl(nip));
[821]139#endif
[3621]140 np = getnetbyaddr(ntohl(nip), AF_INET);
[1765]141 if (np)
142 name = xstrdup(np->n_name);
[821]143 }
[1765]144 if (!name)
[3621]145 name = xmalloc_sockaddr2dotted_noport((void*)s_in);
146
[1765]147 pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */
148 pn->next = cache;
[3621]149 pn->nip = nip;
150 pn->is_host = is_host;
[1765]151 strcpy(pn->name, name);
152 cache = pn;
[3621]153
[1765]154 return name;
[821]155}
156
[1765]157#if ENABLE_FEATURE_IPV6
[821]158
[2725]159int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6)
[821]160{
[3232]161 struct addrinfo req, *ai = NULL;
[821]162 int s;
163
[3232]164 memset(&req, 0, sizeof(req));
[821]165 req.ai_family = AF_INET6;
[1765]166 s = getaddrinfo(name, NULL, &req, &ai);
[3232]167 if (s != 0) {
[821]168 bb_error_msg("getaddrinfo: %s: %d", name, s);
169 return -1;
170 }
[3232]171 memcpy(sin6, ai->ai_addr, sizeof(*sin6));
[3621]172 freeaddrinfo(ai);
[1765]173 return 0;
[821]174}
175
176#ifndef IN6_IS_ADDR_UNSPECIFIED
177# define IN6_IS_ADDR_UNSPECIFIED(a) \
178 (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
179 ((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] == 0)
180#endif
181
182
[2725]183char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric)
[821]184{
185 if (sin6->sin6_family != AF_INET6) {
186#ifdef DEBUG
[2725]187 bb_error_msg("rresolve: unsupported address family %d!",
[3232]188 sin6->sin6_family);
[821]189#endif
190 errno = EAFNOSUPPORT;
[1765]191 return NULL;
[821]192 }
193 if (numeric & 0x7FFF) {
[3621]194 return xmalloc_sockaddr2dotted_noport((void*)sin6);
[821]195 }
196 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
[1765]197 if (numeric & 0x8000)
[2725]198 return xstrdup("default");
[1765]199 return xstrdup("*");
[821]200 }
201
[3621]202 return xmalloc_sockaddr2host_noport((void*)sin6);
[821]203}
204
[2725]205#endif /* CONFIG_FEATURE_IPV6 */
Note: See TracBrowser for help on using the repository browser.