socket: fix broken connect for non broadcast traffic
[deb_libnfs.git] / portmap / portmap.c
CommitLineData
84004dbf
RS
1/*
2 Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
16*/
a8a1b858
M
17#ifdef WIN32
18#include "win32_compat.h"
19#endif/*WIN32*/
84004dbf
RS
20
21#include <stdio.h>
763cd6e3 22#include "libnfs-zdr.h"
84004dbf
RS
23#include "libnfs.h"
24#include "libnfs-raw.h"
25#include "libnfs-private.h"
26#include "libnfs-raw-portmap.h"
27
4edd7830
RS
28/*
29 * PORTMAP v2
30 */
0f0e352f 31int rpc_pmap2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data)
84004dbf
RS
32{
33 struct rpc_pdu *pdu;
34
0f0e352f 35 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_NULL, cb, private_data, (zdrproc_t)zdr_void, 0);
84004dbf 36 if (pdu == NULL) {
0f0e352f 37 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/NULL call");
84004dbf
RS
38 return -1;
39 }
40
41 if (rpc_queue_pdu(rpc, pdu) != 0) {
0f0e352f 42 rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP2/NULL call");
84004dbf 43 rpc_free_pdu(rpc, pdu);
1896d37b 44 return -1;
84004dbf
RS
45 }
46
47 return 0;
48}
49
0f0e352f 50int rpc_pmap2_getport_async(struct rpc_context *rpc, int program, int version, int protocol, rpc_cb cb, void *private_data)
84004dbf
RS
51{
52 struct rpc_pdu *pdu;
4edd7830 53 struct pmap2_mapping m;
84004dbf 54
0f0e352f 55 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_GETPORT, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t));
84004dbf 56 if (pdu == NULL) {
0f0e352f 57 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/GETPORT call");
84004dbf
RS
58 return -1;
59 }
60
61 m.prog = program;
62 m.vers = version;
5c6b1176 63 m.prot = protocol;
84004dbf 64 m.port = 0;
4edd7830 65 if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) {
0f0e352f 66 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/GETPORT call");
84004dbf 67 rpc_free_pdu(rpc, pdu);
1896d37b 68 return -1;
84004dbf
RS
69 }
70
71 if (rpc_queue_pdu(rpc, pdu) != 0) {
0f0e352f 72 rpc_set_error(rpc, "Failed to queue PORTMAP2/GETPORT pdu");
84004dbf 73 rpc_free_pdu(rpc, pdu);
1896d37b 74 return -1;
84004dbf
RS
75 }
76
77 return 0;
78}
fd59fd0d 79
0f0e352f 80int rpc_pmap2_set_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data)
1fbe4080
RS
81{
82 struct rpc_pdu *pdu;
4edd7830 83 struct pmap2_mapping m;
1fbe4080 84
0f0e352f 85 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t));
1fbe4080 86 if (pdu == NULL) {
0f0e352f 87 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/SET call");
1fbe4080
RS
88 return -1;
89 }
90
91 m.prog = program;
92 m.vers = version;
93 m.prot = protocol;
94 m.port = port;
4edd7830 95 if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) {
0f0e352f 96 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/SET call");
1fbe4080
RS
97 rpc_free_pdu(rpc, pdu);
98 return -1;
99 }
100
101 if (rpc_queue_pdu(rpc, pdu) != 0) {
0f0e352f 102 rpc_set_error(rpc, "Failed to queue PORTMAP2/SET pdu");
1fbe4080
RS
103 rpc_free_pdu(rpc, pdu);
104 return -1;
105 }
106
107 return 0;
108}
109
0f0e352f 110int rpc_pmap2_unset_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data)
1fbe4080
RS
111{
112 struct rpc_pdu *pdu;
4edd7830 113 struct pmap2_mapping m;
1fbe4080 114
0f0e352f 115 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t));
1fbe4080 116 if (pdu == NULL) {
0f0e352f 117 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/UNSET call");
1fbe4080
RS
118 return -1;
119 }
120
121 m.prog = program;
122 m.vers = version;
123 m.prot = protocol;
124 m.port = port;
4edd7830 125 if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) {
0f0e352f 126 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/UNSET call");
1fbe4080
RS
127 rpc_free_pdu(rpc, pdu);
128 return -1;
129 }
130
131 if (rpc_queue_pdu(rpc, pdu) != 0) {
0f0e352f 132 rpc_set_error(rpc, "Failed to queue PORTMAP2/UNSET pdu");
1fbe4080
RS
133 rpc_free_pdu(rpc, pdu);
134 return -1;
135 }
136
137 return 0;
138}
139
0f0e352f 140int rpc_pmap2_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data)
8ae943f6
RS
141{
142 struct rpc_pdu *pdu;
143
4edd7830 144 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_DUMP, cb, private_data, (zdrproc_t)zdr_pmap2_dump_result, sizeof(pmap2_dump_result));
8ae943f6 145 if (pdu == NULL) {
0f0e352f 146 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/DUMP call");
8ae943f6
RS
147 return -1;
148 }
149
150 if (rpc_queue_pdu(rpc, pdu) != 0) {
0f0e352f 151 rpc_set_error(rpc, "Failed to queue PORTMAP2/DUMP pdu");
8ae943f6
RS
152 rpc_free_pdu(rpc, pdu);
153 return -1;
154 }
155
156 return 0;
157}
158
0f0e352f 159int rpc_pmap2_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data)
fd59fd0d
RS
160{
161 struct rpc_pdu *pdu;
4edd7830 162 struct pmap2_call_args ca;
fd59fd0d 163
4edd7830 164 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_CALLIT, cb, private_data, (zdrproc_t)zdr_pmap2_call_result, sizeof(pmap2_call_result));
fd59fd0d 165 if (pdu == NULL) {
0f0e352f 166 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/CALLIT call");
fd59fd0d
RS
167 return -1;
168 }
169
170 ca.prog = program;
171 ca.vers = version;
172 ca.proc = procedure;
173 ca.args.args_len = datalen;
174 ca.args.args_val = data;
175
4edd7830 176 if (zdr_pmap2_call_args(&pdu->zdr, &ca) == 0) {
0f0e352f 177 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/CALLIT call");
fd59fd0d
RS
178 rpc_free_pdu(rpc, pdu);
179 return -1;
180 }
181
182 if (rpc_queue_pdu(rpc, pdu) != 0) {
0f0e352f 183 rpc_set_error(rpc, "Failed to queue PORTMAP2/CALLIT pdu: %s", rpc_get_error(rpc));
fd59fd0d
RS
184 return -1;
185 }
186
187 return 0;
188}
4edd7830
RS
189
190/*
191 * PORTMAP v3
192 */
193int rpc_pmap3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data)
194{
195 struct rpc_pdu *pdu;
196
197 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0);
198 if (pdu == NULL) {
199 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/NULL call");
200 return -1;
201 }
202
203 if (rpc_queue_pdu(rpc, pdu) != 0) {
204 rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP3/NULL call");
205 rpc_free_pdu(rpc, pdu);
206 return -1;
207 }
208
209 return 0;
210}
211
d731e94c
RS
212int rpc_pmap3_set_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data)
213{
214 struct rpc_pdu *pdu;
215
216 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t));
217 if (pdu == NULL) {
218 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/SET call");
219 return -1;
220 }
221
222 if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) {
223 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/SET call");
224 rpc_free_pdu(rpc, pdu);
225 return -1;
226 }
227
228 if (rpc_queue_pdu(rpc, pdu) != 0) {
229 rpc_set_error(rpc, "Failed to queue PORTMAP3/SET pdu");
230 rpc_free_pdu(rpc, pdu);
231 return -1;
232 }
233
234 return 0;
235}
236
237int rpc_pmap3_unset_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data)
238{
239 struct rpc_pdu *pdu;
240
241 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t));
242 if (pdu == NULL) {
243 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/UNSET call");
244 return -1;
245 }
246
247 if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) {
248 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/UNSET call");
249 rpc_free_pdu(rpc, pdu);
250 return -1;
251 }
252
253 if (rpc_queue_pdu(rpc, pdu) != 0) {
254 rpc_set_error(rpc, "Failed to queue PORTMAP3/UNSET pdu");
255 rpc_free_pdu(rpc, pdu);
256 return -1;
257 }
258
259 return 0;
260}
261
7fbedfde
RS
262int rpc_pmap3_getaddr_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data)
263{
264 struct rpc_pdu *pdu;
265
24f45c54 266 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_GETADDR, cb, private_data, (zdrproc_t)zdr_pmap3_string_result, sizeof(pmap3_string_result));
7fbedfde
RS
267 if (pdu == NULL) {
268 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/GETADDR call");
269 return -1;
270 }
271
272 if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) {
273 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/GETADDR call");
274 rpc_free_pdu(rpc, pdu);
275 return -1;
276 }
277
278 if (rpc_queue_pdu(rpc, pdu) != 0) {
279 rpc_set_error(rpc, "Failed to queue PORTMAP3/GETADDR pdu");
280 rpc_free_pdu(rpc, pdu);
281 return -1;
282 }
283
284 return 0;
285}
286
4edd7830
RS
287int rpc_pmap3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data)
288{
289 struct rpc_pdu *pdu;
290
291 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_DUMP, cb, private_data, (zdrproc_t)zdr_pmap3_dump_result, sizeof(pmap3_dump_result));
292 if (pdu == NULL) {
293 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/DUMP call");
294 return -1;
295 }
296
297 if (rpc_queue_pdu(rpc, pdu) != 0) {
298 rpc_set_error(rpc, "Failed to queue PORTMAP3/DUMP pdu");
299 rpc_free_pdu(rpc, pdu);
300 return -1;
301 }
302
303 return 0;
304}
5245608a
RS
305
306int rpc_pmap3_gettime_async(struct rpc_context *rpc, rpc_cb cb, void *private_data)
307{
308 struct rpc_pdu *pdu;
309
310 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_GETTIME, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t));
311 if (pdu == NULL) {
312 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/GETTIME call");
313 return -1;
314 }
315
316 if (rpc_queue_pdu(rpc, pdu) != 0) {
317 rpc_set_error(rpc, "Failed to queue PORTMAP3/GETTIME pdu");
318 rpc_free_pdu(rpc, pdu);
319 return -1;
320 }
321
322 return 0;
323}
b71f7e82
RS
324
325int rpc_pmap3_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data)
326{
327 struct rpc_pdu *pdu;
328 struct pmap3_call_args ca;
329
330 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_CALLIT, cb, private_data, (zdrproc_t)zdr_pmap3_call_result, sizeof(pmap3_call_result));
331 if (pdu == NULL) {
332 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/CALLIT call");
333 return -1;
334 }
335
336 ca.prog = program;
337 ca.vers = version;
338 ca.proc = procedure;
339 ca.args.args_len = datalen;
340 ca.args.args_val = data;
341
342 if (zdr_pmap3_call_args(&pdu->zdr, &ca) == 0) {
343 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/CALLIT call");
344 rpc_free_pdu(rpc, pdu);
345 return -1;
346 }
347
348 if (rpc_queue_pdu(rpc, pdu) != 0) {
349 rpc_set_error(rpc, "Failed to queue PORTMAP3/CALLIT pdu: %s", rpc_get_error(rpc));
350 return -1;
351 }
352
353 return 0;
354}
729266a7
RS
355
356int rpc_pmap3_uaddr2taddr_async(struct rpc_context *rpc, char *uaddr, rpc_cb cb, void *private_data)
357{
358 struct rpc_pdu *pdu;
359
360 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_UADDR2TADDR, cb, private_data, (zdrproc_t)zdr_pmap3_netbuf, sizeof(pmap3_netbuf));
361 if (pdu == NULL) {
362 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/UADDR2TADDR call");
363 return -1;
364 }
365
366 if (zdr_string(&pdu->zdr, &uaddr, 255) == 0) {
367 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/UADDR2TADDR call");
368 rpc_free_pdu(rpc, pdu);
369 return -1;
370 }
371
372 if (rpc_queue_pdu(rpc, pdu) != 0) {
373 rpc_set_error(rpc, "Failed to queue PORTMAP3/UADDR2TADDR pdu: %s", rpc_get_error(rpc));
374 return -1;
375 }
376
377 return 0;
378}
29258a73
RS
379
380int rpc_pmap3_taddr2uaddr_async(struct rpc_context *rpc, struct pmap3_netbuf *nb, rpc_cb cb, void *private_data)
381{
382 struct rpc_pdu *pdu;
383
24f45c54 384 pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_TADDR2UADDR, cb, private_data, (zdrproc_t)zdr_pmap3_string_result, sizeof(pmap3_string_result));
29258a73
RS
385 if (pdu == NULL) {
386 rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/TADDR2UADDR call");
387 return -1;
388 }
389
390 if (zdr_pmap3_netbuf(&pdu->zdr, nb) == 0) {
391 rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/TADDR2UADDR call");
392 rpc_free_pdu(rpc, pdu);
393 return -1;
394 }
395
396 if (rpc_queue_pdu(rpc, pdu) != 0) {
397 rpc_set_error(rpc, "Failed to queue PORTMAP3/TADDR2UADDR pdu: %s", rpc_get_error(rpc));
398 return -1;
399 }
400
401 return 0;
402}