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
78static void rpcb_getport_done(struct rpc_task *, void *);
79static void rpcb_map_release(void *data);
80static struct rpc_program rpcb_program;
81
82struct rpcbind_args {
83 struct rpc_xprt * r_xprt;
84
85 u32 r_prog;
86 u32 r_vers;
87 u32 r_prot;
88 unsigned short r_port;
89 const char * r_netid;
90 const char * r_addr;
91 const char * r_owner;
92
93 int r_status;
94};
95
96static struct rpc_procinfo rpcb_procedures2[];
97static struct rpc_procinfo rpcb_procedures3[];
98static struct rpc_procinfo rpcb_procedures4[];
99
100struct rpcb_info {
101 u32 rpc_vers;
102 struct rpc_procinfo * rpc_proc;
103};
104
105static struct rpcb_info rpcb_next_version[];
106static struct rpcb_info rpcb_next_version6[];
107
108static const struct rpc_call_ops rpcb_getport_ops = {
109 .rpc_call_done = rpcb_getport_done,
110 .rpc_release = rpcb_map_release,
111};
112
113static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
114{
115 xprt_clear_binding(xprt);
116 rpc_wake_up_status(&xprt->binding, status);
117}
118
119static void rpcb_map_release(void *data)
120{
121 struct rpcbind_args *map = data;
122
123 rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
124 xprt_put(map->r_xprt);
125 kfree(map);
126}
127
128static const struct sockaddr_in rpcb_inaddr_loopback = {
129 .sin_family = AF_INET,
130 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
131 .sin_port = htons(RPCBIND_PORT),
132};
133
134static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
135 size_t addrlen, u32 version)
136{
137 struct rpc_create_args args = {
138 .protocol = XPRT_TRANSPORT_UDP,
139 .address = addr,
140 .addrsize = addrlen,
141 .servername = "localhost",
142 .program = &rpcb_program,
143 .version = version,
144 .authflavor = RPC_AUTH_UNIX,
145 .flags = RPC_CLNT_CREATE_NOPING,
146 };
147
148 return rpc_create(&args);
149}
150
151static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
152 size_t salen, int proto, u32 version)
153{
154 struct rpc_create_args args = {
155 .protocol = proto,
156 .address = srvaddr,
157 .addrsize = salen,
158 .servername = hostname,
159 .program = &rpcb_program,
160 .version = version,
161 .authflavor = RPC_AUTH_UNIX,
162 .flags = (RPC_CLNT_CREATE_NOPING |
163 RPC_CLNT_CREATE_NONPRIVPORT),
164 };
165
166 switch (srvaddr->sa_family) {
167 case AF_INET:
168 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
169 break;
170 case AF_INET6:
171 ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
172 break;
173 default:
174 return NULL;
175 }
176
177 return rpc_create(&args);
178}
179
180static int rpcb_register_call(const u32 version, struct rpc_message *msg)
181{
182 struct sockaddr *addr = (struct sockaddr *)&rpcb_inaddr_loopback;
183 size_t addrlen = sizeof(rpcb_inaddr_loopback);
184 struct rpc_clnt *rpcb_clnt;
185 int result, error = 0;
186
187 msg->rpc_resp = &result;
188
189 rpcb_clnt = rpcb_create_local(addr, addrlen, version);
190 if (!IS_ERR(rpcb_clnt)) {
191 error = rpc_call_sync(rpcb_clnt, msg, 0);
192 rpc_shutdown_client(rpcb_clnt);
193 } else
194 error = PTR_ERR(rpcb_clnt);
195
196 if (error < 0) {
197 dprintk("RPC: failed to contact local rpcbind "
198 "server (errno %d).\n", -error);
199 return error;
200 }
201
202 if (!result)
203 return -EACCES;
204 return 0;
205}
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
240{
241 struct rpcbind_args map = {
242 .r_prog = prog,
243 .r_vers = vers,
244 .r_prot = prot,
245 .r_port = port,
246 };
247 struct rpc_message msg = {
248 .rpc_argp = &map,
249 };
250
251 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
252 "rpcbind\n", (port ? "" : "un"),
253 prog, vers, prot, port);
254
255 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
256 if (port)
257 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
258
259 return rpcb_register_call(RPCBVERS_2, &msg);
260}
261
262
263
264
265static int rpcb_register_inet4(const struct sockaddr *sap,
266 struct rpc_message *msg)
267{
268 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
269 struct rpcbind_args *map = msg->rpc_argp;
270 unsigned short port = ntohs(sin->sin_port);
271 char buf[32];
272
273
274 snprintf(buf, sizeof(buf), "%pI4.%u.%u",
275 &sin->sin_addr.s_addr, port >> 8, port & 0xff);
276 map->r_addr = buf;
277
278 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
279 "local rpcbind\n", (port ? "" : "un"),
280 map->r_prog, map->r_vers,
281 map->r_addr, map->r_netid);
282
283 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
284 if (port)
285 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
286
287 return rpcb_register_call(RPCBVERS_4, msg);
288}
289
290
291
292
293static int rpcb_register_inet6(const struct sockaddr *sap,
294 struct rpc_message *msg)
295{
296 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
297 struct rpcbind_args *map = msg->rpc_argp;
298 unsigned short port = ntohs(sin6->sin6_port);
299 char buf[64];
300
301
302 if (ipv6_addr_any(&sin6->sin6_addr))
303 snprintf(buf, sizeof(buf), "::.%u.%u",
304 port >> 8, port & 0xff);
305 else
306 snprintf(buf, sizeof(buf), "%pI6.%u.%u",
307 &sin6->sin6_addr, port >> 8, port & 0xff);
308 map->r_addr = buf;
309
310 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
311 "local rpcbind\n", (port ? "" : "un"),
312 map->r_prog, map->r_vers,
313 map->r_addr, map->r_netid);
314
315 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
316 if (port)
317 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
318
319 return rpcb_register_call(RPCBVERS_4, msg);
320}
321
322static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
323{
324 struct rpcbind_args *map = msg->rpc_argp;
325
326 dprintk("RPC: unregistering [%u, %u, '%s'] with "
327 "local rpcbind\n",
328 map->r_prog, map->r_vers, map->r_netid);
329
330 map->r_addr = "";
331 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
332
333 return rpcb_register_call(RPCBVERS_4, msg);
334}
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379int rpcb_v4_register(const u32 program, const u32 version,
380 const struct sockaddr *address, const char *netid)
381{
382 struct rpcbind_args map = {
383 .r_prog = program,
384 .r_vers = version,
385 .r_netid = netid,
386 .r_owner = RPCB_OWNER_STRING,
387 };
388 struct rpc_message msg = {
389 .rpc_argp = &map,
390 };
391
392 if (address == NULL)
393 return rpcb_unregister_all_protofamilies(&msg);
394
395 switch (address->sa_family) {
396 case AF_INET:
397 return rpcb_register_inet4(address, &msg);
398 case AF_INET6:
399 return rpcb_register_inet6(address, &msg);
400 }
401
402 return -EAFNOSUPPORT;
403}
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
421{
422 struct rpcbind_args map = {
423 .r_prog = prog,
424 .r_vers = vers,
425 .r_prot = prot,
426 .r_port = 0,
427 };
428 struct rpc_message msg = {
429 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
430 .rpc_argp = &map,
431 .rpc_resp = &map.r_port,
432 };
433 struct rpc_clnt *rpcb_clnt;
434 int status;
435
436 dprintk("RPC: %s(%pI4, %u, %u, %d)\n",
437 __func__, &sin->sin_addr.s_addr, prog, vers, prot);
438
439 rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
440 sizeof(*sin), prot, RPCBVERS_2);
441 if (IS_ERR(rpcb_clnt))
442 return PTR_ERR(rpcb_clnt);
443
444 status = rpc_call_sync(rpcb_clnt, &msg, 0);
445 rpc_shutdown_client(rpcb_clnt);
446
447 if (status >= 0) {
448 if (map.r_port != 0)
449 return map.r_port;
450 status = -EACCES;
451 }
452 return status;
453}
454EXPORT_SYMBOL_GPL(rpcb_getport_sync);
455
456static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
457{
458 struct rpc_message msg = {
459 .rpc_proc = proc,
460 .rpc_argp = map,
461 .rpc_resp = &map->r_port,
462 };
463 struct rpc_task_setup task_setup_data = {
464 .rpc_client = rpcb_clnt,
465 .rpc_message = &msg,
466 .callback_ops = &rpcb_getport_ops,
467 .callback_data = map,
468 .flags = RPC_TASK_ASYNC,
469 };
470
471 return rpc_run_task(&task_setup_data);
472}
473
474
475
476
477
478
479
480
481static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
482{
483 struct rpc_clnt *parent = clnt->cl_parent;
484
485 while (parent != clnt) {
486 if (parent->cl_xprt != clnt->cl_xprt)
487 break;
488 if (clnt->cl_autobind)
489 break;
490 clnt = parent;
491 parent = parent->cl_parent;
492 }
493 return clnt;
494}
495
496
497
498
499
500
501
502
503void rpcb_getport_async(struct rpc_task *task)
504{
505 struct rpc_clnt *clnt;
506 struct rpc_procinfo *proc;
507 u32 bind_version;
508 struct rpc_xprt *xprt;
509 struct rpc_clnt *rpcb_clnt;
510 static struct rpcbind_args *map;
511 struct rpc_task *child;
512 struct sockaddr_storage addr;
513 struct sockaddr *sap = (struct sockaddr *)&addr;
514 size_t salen;
515 int status;
516
517 clnt = rpcb_find_transport_owner(task->tk_client);
518 xprt = clnt->cl_xprt;
519
520 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
521 task->tk_pid, __func__,
522 clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
523
524
525
526 rpc_sleep_on(&xprt->binding, task, NULL);
527
528 if (xprt_test_and_set_binding(xprt)) {
529 dprintk("RPC: %5u %s: waiting for another binder\n",
530 task->tk_pid, __func__);
531 return;
532 }
533
534
535 if (xprt_bound(xprt)) {
536 status = 0;
537 dprintk("RPC: %5u %s: already bound\n",
538 task->tk_pid, __func__);
539 goto bailout_nofree;
540 }
541
542 salen = rpc_peeraddr(clnt, sap, sizeof(addr));
543
544
545 switch (sap->sa_family) {
546 case AF_INET:
547 proc = rpcb_next_version[xprt->bind_index].rpc_proc;
548 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
549 break;
550 case AF_INET6:
551 proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
552 bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
553 break;
554 default:
555 status = -EAFNOSUPPORT;
556 dprintk("RPC: %5u %s: bad address family\n",
557 task->tk_pid, __func__);
558 goto bailout_nofree;
559 }
560 if (proc == NULL) {
561 xprt->bind_index = 0;
562 status = -EPFNOSUPPORT;
563 dprintk("RPC: %5u %s: no more getport versions available\n",
564 task->tk_pid, __func__);
565 goto bailout_nofree;
566 }
567
568 dprintk("RPC: %5u %s: trying rpcbind version %u\n",
569 task->tk_pid, __func__, bind_version);
570
571 rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
572 bind_version);
573 if (IS_ERR(rpcb_clnt)) {
574 status = PTR_ERR(rpcb_clnt);
575 dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
576 task->tk_pid, __func__, PTR_ERR(rpcb_clnt));
577 goto bailout_nofree;
578 }
579
580 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
581 if (!map) {
582 status = -ENOMEM;
583 dprintk("RPC: %5u %s: no memory available\n",
584 task->tk_pid, __func__);
585 goto bailout_release_client;
586 }
587 map->r_prog = clnt->cl_prog;
588 map->r_vers = clnt->cl_vers;
589 map->r_prot = xprt->prot;
590 map->r_port = 0;
591 map->r_xprt = xprt_get(xprt);
592 map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
593 map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
594 map->r_owner = "";
595 map->r_status = -EIO;
596
597 child = rpcb_call_async(rpcb_clnt, map, proc);
598 rpc_release_client(rpcb_clnt);
599 if (IS_ERR(child)) {
600
601 dprintk("RPC: %5u %s: rpc_run_task failed\n",
602 task->tk_pid, __func__);
603 return;
604 }
605
606 xprt->stat.bind_count++;
607 rpc_put_task(child);
608 return;
609
610bailout_release_client:
611 rpc_release_client(rpcb_clnt);
612bailout_nofree:
613 rpcb_wake_rpcbind_waiters(xprt, status);
614 task->tk_status = status;
615}
616EXPORT_SYMBOL_GPL(rpcb_getport_async);
617
618
619
620
621static void rpcb_getport_done(struct rpc_task *child, void *data)
622{
623 struct rpcbind_args *map = data;
624 struct rpc_xprt *xprt = map->r_xprt;
625 int status = child->tk_status;
626
627
628 if (status == -EIO)
629 status = -EPROTONOSUPPORT;
630
631
632 if (status == -EPROTONOSUPPORT)
633 xprt->bind_index++;
634
635 if (status < 0) {
636
637 xprt->ops->set_port(xprt, 0);
638 } else if (map->r_port == 0) {
639
640 xprt->ops->set_port(xprt, 0);
641 status = -EACCES;
642 } else {
643
644 xprt->ops->set_port(xprt, map->r_port);
645 xprt_set_bound(xprt);
646 status = 0;
647 }
648
649 dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
650 child->tk_pid, status, map->r_port);
651
652 map->r_status = status;
653}
654
655
656
657
658
659static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p,
660 struct rpcbind_args *rpcb)
661{
662 dprintk("RPC: encoding rpcb request (%u, %u, %d, %u)\n",
663 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
664 *p++ = htonl(rpcb->r_prog);
665 *p++ = htonl(rpcb->r_vers);
666 *p++ = htonl(rpcb->r_prot);
667 *p++ = htonl(rpcb->r_port);
668
669 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
670 return 0;
671}
672
673static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p,
674 unsigned short *portp)
675{
676 *portp = (unsigned short) ntohl(*p++);
677 dprintk("RPC: rpcb getport result: %u\n",
678 *portp);
679 return 0;
680}
681
682static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
683 unsigned int *boolp)
684{
685 *boolp = (unsigned int) ntohl(*p++);
686 dprintk("RPC: rpcb set/unset call %s\n",
687 (*boolp ? "succeeded" : "failed"));
688 return 0;
689}
690
691static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p,
692 struct rpcbind_args *rpcb)
693{
694 dprintk("RPC: encoding rpcb request (%u, %u, %s)\n",
695 rpcb->r_prog, rpcb->r_vers, rpcb->r_addr);
696 *p++ = htonl(rpcb->r_prog);
697 *p++ = htonl(rpcb->r_vers);
698
699 p = xdr_encode_string(p, rpcb->r_netid);
700 p = xdr_encode_string(p, rpcb->r_addr);
701 p = xdr_encode_string(p, rpcb->r_owner);
702
703 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
704
705 return 0;
706}
707
708static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
709 unsigned short *portp)
710{
711 char *addr;
712 u32 addr_len;
713 int c, i, f, first, val;
714
715 *portp = 0;
716 addr_len = ntohl(*p++);
717
718 if (addr_len == 0) {
719 dprintk("RPC: rpcb_decode_getaddr: "
720 "service is not registered\n");
721 return 0;
722 }
723
724
725
726
727 if (addr_len > RPCBIND_MAXUADDRLEN)
728 goto out_err;
729
730
731
732
733
734
735 addr = (char *)p;
736 val = 0;
737 first = 1;
738 f = 1;
739 for (i = addr_len - 1; i > 0; i--) {
740 c = addr[i];
741 if (c >= '0' && c <= '9') {
742 val += (c - '0') * f;
743 f *= 10;
744 } else if (c == '.') {
745 if (first) {
746 *portp = val;
747 val = first = 0;
748 f = 1;
749 } else {
750 *portp |= (val << 8);
751 break;
752 }
753 }
754 }
755
756
757
758
759
760 if (first)
761 goto out_err;
762
763 dprintk("RPC: rpcb_decode_getaddr port=%u\n", *portp);
764 return 0;
765
766out_err:
767 dprintk("RPC: rpcbind server returned malformed reply\n");
768 return -EIO;
769}
770
771#define RPCB_program_sz (1u)
772#define RPCB_version_sz (1u)
773#define RPCB_protocol_sz (1u)
774#define RPCB_port_sz (1u)
775#define RPCB_boolean_sz (1u)
776
777#define RPCB_netid_sz (1+XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
778#define RPCB_addr_sz (1+XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
779#define RPCB_ownerstring_sz (1+XDR_QUADLEN(RPCB_MAXOWNERLEN))
780
781#define RPCB_mappingargs_sz RPCB_program_sz+RPCB_version_sz+ \
782 RPCB_protocol_sz+RPCB_port_sz
783#define RPCB_getaddrargs_sz RPCB_program_sz+RPCB_version_sz+ \
784 RPCB_netid_sz+RPCB_addr_sz+ \
785 RPCB_ownerstring_sz
786
787#define RPCB_setres_sz RPCB_boolean_sz
788#define RPCB_getportres_sz RPCB_port_sz
789
790
791
792
793
794#define RPCB_getaddrres_sz RPCB_addr_sz
795
796#define PROC(proc, argtype, restype) \
797 [RPCBPROC_##proc] = { \
798 .p_proc = RPCBPROC_##proc, \
799 .p_encode = (kxdrproc_t) rpcb_encode_##argtype, \
800 .p_decode = (kxdrproc_t) rpcb_decode_##restype, \
801 .p_arglen = RPCB_##argtype##args_sz, \
802 .p_replen = RPCB_##restype##res_sz, \
803 .p_statidx = RPCBPROC_##proc, \
804 .p_timer = 0, \
805 .p_name = #proc, \
806 }
807
808
809
810
811
812static struct rpc_procinfo rpcb_procedures2[] = {
813 PROC(SET, mapping, set),
814 PROC(UNSET, mapping, set),
815 PROC(GETPORT, mapping, getport),
816};
817
818static struct rpc_procinfo rpcb_procedures3[] = {
819 PROC(SET, getaddr, set),
820 PROC(UNSET, getaddr, set),
821 PROC(GETADDR, getaddr, getaddr),
822};
823
824static struct rpc_procinfo rpcb_procedures4[] = {
825 PROC(SET, getaddr, set),
826 PROC(UNSET, getaddr, set),
827 PROC(GETADDR, getaddr, getaddr),
828 PROC(GETVERSADDR, getaddr, getaddr),
829};
830
831static struct rpcb_info rpcb_next_version[] = {
832 {
833 .rpc_vers = RPCBVERS_2,
834 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
835 },
836 {
837 .rpc_proc = NULL,
838 },
839};
840
841static struct rpcb_info rpcb_next_version6[] = {
842 {
843 .rpc_vers = RPCBVERS_4,
844 .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR],
845 },
846 {
847 .rpc_vers = RPCBVERS_3,
848 .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
849 },
850 {
851 .rpc_proc = NULL,
852 },
853};
854
855static struct rpc_version rpcb_version2 = {
856 .number = RPCBVERS_2,
857 .nrprocs = RPCB_HIGHPROC_2,
858 .procs = rpcb_procedures2
859};
860
861static struct rpc_version rpcb_version3 = {
862 .number = RPCBVERS_3,
863 .nrprocs = RPCB_HIGHPROC_3,
864 .procs = rpcb_procedures3
865};
866
867static struct rpc_version rpcb_version4 = {
868 .number = RPCBVERS_4,
869 .nrprocs = RPCB_HIGHPROC_4,
870 .procs = rpcb_procedures4
871};
872
873static struct rpc_version *rpcb_version[] = {
874 NULL,
875 NULL,
876 &rpcb_version2,
877 &rpcb_version3,
878 &rpcb_version4
879};
880
881static struct rpc_stat rpcb_stats;
882
883static struct rpc_program rpcb_program = {
884 .name = "rpcbind",
885 .number = RPCBIND_PROGRAM,
886 .nrvers = ARRAY_SIZE(rpcb_version),
887 .version = rpcb_version,
888 .stats = &rpcb_stats,
889};
890