2 This file is part of nss-gns.
4 Parts taken from: nss.c in nss-mdns
6 nss-mdns is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3 of the License,
9 or (at your option) any later version.
11 nss-mdns is distributed in the hope that it will be useful, but1
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with nss-mdns; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22 #include <gnunet_config.h>
28 #include <sys/socket.h>
34 #include "nss_gns_query.h"
36 #include <arpa/inet.h>
38 /** macro to align idx to 32bit boundary */
39 #define ALIGN(idx) do { \
40 if (idx % sizeof(void*)) \
41 idx += (sizeof(void*) - idx % sizeof(void*)); /* Align on 32 bit boundary */ \
46 * The gethostbyname hook executed by nsswitch
48 * @param name the name to resolve
49 * @param af the address family to resolve
50 * @param result the result hostent
51 * @param buffer the result buffer
52 * @param buflen length of the buffer
55 * @return a nss_status code
58 _nss_gns_gethostbyname2_r (const char *name,
60 struct hostent *result,
67 enum nss_status status = NSS_STATUS_UNAVAIL;
69 size_t address_length;
86 if ((af != AF_INET) &&
91 *h_errnop = NO_RECOVERY;
96 address_length = (af == AF_INET) ? sizeof(ipv4_address_t) :
97 sizeof(ipv6_address_t);
99 sizeof(char*) /* alias names */
101 { /* official name */
103 *h_errnop = NO_RECOVERY;
104 status = NSS_STATUS_TRYAGAIN;
110 i = gns_resolve_name (af,
116 status = NSS_STATUS_UNAVAIL;
117 *h_errnop = NO_RECOVERY;
123 *h_errnop = NO_RECOVERY;
124 status = NSS_STATUS_UNAVAIL;
130 *h_errnop = HOST_NOT_FOUND;
131 status = NSS_STATUS_NOTFOUND;
136 *errnop = 0; /* success */
137 *h_errnop = NO_DATA; /* success */
138 status = NSS_STATUS_NOTFOUND;
142 *((char **) buffer) = NULL;
143 result->h_aliases = (char **) buffer;
147 strcpy (buffer + idx,
149 result->h_name = buffer + idx;
150 idx += strlen (name) + 1;
154 result->h_addrtype = af;
155 result->h_length = address_length;
157 /* Check if there's enough space for the addresses */
158 if (buflen < idx + u.data_len + sizeof(char*) * (u.count + 1))
161 *h_errnop = NO_RECOVERY;
162 status = NSS_STATUS_TRYAGAIN;
167 l = u.count * address_length;
169 memcpy (buffer + astart,
172 /* address_length is a multiple of 32bits, so idx is still aligned
176 /* Address array address_length is always a multiple of 32bits */
177 for (i = 0; i < u.count; i++)
178 ((char **) (buffer + idx))[i] = buffer + astart + address_length * i;
179 ((char **) (buffer + idx))[i] = NULL;
180 result->h_addr_list = (char **) (buffer + idx);
182 status = NSS_STATUS_SUCCESS;
190 * The gethostbyname hook executed by nsswitch
192 * @param name the name to resolve
193 * @param result the result hostent
194 * @param buffer the result buffer
195 * @param buflen length of the buffer
196 * @param errnop[out] the low-level error code to return to the application
197 * @param h_errnop idk
198 * @return a nss_status code
201 _nss_gns_gethostbyname_r (const char *name,
202 struct hostent *result,
208 return _nss_gns_gethostbyname2_r (name,
219 * The gethostbyaddr hook executed by nsswitch
220 * We can't do this so we always return NSS_STATUS_UNAVAIL
222 * @param addr the address to resolve
223 * @param len the length of the address
224 * @param af the address family of the address
225 * @param result the result hostent
226 * @param buffer the result buffer
227 * @param buflen length of the buffer
228 * @param errnop[out] the low-level error code to return to the application
229 * @param h_errnop idk
230 * @return NSS_STATUS_UNAVAIL
233 _nss_gns_gethostbyaddr_r (const void*addr,
236 struct hostent *result,
249 *h_errnop = NO_RECOVERY;
250 /* NOTE we allow to leak this into DNS so no NOTFOUND */
251 return NSS_STATUS_UNAVAIL;