GNUnet 0.22.0
nss_gns.c
Go to the documentation of this file.
1/***
2 This file is part of nss-gns.
3
4 Parts taken from: nss.c in nss-mdns
5
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.
10
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.
15
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
19 USA.
20 ***/
21
22#include <gnunet_private_config.h>
23#include <unistd.h>
24#include <errno.h>
25#include <string.h>
26#include <assert.h>
27#include <netdb.h>
28#include <sys/socket.h>
29#include <nss.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <errno.h>
33
34#include "nss_gns_query.h"
35
36#include <arpa/inet.h>
37
39#define ALIGN(idx) do { \
40 if (idx % sizeof(void*)) \
41 idx += (sizeof(void*) - idx % sizeof(void*)); /* Align on 32 bit boundary */ \
42} while (0)
43
44enum nss_status
46 int af,
47 struct hostent *result,
48 char *buffer,
49 size_t buflen,
50 int *errnop,
51 int *h_errnop);
52
65enum nss_status
67 int af,
68 struct hostent *result,
69 char *buffer,
70 size_t buflen,
71 int *errnop,
72 int *h_errnop)
73{
74 struct userdata u;
75 enum nss_status status = NSS_STATUS_UNAVAIL;
76 int i;
77 size_t address_length;
78 size_t l;
79 size_t idx;
80 size_t astart;
81
82 if (af == AF_UNSPEC)
83#ifdef NSS_IPV6_ONLY
84 af = AF_INET6;
85#else
86 af = AF_INET;
87#endif
88
89#ifdef NSS_IPV4_ONLY
90 if (af != AF_INET)
91#elif NSS_IPV6_ONLY
92 if (af != AF_INET6)
93#else
94 if ((af != AF_INET) &&
95 (af != AF_INET6))
96#endif
97 {
98 *errnop = EINVAL;
99 *h_errnop = NO_RECOVERY;
100
101 goto finish;
102 }
103
104 address_length = (af == AF_INET) ? sizeof(ipv4_address_t) :
105 sizeof(ipv6_address_t);
106 if (buflen <
107 sizeof(char*) /* alias names */
108 + strlen (name) + 1)
109 { /* official name */
110 *errnop = ERANGE;
111 *h_errnop = NO_RECOVERY;
112 status = NSS_STATUS_TRYAGAIN;
113
114 goto finish;
115 }
116 u.count = 0;
117 u.data_len = 0;
118 i = gns_resolve_name (af,
119 name,
120 &u);
121 if (-1 == i)
122 {
123 *errnop = errno;
124 status = NSS_STATUS_UNAVAIL;
125 *h_errnop = NO_RECOVERY;
126 goto finish;
127 }
128 if (-2 == i)
129 {
130 *errnop = ENOENT;
131 *h_errnop = NO_RECOVERY;
132 status = NSS_STATUS_UNAVAIL;
133 goto finish;
134 }
135 if (-3 == i)
136 {
137 *errnop = ETIMEDOUT;
138 *h_errnop = HOST_NOT_FOUND;
139 status = NSS_STATUS_NOTFOUND;
140 goto finish;
141 }
142 if (0 == u.count)
143 {
144 *errnop = 0; /* success */
145 *h_errnop = NO_DATA; /* success */
146 status = NSS_STATUS_NOTFOUND;
147 goto finish;
148 }
149 /* Alias names */
150 *((char **) buffer) = NULL;
151 result->h_aliases = (char **) buffer;
152 idx = sizeof(char*);
153
154 /* Official name */
155 strcpy (buffer + idx,
156 name);
157 result->h_name = buffer + idx;
158 idx += strlen (name) + 1;
159
160 ALIGN (idx);
161
162 result->h_addrtype = af;
163 result->h_length = address_length;
164
165 /* Check if there's enough space for the addresses */
166 if (buflen < idx + u.data_len + sizeof(char*) * (u.count + 1))
167 {
168 *errnop = ERANGE;
169 *h_errnop = NO_RECOVERY;
170 status = NSS_STATUS_TRYAGAIN;
171 goto finish;
172 }
173 /* Addresses */
174 astart = idx;
175 l = u.count * address_length;
176 if (0 != l)
177 memcpy (buffer + astart,
178 &u.data,
179 l);
180 /* address_length is a multiple of 32bits, so idx is still aligned
181 * correctly */
182 idx += l;
183
184 /* Address array address_length is always a multiple of 32bits */
185 for (i = 0; i < u.count; i++)
186 ((char **) (buffer + idx))[i] = buffer + astart + address_length * i;
187 ((char **) (buffer + idx))[i] = NULL;
188 result->h_addr_list = (char **) (buffer + idx);
189
190 status = NSS_STATUS_SUCCESS;
191
192finish:
193 return status;
194}
195
196enum nss_status
197_nss_gns_gethostbyname_r (const char *name,
198 struct hostent *result,
199 char *buffer,
200 size_t buflen,
201 int *errnop,
202 int *h_errnop);
214enum nss_status
216 struct hostent *result,
217 char *buffer,
218 size_t buflen,
219 int *errnop,
220 int *h_errnop)
221{
223 AF_UNSPEC,
224 result,
225 buffer,
226 buflen,
227 errnop,
228 h_errnop);
229}
230
231enum nss_status
232_nss_gns_gethostbyaddr_r (const void*addr,
233 int len,
234 int af,
235 struct hostent *result,
236 char *buffer,
237 size_t buflen,
238 int *errnop,
239 int *h_errnop);
254enum nss_status
256 int len,
257 int af,
258 struct hostent *result,
259 char *buffer,
260 size_t buflen,
261 int *errnop,
262 int *h_errnop)
263{
264 (void) addr;
265 (void) len;
266 (void) af;
267 (void) result;
268 (void) buffer;
269 (void) buflen;
270 *errnop = EINVAL;
271 *h_errnop = NO_RECOVERY;
272 /* NOTE we allow to leak this into DNS so no NOTFOUND */
273 return NSS_STATUS_UNAVAIL;
274}
static mp_limb_t u[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static char * name
Name (label) of the records to list.
static int status
The program status; 0 for success.
Definition: gnunet-nse.c:39
static int result
Global testing status.
enum nss_status _nss_gns_gethostbyname_r(const char *name, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop)
The gethostbyname hook executed by nsswitch.
Definition: nss_gns.c:215
enum nss_status _nss_gns_gethostbyname2_r(const char *name, int af, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop)
The gethostbyname hook executed by nsswitch.
Definition: nss_gns.c:66
#define ALIGN(idx)
macro to align idx to 32bit boundary
Definition: nss_gns.c:39
enum nss_status _nss_gns_gethostbyaddr_r(const void *addr, int len, int af, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop)
The gethostbyaddr hook executed by nsswitch We can't do this so we always return NSS_STATUS_UNAVAIL.
Definition: nss_gns.c:255
int gns_resolve_name(int af, const char *name, struct userdata *u)
Wrapper function that uses gnunet-gns cli tool to resolve an IPv4/6 address.
Definition: nss_gns_query.c:58