1/*	$NetBSD: pmap_rmt.c,v 1.30 2010/03/23 20:28:59 drochner Exp $	*/
2
3/*
4 * Copyright (c) 2010, Oracle America, Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *     * Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above
13 *       copyright notice, this list of conditions and the following
14 *       disclaimer in the documentation and/or other materials
15 *       provided with the distribution.
16 *     * Neither the name of the "Oracle America, Inc." nor the names of its
17 *       contributors may be used to endorse or promote products derived
18 *       from this software without specific prior written permission.
19 *
20 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/cdefs.h>
35#if defined(LIBC_SCCS) && !defined(lint)
36#if 0
37static char *sccsid = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";
38static char *sccsid = "@(#)pmap_rmt.c	2.2 88/08/01 4.0 RPCSRC";
39#else
40__RCSID("$NetBSD: pmap_rmt.c,v 1.30 2010/03/23 20:28:59 drochner Exp $");
41#endif
42#endif
43
44/*
45 * pmap_rmt.c
46 * Client interface to pmap rpc service.
47 * remote call and broadcast service
48 *
49 * Copyright (C) 1984, Sun Microsystems, Inc.
50 */
51
52#include "namespace.h"
53
54#include <sys/types.h>
55#include <sys/ioctl.h>
56#include <sys/poll.h>
57#include <sys/socket.h>
58
59#include <net/if.h>
60#include <netinet/in.h>
61#include <arpa/inet.h>
62
63#include <assert.h>
64#include <err.h>
65#include <errno.h>
66#include <stdio.h>
67#include <string.h>
68#include <unistd.h>
69
70#include <rpc/rpc.h>
71#include <rpc/pmap_prot.h>
72#include <rpc/pmap_clnt.h>
73#include <rpc/pmap_rmt.h>
74
75#ifdef __weak_alias
76__weak_alias(xdr_rmtcall_args,_xdr_rmtcall_args)
77__weak_alias(xdr_rmtcallres,_xdr_rmtcallres)
78#endif
79
80static const struct timeval timeout = { 3, 0 };
81
82/*
83 * pmapper remote-call-service interface.
84 * This routine is used to call the pmapper remote call service
85 * which will look up a service program in the port maps, and then
86 * remotely call that routine with the given parameters.  This allows
87 * programs to do a lookup and call in one step.
88*/
89enum clnt_stat
90pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout,
91    port_ptr)
92	struct sockaddr_in *addr;
93	u_long prog, vers, proc;
94	xdrproc_t xdrargs, xdrres;
95	caddr_t argsp, resp;
96	struct timeval tout;
97	u_long *port_ptr;
98{
99	int sock = -1;
100	CLIENT *client;
101	struct rmtcallargs a;
102	struct rmtcallres r;
103	enum clnt_stat stat;
104
105	_DIAGASSERT(addr != NULL);
106	_DIAGASSERT(port_ptr != NULL);
107
108	addr->sin_port = htons(PMAPPORT);
109	client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock);
110	if (client != NULL) {
111		a.prog = prog;
112		a.vers = vers;
113		a.proc = proc;
114		a.args_ptr = argsp;
115		a.xdr_args = xdrargs;
116		r.port_ptr = port_ptr;
117		r.results_ptr = resp;
118		r.xdr_results = xdrres;
119		stat = CLNT_CALL(client, (rpcproc_t)PMAPPROC_CALLIT,
120		    (xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres,
121		    &r, tout);
122		CLNT_DESTROY(client);
123	} else {
124		stat = RPC_FAILED;
125	}
126	addr->sin_port = 0;
127	return (stat);
128}
129
130
131/*
132 * XDR remote call arguments
133 * written for XDR_ENCODE direction only
134 */
135bool_t
136xdr_rmtcall_args(xdrs, cap)
137	XDR *xdrs;
138	struct rmtcallargs *cap;
139{
140	u_int lenposition, argposition, position;
141
142	_DIAGASSERT(xdrs != NULL);
143	_DIAGASSERT(cap != NULL);
144
145	if (xdr_u_long(xdrs, &(cap->prog)) &&
146	    xdr_u_long(xdrs, &(cap->vers)) &&
147	    xdr_u_long(xdrs, &(cap->proc))) {
148		lenposition = XDR_GETPOS(xdrs);
149		if (! xdr_u_long(xdrs, &(cap->arglen)))
150		    return (FALSE);
151		argposition = XDR_GETPOS(xdrs);
152		if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
153		    return (FALSE);
154		position = XDR_GETPOS(xdrs);
155		cap->arglen = (u_long)position - (u_long)argposition;
156		XDR_SETPOS(xdrs, lenposition);
157		if (! xdr_u_long(xdrs, &(cap->arglen)))
158		    return (FALSE);
159		XDR_SETPOS(xdrs, position);
160		return (TRUE);
161	}
162	return (FALSE);
163}
164
165/*
166 * XDR remote call results
167 * written for XDR_DECODE direction only
168 */
169bool_t
170xdr_rmtcallres(xdrs, crp)
171	XDR *xdrs;
172	struct rmtcallres *crp;
173{
174	caddr_t port_ptr;
175
176	_DIAGASSERT(xdrs != NULL);
177	_DIAGASSERT(crp != NULL);
178
179	port_ptr = (caddr_t)(void *)crp->port_ptr;
180	if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
181	    (xdrproc_t)xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
182		crp->port_ptr = (u_long *)(void *)port_ptr;
183		return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
184	}
185	return (FALSE);
186}
187