1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/module.h>
16
17#include <linux/types.h>
18#include <linux/socket.h>
19#include <linux/in.h>
20#include <linux/in6.h>
21#include <linux/kernel.h>
22#include <linux/errno.h>
23#include <net/ipv6.h>
24
25#include <linux/sunrpc/clnt.h>
26#include <linux/sunrpc/sched.h>
27#include <linux/sunrpc/xprtsock.h>
28
29#ifdef RPC_DEBUG
30# define RPCDBG_FACILITY RPCDBG_BIND
31#endif
32
33#define RPCBIND_PROGRAM (100000u)
34#define RPCBIND_PORT (111u)
35
36#define RPCBVERS_2 (2u)
37#define RPCBVERS_3 (3u)
38#define RPCBVERS_4 (4u)
39
40enum {
41 RPCBPROC_NULL,
42 RPCBPROC_SET,
43 RPCBPROC_UNSET,
44 RPCBPROC_GETPORT,
45 RPCBPROC_GETADDR = 3,
46 RPCBPROC_DUMP,
47 RPCBPROC_CALLIT,
48 RPCBPROC_BCAST = 5,
49 RPCBPROC_GETTIME,
50 RPCBPROC_UADDR2TADDR,
51 RPCBPROC_TADDR2UADDR,
52 RPCBPROC_GETVERSADDR,
53 RPCBPROC_INDIRECT,
54 RPCBPROC_GETADDRLIST,
55 RPCBPROC_GETSTAT,
56};
57
58#define RPCB_HIGHPROC_2 RPCBPROC_CALLIT
59#define RPCB_HIGHPROC_3 RPCBPROC_TADDR2UADDR
60#define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75#define RPCB_OWNER_STRING "0"
76#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
77
78
79
80
81#define RPCB_program_sz (1)
82#define RPCB_version_sz (1)
83#define RPCB_protocol_sz (1)
84#define RPCB_port_sz (1)
85#define RPCB_boolean_sz (1)
86
87#define RPCB_netid_sz (1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
88#define RPCB_addr_sz (1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
89#define RPCB_ownerstring_sz (1 + XDR_QUADLEN(RPCB_MAXOWNERLEN))
90
91
92
93
94#define RPCB_mappingargs_sz (RPCB_program_sz + RPCB_version_sz + \
95 RPCB_protocol_sz + RPCB_port_sz)
96#define RPCB_getaddrargs_sz (RPCB_program_sz + RPCB_version_sz + \
97 RPCB_netid_sz + RPCB_addr_sz + \
98 RPCB_ownerstring_sz)
99
100#define RPCB_getportres_sz RPCB_port_sz
101#define RPCB_setres_sz RPCB_boolean_sz
102
103
104
105
106
107#define RPCB_getaddrres_sz RPCB_addr_sz
108
109static void rpcb_getport_done(struct rpc_task *, void *);
110static void rpcb_map_release(void *data);
111static struct rpc_program rpcb_program;
112
113struct rpcbind_args {
114 struct rpc_xprt * r_xprt;
115
116 u32 r_prog;
117 u32 r_vers;
118 u32 r_prot;
119 unsigned short r_port;
120 const char * r_netid;
121 const char * r_addr;
122 const char * r_owner;
123
124 int r_status;
125};
126
127static struct rpc_procinfo rpcb_procedures2[];
128static struct rpc_procinfo rpcb_procedures3[];
129static struct rpc_procinfo rpcb_procedures4[];
130
131struct rpcb_info {
132 u32 rpc_vers;
133 struct rpc_procinfo * rpc_proc;
134};
135
136static struct rpcb_info rpcb_next_version[];
137static struct rpcb_info rpcb_next_version6[];
138
139static const struct rpc_call_ops rpcb_getport_ops = {
140 .rpc_call_done = rpcb_getport_done,
141 .rpc_release = rpcb_map_release,
142};
143
144static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
145{
146 xprt_clear_binding(xprt);
147 rpc_wake_up_status(&xprt->binding, status);
148}
149
150static void rpcb_map_release(void *data)
151{
152 struct rpcbind_args *map = data;
153
154 rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
155 xprt_put(map->r_xprt);
156 kfree(map->r_addr);
157 kfree(map);
158}
159
160static const struct sockaddr_in rpcb_inaddr_loopback = {
161 .sin_family = AF_INET,
162 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
163 .sin_port = htons(RPCBIND_PORT),
164};
165
166static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
167 size_t addrlen, u32 version)
168{
169 struct rpc_create_args args = {
170 .protocol = XPRT_TRANSPORT_UDP,
171 .address = addr,
172 .addrsize = addrlen,
173 .servername = "localhost",
174 .program = &rpcb_program,
175 .version = version,
176 .authflavor = RPC_AUTH_UNIX,
177 .flags = RPC_CLNT_CREATE_NOPING,
178 };
179
180 return rpc_create(&args);
181}
182
183static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
184 size_t salen, int proto, u32 version)
185{
186 struct rpc_create_args args = {
187 .protocol = proto,
188 .address = srvaddr,
189 .addrsize = salen,
190 .servername = hostname,
191 .program = &rpcb_program,
192 .version = version,
193 .authflavor = RPC_AUTH_UNIX,
194 .flags = (RPC_CLNT_CREATE_NOPING |
195 RPC_CLNT_CREATE_NONPRIVPORT),
196 };
197
198 switch (srvaddr->sa_family) {
199 case AF_INET:
200 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
201 break;
202 case AF_INET6:
203 ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
204 break;
205 default:
206 return NULL;
207 }
208
209 return rpc_create(&args);
210}
211
212static int rpcb_register_call(const u32 version, struct rpc_message *msg)
213{
214 struct sockaddr *addr = (struct sockaddr *)&rpcb_inaddr_loopback;
215 size_t addrlen = sizeof(rpcb_inaddr_loopback);
216 struct rpc_clnt *rpcb_clnt;
217 int result, error = 0;
218
219 msg->rpc_resp = &result;
220
221 rpcb_clnt = rpcb_create_local(addr, addrlen, version);
222 if (!IS_ERR(rpcb_clnt)) {
223 error = rpc_call_sync(rpcb_clnt, msg, 0);
224 rpc_shutdown_client(rpcb_clnt);
225 } else
226 error = PTR_ERR(rpcb_clnt);
227
228 if (error < 0) {
229 dprintk("RPC: failed to contact local rpcbind "
230 "server (errno %d).\n", -error);
231 return error;
232 }
233
234 if (!result)
235 return -EACCES;
236 return 0;
237}
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
272{
273 struct rpcbind_args map = {
274 .r_prog = prog,
275 .r_vers = vers,
276 .r_prot = prot,
277 .r_port = port,
278 };
279 struct rpc_message msg = {
280 .rpc_argp = &map,
281 };
282
283 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
284 "rpcbind\n", (port ? "" : "un"),
285 prog, vers, prot, port);
286
287 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
288 if (port)
289 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
290
291 return rpcb_register_call(RPCBVERS_2, &msg);
292}
293
294
295
296
297static int rpcb_register_inet4(const struct sockaddr *sap,
298 struct rpc_message *msg)
299{
300 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
301 struct rpcbind_args *map = msg->rpc_argp;
302 unsigned short port = ntohs(sin->sin_port);
303 int result;
304
305 map->r_addr = rpc_sockaddr2uaddr(sap);
306
307 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
308 "local rpcbind\n", (port ? "" : "un"),
309 map->r_prog, map->r_vers,
310 map->r_addr, map->r_netid);
311
312 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
313 if (port)
314 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
315
316 result = rpcb_register_call(RPCBVERS_4, msg);
317 kfree(map->r_addr);
318 return result;
319}
320
321
322
323
324static int rpcb_register_inet6(const struct sockaddr *sap,
325 struct rpc_message *msg)
326{
327 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
328 struct rpcbind_args *map = msg->rpc_argp;
329 unsigned short port = ntohs(sin6->sin6_port);
330 int result;
331
332 map->r_addr = rpc_sockaddr2uaddr(sap);
333
334 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
335 "local rpcbind\n", (port ? "" : "un"),
336 map->r_prog, map->r_vers,
337 map->r_addr, map->r_netid);
338
339 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
340 if (port)
341 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
342
343 result = rpcb_register_call(RPCBVERS_4, msg);
344 kfree(map->r_addr);
345 return result;
346}
347
348static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
349{
350 struct rpcbind_args *map = msg->rpc_argp;
351
352 dprintk("RPC: unregistering [%u, %u, '%s'] with "
353 "local rpcbind\n",
354 map->r_prog, map->r_vers, map->r_netid);
355
356 map->r_addr = "";
357 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
358
359 return rpcb_register_call(RPCBVERS_4, msg);
360}
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405int rpcb_v4_register(const u32 program, const u32 version,
406 const struct sockaddr *address, const char *netid)
407{
408 struct rpcbind_args map = {
409 .r_prog = program,
410 .r_vers = version,
411 .r_netid = netid,
412 .r_owner = RPCB_OWNER_STRING,
413 };
414 struct rpc_message msg = {
415 .rpc_argp = &map,
416 };
417
418 if (address == NULL)
419 return rpcb_unregister_all_protofamilies(&msg);
420
421 switch (address->sa_family) {
422 case AF_INET:
423 return rpcb_register_inet4(address, &msg);
424 case AF_INET6:
425 return rpcb_register_inet6(address, &msg);
426 }
427
428 return -EAFNOSUPPORT;
429}
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
447{
448 struct rpcbind_args map = {
449 .r_prog = prog,
450 .r_vers = vers,
451 .r_prot = prot,
452 .r_port = 0,
453 };
454 struct rpc_message msg = {
455 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
456 .rpc_argp = &map,
457 .rpc_resp = &map,
458 };
459 struct rpc_clnt *rpcb_clnt;
460 int status;
461
462 dprintk("RPC: %s(%pI4, %u, %u, %d)\n",
463 __func__, &sin->sin_addr.s_addr, prog, vers, prot);
464
465 rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
466 sizeof(*sin), prot, RPCBVERS_2);
467 if (IS_ERR(rpcb_clnt))
468 return PTR_ERR(rpcb_clnt);
469
470 status = rpc_call_sync(rpcb_clnt, &msg, 0);
471 rpc_shutdown_client(rpcb_clnt);
472
473 if (status >= 0) {
474 if (map.r_port != 0)
475 return map.r_port;
476 status = -EACCES;
477 }
478 return status;
479}
480EXPORT_SYMBOL_GPL(rpcb_getport_sync);
481
482static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
483{
484 struct rpc_message msg = {
485 .rpc_proc = proc,
486 .rpc_argp = map,
487 .rpc_resp = map,
488 };
489 struct rpc_task_setup task_setup_data = {
490 .rpc_client = rpcb_clnt,
491 .rpc_message = &msg,
492 .callback_ops = &rpcb_getport_ops,
493 .callback_data = map,
494 .flags = RPC_TASK_ASYNC,
495 };
496
497 return rpc_run_task(&task_setup_data);
498}
499
500
501
502
503
504
505
506
507static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
508{
509 struct rpc_clnt *parent = clnt->cl_parent;
510
511 while (parent != clnt) {
512 if (parent->cl_xprt != clnt->cl_xprt)
513 break;
514 if (clnt->cl_autobind)
515 break;
516 clnt = parent;
517 parent = parent->cl_parent;
518 }
519 return clnt;
520}
521
522
523
524
525
526
527
528
529void rpcb_getport_async(struct rpc_task *task)
530{
531 struct rpc_clnt *clnt;
532 struct rpc_procinfo *proc;
533 u32 bind_version;
534 struct rpc_xprt *xprt;
535 struct rpc_clnt *rpcb_clnt;
536 static struct rpcbind_args *map;
537 struct rpc_task *child;
538 struct sockaddr_storage addr;
539 struct sockaddr *sap = (struct sockaddr *)&addr;
540 size_t salen;
541 int status;
542
543 clnt = rpcb_find_transport_owner(task->tk_client);
544 xprt = clnt->cl_xprt;
545
546 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
547 task->tk_pid, __func__,
548 clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
549
550
551
552 rpc_sleep_on(&xprt->binding, task, NULL);
553
554 if (xprt_test_and_set_binding(xprt)) {
555 dprintk("RPC: %5u %s: waiting for another binder\n",
556 task->tk_pid, __func__);
557 return;
558 }
559
560
561 if (xprt_bound(xprt)) {
562 status = 0;
563 dprintk("RPC: %5u %s: already bound\n",
564 task->tk_pid, __func__);
565 goto bailout_nofree;
566 }
567
568
569 salen = rpc_peeraddr(clnt, sap, sizeof(addr));
570
571
572 switch (sap->sa_family) {
573 case AF_INET:
574 proc = rpcb_next_version[xprt->bind_index].rpc_proc;
575 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
576 break;
577 case AF_INET6:
578 proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
579 bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
580 break;
581 default:
582 status = -EAFNOSUPPORT;
583 dprintk("RPC: %5u %s: bad address family\n",
584 task->tk_pid, __func__);
585 goto bailout_nofree;
586 }
587 if (proc == NULL) {
588 xprt->bind_index = 0;
589 status = -EPFNOSUPPORT;
590 dprintk("RPC: %5u %s: no more getport versions available\n",
591 task->tk_pid, __func__);
592 goto bailout_nofree;
593 }
594
595 dprintk("RPC: %5u %s: trying rpcbind version %u\n",
596 task->tk_pid, __func__, bind_version);
597
598 rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
599 bind_version);
600 if (IS_ERR(rpcb_clnt)) {
601 status = PTR_ERR(rpcb_clnt);
602 dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
603 task->tk_pid, __func__, PTR_ERR(rpcb_clnt));
604 goto bailout_nofree;
605 }
606
607 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
608 if (!map) {
609 status = -ENOMEM;
610 dprintk("RPC: %5u %s: no memory available\n",
611 task->tk_pid, __func__);
612 goto bailout_release_client;
613 }
614 map->r_prog = clnt->cl_prog;
615 map->r_vers = clnt->cl_vers;
616 map->r_prot = xprt->prot;
617 map->r_port = 0;
618 map->r_xprt = xprt_get(xprt);
619 map->r_status = -EIO;
620
621 switch (bind_version) {
622 case RPCBVERS_4:
623 case RPCBVERS_3:
624 map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
625 map->r_addr = rpc_sockaddr2uaddr(sap);
626 map->r_owner = "";
627 break;
628 case RPCBVERS_2:
629 map->r_addr = NULL;
630 break;
631 default:
632 BUG();
633 }
634
635 child = rpcb_call_async(rpcb_clnt, map, proc);
636 rpc_release_client(rpcb_clnt);
637 if (IS_ERR(child)) {
638
639 dprintk("RPC: %5u %s: rpc_run_task failed\n",
640 task->tk_pid, __func__);
641 return;
642 }
643
644 xprt->stat.bind_count++;
645 rpc_put_task(child);
646 return;
647
648bailout_release_client:
649 rpc_release_client(rpcb_clnt);
650bailout_nofree:
651 rpcb_wake_rpcbind_waiters(xprt, status);
652 task->tk_status = status;
653}
654EXPORT_SYMBOL_GPL(rpcb_getport_async);
655
656
657
658
659static void rpcb_getport_done(struct rpc_task *child, void *data)
660{
661 struct rpcbind_args *map = data;
662 struct rpc_xprt *xprt = map->r_xprt;
663 int status = child->tk_status;
664
665
666 if (status == -EIO)
667 status = -EPROTONOSUPPORT;
668
669
670 if (status == -EPROTONOSUPPORT)
671 xprt->bind_index++;
672
673 if (status < 0) {
674
675 xprt->ops->set_port(xprt, 0);
676 } else if (map->r_port == 0) {
677
678 xprt->ops->set_port(xprt, 0);
679 status = -EACCES;
680 } else {
681
682 xprt->ops->set_port(xprt, map->r_port);
683 xprt_set_bound(xprt);
684 status = 0;
685 }
686
687 dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
688 child->tk_pid, status, map->r_port);
689
690 map->r_status = status;
691}
692
693
694
695
696
697static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p,
698 const struct rpcbind_args *rpcb)
699{
700 struct rpc_task *task = req->rq_task;
701 struct xdr_stream xdr;
702
703 dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n",
704 task->tk_pid, task->tk_msg.rpc_proc->p_name,
705 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
706
707 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
708
709 p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz);
710 if (unlikely(p == NULL))
711 return -EIO;
712
713 *p++ = htonl(rpcb->r_prog);
714 *p++ = htonl(rpcb->r_vers);
715 *p++ = htonl(rpcb->r_prot);
716 *p = htonl(rpcb->r_port);
717
718 return 0;
719}
720
721static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p,
722 struct rpcbind_args *rpcb)
723{
724 struct rpc_task *task = req->rq_task;
725 struct xdr_stream xdr;
726 unsigned long port;
727
728 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
729
730 rpcb->r_port = 0;
731
732 p = xdr_inline_decode(&xdr, sizeof(__be32));
733 if (unlikely(p == NULL))
734 return -EIO;
735
736 port = ntohl(*p);
737 dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid,
738 task->tk_msg.rpc_proc->p_name, port);
739 if (unlikely(port > USHORT_MAX))
740 return -EIO;
741
742 rpcb->r_port = port;
743 return 0;
744}
745
746static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p,
747 unsigned int *boolp)
748{
749 struct rpc_task *task = req->rq_task;
750 struct xdr_stream xdr;
751
752 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
753
754 p = xdr_inline_decode(&xdr, sizeof(__be32));
755 if (unlikely(p == NULL))
756 return -EIO;
757
758 *boolp = 0;
759 if (*p)
760 *boolp = 1;
761
762 dprintk("RPC: %5u RPCB_%s call %s\n",
763 task->tk_pid, task->tk_msg.rpc_proc->p_name,
764 (*boolp ? "succeeded" : "failed"));
765 return 0;
766}
767
768static int encode_rpcb_string(struct xdr_stream *xdr, const char *string,
769 const u32 maxstrlen)
770{
771 u32 len;
772 __be32 *p;
773
774 if (unlikely(string == NULL))
775 return -EIO;
776 len = strlen(string);
777 if (unlikely(len > maxstrlen))
778 return -EIO;
779
780 p = xdr_reserve_space(xdr, sizeof(__be32) + len);
781 if (unlikely(p == NULL))
782 return -EIO;
783 xdr_encode_opaque(p, string, len);
784
785 return 0;
786}
787
788static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p,
789 const struct rpcbind_args *rpcb)
790{
791 struct rpc_task *task = req->rq_task;
792 struct xdr_stream xdr;
793
794 dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n",
795 task->tk_pid, task->tk_msg.rpc_proc->p_name,
796 rpcb->r_prog, rpcb->r_vers,
797 rpcb->r_netid, rpcb->r_addr);
798
799 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
800
801 p = xdr_reserve_space(&xdr,
802 sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz));
803 if (unlikely(p == NULL))
804 return -EIO;
805 *p++ = htonl(rpcb->r_prog);
806 *p = htonl(rpcb->r_vers);
807
808 if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN))
809 return -EIO;
810 if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN))
811 return -EIO;
812 if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN))
813 return -EIO;
814
815 return 0;
816}
817
818static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p,
819 struct rpcbind_args *rpcb)
820{
821 struct sockaddr_storage address;
822 struct sockaddr *sap = (struct sockaddr *)&address;
823 struct rpc_task *task = req->rq_task;
824 struct xdr_stream xdr;
825 u32 len;
826
827 rpcb->r_port = 0;
828
829 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
830
831 p = xdr_inline_decode(&xdr, sizeof(__be32));
832 if (unlikely(p == NULL))
833 goto out_fail;
834 len = ntohl(*p);
835
836
837
838
839
840 if (len == 0) {
841 dprintk("RPC: %5u RPCB reply: program not registered\n",
842 task->tk_pid);
843 return 0;
844 }
845
846 if (unlikely(len > RPCBIND_MAXUADDRLEN))
847 goto out_fail;
848
849 p = xdr_inline_decode(&xdr, len);
850 if (unlikely(p == NULL))
851 goto out_fail;
852 dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid,
853 task->tk_msg.rpc_proc->p_name, (char *)p);
854
855 if (rpc_uaddr2sockaddr((char *)p, len, sap, sizeof(address)) == 0)
856 goto out_fail;
857 rpcb->r_port = rpc_get_port(sap);
858
859 return 0;
860
861out_fail:
862 dprintk("RPC: %5u malformed RPCB_%s reply\n",
863 task->tk_pid, task->tk_msg.rpc_proc->p_name);
864 return -EIO;
865}
866
867
868
869
870
871
872static struct rpc_procinfo rpcb_procedures2[] = {
873 [RPCBPROC_SET] = {
874 .p_proc = RPCBPROC_SET,
875 .p_encode = (kxdrproc_t)rpcb_enc_mapping,
876 .p_decode = (kxdrproc_t)rpcb_dec_set,
877 .p_arglen = RPCB_mappingargs_sz,
878 .p_replen = RPCB_setres_sz,
879 .p_statidx = RPCBPROC_SET,
880 .p_timer = 0,
881 .p_name = "SET",
882 },
883 [RPCBPROC_UNSET] = {
884 .p_proc = RPCBPROC_UNSET,
885 .p_encode = (kxdrproc_t)rpcb_enc_mapping,
886 .p_decode = (kxdrproc_t)rpcb_dec_set,
887 .p_arglen = RPCB_mappingargs_sz,
888 .p_replen = RPCB_setres_sz,
889 .p_statidx = RPCBPROC_UNSET,
890 .p_timer = 0,
891 .p_name = "UNSET",
892 },
893 [RPCBPROC_GETPORT] = {
894 .p_proc = RPCBPROC_GETPORT,
895 .p_encode = (kxdrproc_t)rpcb_enc_mapping,
896 .p_decode = (kxdrproc_t)rpcb_dec_getport,
897 .p_arglen = RPCB_mappingargs_sz,
898 .p_replen = RPCB_getportres_sz,
899 .p_statidx = RPCBPROC_GETPORT,
900 .p_timer = 0,
901 .p_name = "GETPORT",
902 },
903};
904
905static struct rpc_procinfo rpcb_procedures3[] = {
906 [RPCBPROC_SET] = {
907 .p_proc = RPCBPROC_SET,
908 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
909 .p_decode = (kxdrproc_t)rpcb_dec_set,
910 .p_arglen = RPCB_getaddrargs_sz,
911 .p_replen = RPCB_setres_sz,
912 .p_statidx = RPCBPROC_SET,
913 .p_timer = 0,
914 .p_name = "SET",
915 },
916 [RPCBPROC_UNSET] = {
917 .p_proc = RPCBPROC_UNSET,
918 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
919 .p_decode = (kxdrproc_t)rpcb_dec_set,
920 .p_arglen = RPCB_getaddrargs_sz,
921 .p_replen = RPCB_setres_sz,
922 .p_statidx = RPCBPROC_UNSET,
923 .p_timer = 0,
924 .p_name = "UNSET",
925 },
926 [RPCBPROC_GETADDR] = {
927 .p_proc = RPCBPROC_GETADDR,
928 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
929 .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
930 .p_arglen = RPCB_getaddrargs_sz,
931 .p_replen = RPCB_getaddrres_sz,
932 .p_statidx = RPCBPROC_GETADDR,
933 .p_timer = 0,
934 .p_name = "GETADDR",
935 },
936};
937
938static struct rpc_procinfo rpcb_procedures4[] = {
939 [RPCBPROC_SET] = {
940 .p_proc = RPCBPROC_SET,
941 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
942 .p_decode = (kxdrproc_t)rpcb_dec_set,
943 .p_arglen = RPCB_getaddrargs_sz,
944 .p_replen = RPCB_setres_sz,
945 .p_statidx = RPCBPROC_SET,
946 .p_timer = 0,
947 .p_name = "SET",
948 },
949 [RPCBPROC_UNSET] = {
950 .p_proc = RPCBPROC_UNSET,
951 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
952 .p_decode = (kxdrproc_t)rpcb_dec_set,
953 .p_arglen = RPCB_getaddrargs_sz,
954 .p_replen = RPCB_setres_sz,
955 .p_statidx = RPCBPROC_UNSET,
956 .p_timer = 0,
957 .p_name = "UNSET",
958 },
959 [RPCBPROC_GETADDR] = {
960 .p_proc = RPCBPROC_GETADDR,
961 .p_encode = (kxdrproc_t)rpcb_enc_getaddr,
962 .p_decode = (kxdrproc_t)rpcb_dec_getaddr,
963 .p_arglen = RPCB_getaddrargs_sz,
964 .p_replen = RPCB_getaddrres_sz,
965 .p_statidx = RPCBPROC_GETADDR,
966 .p_timer = 0,
967 .p_name = "GETADDR",
968 },
969};
970
971static struct rpcb_info rpcb_next_version[] = {
972 {
973 .rpc_vers = RPCBVERS_2,
974 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
975 },
976 {
977 .rpc_proc = NULL,
978 },
979};
980
981static struct rpcb_info rpcb_next_version6[] = {
982 {
983 .rpc_vers = RPCBVERS_4,
984 .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR],
985 },
986 {
987 .rpc_vers = RPCBVERS_3,
988 .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
989 },
990 {
991 .rpc_proc = NULL,
992 },
993};
994
995static struct rpc_version rpcb_version2 = {
996 .number = RPCBVERS_2,
997 .nrprocs = RPCB_HIGHPROC_2,
998 .procs = rpcb_procedures2
999};
1000
1001static struct rpc_version rpcb_version3 = {
1002 .number = RPCBVERS_3,
1003 .nrprocs = RPCB_HIGHPROC_3,
1004 .procs = rpcb_procedures3
1005};
1006
1007static struct rpc_version rpcb_version4 = {
1008 .number = RPCBVERS_4,
1009 .nrprocs = RPCB_HIGHPROC_4,
1010 .procs = rpcb_procedures4
1011};
1012
1013static struct rpc_version *rpcb_version[] = {
1014 NULL,
1015 NULL,
1016 &rpcb_version2,
1017 &rpcb_version3,
1018 &rpcb_version4
1019};
1020
1021static struct rpc_stat rpcb_stats;
1022
1023static struct rpc_program rpcb_program = {
1024 .name = "rpcbind",
1025 .number = RPCBIND_PROGRAM,
1026 .nrvers = ARRAY_SIZE(rpcb_version),
1027 .version = rpcb_version,
1028 .stats = &rpcb_stats,
1029};
1030