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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 #include <gnunet_config.h>
28 #include <sys/socket.h>
33 #include "nss_gns_query.h"
35 #include <arpa/inet.h>
37 /** macro to align idx to 32bit boundary */
38 #define ALIGN(idx) do { \
39 if (idx % sizeof(void*)) \
40 idx += (sizeof(void*) - idx % sizeof(void*)); /* Align on 32 bit boundary */ \
45 * function to check if name ends with a specific suffix
47 * @param name the name to check
48 * @param suffix the suffix to check for
51 static int ends_with(const char *name, const char* suffix) {
56 if ((ls = strlen(suffix)) > (ln = strlen(name)))
59 return strcasecmp(name+ln-ls, suffix) == 0;
64 * Check if name is inside .gnu or .zkey TLD
66 * @param name name to check
69 static int verify_name_allowed (const char *name) {
70 return ends_with(name, ".gnu") || ends_with(name, ".zkey");
74 * The gethostbyname hook executed by nsswitch
76 * @param name the name to resolve
77 * @param af the address family to resolve
78 * @param result the result hostent
79 * @param buffer the result buffer
80 * @param buflen length of the buffer
83 * @return a nss_status code
85 enum nss_status _nss_gns_gethostbyname2_r(
88 struct hostent * result,
95 enum nss_status status = NSS_STATUS_UNAVAIL;
97 size_t address_length, l, idx, astart;
112 if (af != AF_INET && af != AF_INET6)
116 *h_errnop = NO_RECOVERY;
121 address_length = af == AF_INET ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t);
123 sizeof(char*)+ /* alias names */
124 strlen(name)+1) { /* official name */
127 *h_errnop = NO_RECOVERY;
128 status = NSS_STATUS_TRYAGAIN;
136 name_allowed = verify_name_allowed(name);
140 if (!gns_resolve_name(af, name, &u) == 0)
142 status = NSS_STATUS_NOTFOUND;
148 status = NSS_STATUS_UNAVAIL;
154 *h_errnop = HOST_NOT_FOUND;
155 status = NSS_STATUS_NOTFOUND;
161 *((char**) buffer) = NULL;
162 result->h_aliases = (char**) buffer;
166 strcpy(buffer+idx, name);
167 result->h_name = buffer+idx;
168 idx += strlen(name)+1;
172 result->h_addrtype = af;
173 result->h_length = address_length;
175 /* Check if there's enough space for the addresses */
176 if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) {
178 *h_errnop = NO_RECOVERY;
179 status = NSS_STATUS_TRYAGAIN;
185 l = u.count*address_length;
186 memcpy(buffer+astart, &u.data, l);
187 /* address_length is a multiple of 32bits, so idx is still aligned
191 /* Address array address_lenght is always a multiple of 32bits */
192 for (i = 0; i < u.count; i++)
193 ((char**) (buffer+idx))[i] = buffer+astart+address_length*i;
194 ((char**) (buffer+idx))[i] = NULL;
195 result->h_addr_list = (char**) (buffer+idx);
197 status = NSS_STATUS_SUCCESS;
204 * The gethostbyname hook executed by nsswitch
206 * @param name the name to resolve
207 * @param result the result hostent
208 * @param buffer the result buffer
209 * @param buflen length of the buffer
211 * @param h_errnop idk
212 * @return a nss_status code
214 enum nss_status _nss_gns_gethostbyname_r (
216 struct hostent *result,
222 return _nss_gns_gethostbyname2_r(
233 * The gethostbyaddr hook executed by nsswitch
234 * We can't do this so we always return NSS_STATUS_UNAVAIL
236 * @param addr the address to resolve
237 * @param len the length of the address
238 * @param af the address family of the address
239 * @param result the result hostent
240 * @param buffer the result buffer
241 * @param buflen length of the buffer
243 * @param h_errnop idk
244 * @return NSS_STATUS_UNAVAIL
246 enum nss_status _nss_gns_gethostbyaddr_r(
250 struct hostent *result,
256 /* we dont do this */
258 enum nss_status status = NSS_STATUS_UNAVAIL;
261 *h_errnop = NO_RECOVERY;
263 /* Check for address types */
265 *h_errnop = NO_RECOVERY;
267 status = NSS_STATUS_NOTFOUND;