4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
29 * Portions of this source code were derived from Berkeley
30 * 4.3 BSD under license from the Regents of the University of
35 * interface to pmap rpc service.
40 #include <rpc/clnt_soc.h>
41 #include <rpc/nettype.h>
43 #include <rpc/pmap_prot.h>
44 #include <rpc/pmap_clnt.h>
45 #include <rpc/pmap_rmt.h>
48 #include <netinet/in.h>
49 #include <sys/socket.h>
52 int use_portmapper
= 0;
53 static const struct timeval timeout
= { 5, 0 };
54 static const struct timeval tottimeout
= { 60, 0 };
55 static const struct timeval rmttimeout
= { 3, 0 };
58 * Set a mapping between program, version and port.
59 * Calls the pmap service remotely to do the mapping.
62 pmap_set(rpcprog_t program
, rpcvers_t version
, rpcprot_t protocol
,
67 struct netconfig
*nconf
;
70 if ((protocol
!= IPPROTO_UDP
) && (protocol
!= IPPROTO_TCP
))
72 nconf
= __rpc_getconfip(protocol
== IPPROTO_UDP
? "udp" : "tcp");
75 (void) sprintf(buf
, "0.0.0.0.%d.%d", port
>> 8 & 0xff, port
& 0xff);
76 na
= uaddr2taddr(nconf
, buf
);
78 freenetconfigent(nconf
);
81 rslt
= rpcb_set(program
, version
, nconf
, na
);
83 netdir_free((char *)na
, ND_ADDR
);
84 freenetconfigent(nconf
);
89 * Remove the mapping between program, version and port.
90 * Calls the pmap service remotely to do the un-mapping.
93 pmap_unset(rpcprog_t program
, rpcvers_t version
)
95 struct netconfig
*nconf
;
96 bool_t udp_rslt
= FALSE
;
97 bool_t tcp_rslt
= FALSE
;
99 nconf
= __rpc_getconfip("udp");
101 udp_rslt
= rpcb_unset(program
, version
, nconf
);
102 freenetconfigent(nconf
);
104 nconf
= __rpc_getconfip("tcp");
106 tcp_rslt
= rpcb_unset(program
, version
, nconf
);
107 freenetconfigent(nconf
);
110 * XXX: The call may still succeed even if only one of the
111 * calls succeeded. This was the best that could be
112 * done for backward compatibility.
114 return (tcp_rslt
|| udp_rslt
);
118 * Find the mapped port for program, version.
119 * Calls the pmap service remotely to do the lookup.
120 * Returns 0 if no map exists.
122 * XXX: It talks only to the portmapper and not to the rpcbind
123 * service. There may be implementations out there which do not
124 * run portmapper as a part of rpcbind.
127 pmap_getport(struct sockaddr_in
*address
, rpcprog_t program
,
128 rpcvers_t version
, rpcprot_t protocol
)
135 address
->sin_port
= htons(PMAPPORT
);
136 client
= clntudp_bufcreate(address
, PMAPPROG
, PMAPVERS
, timeout
,
137 &fd
, RPCSMALLMSGSIZE
, RPCSMALLMSGSIZE
);
138 if (client
!= NULL
) {
139 parms
.pm_prog
= program
;
140 parms
.pm_vers
= version
;
141 parms
.pm_prot
= protocol
;
142 parms
.pm_port
= 0; /* not needed or used */
143 if (CLNT_CALL(client
, PMAPPROC_GETPORT
, (xdrproc_t
)xdr_pmap
,
144 (caddr_t
)&parms
, (xdrproc_t
)xdr_u_short
,
145 (caddr_t
)&port
, tottimeout
) != RPC_SUCCESS
) {
146 rpc_createerr
.cf_stat
= RPC_PMAPFAILURE
;
147 clnt_geterr(client
, &rpc_createerr
.cf_error
);
148 } else if (port
== 0) {
149 rpc_createerr
.cf_stat
= RPC_PROGNOTREGISTERED
;
151 CLNT_DESTROY(client
);
153 address
->sin_port
= 0;
158 * Get a copy of the current port maps.
159 * Calls the pmap service remotely to do get the maps.
162 pmap_getmaps(struct sockaddr_in
*address
)
164 pmaplist_ptr head
= NULL
;
166 struct timeval minutetimeout
;
169 minutetimeout
.tv_sec
= 60;
170 minutetimeout
.tv_usec
= 0;
171 address
->sin_port
= htons(PMAPPORT
);
172 client
= clnttcp_create(address
, PMAPPROG
, PMAPVERS
, &fd
, 50, 500);
173 if (client
!= NULL
) {
174 if (CLNT_CALL(client
, PMAPPROC_DUMP
, (xdrproc_t
)xdr_void
,
175 NULL
, (xdrproc_t
)xdr_pmaplist_ptr
,
176 (caddr_t
)&head
, minutetimeout
) != RPC_SUCCESS
) {
177 (void) syslog(LOG_ERR
, "%s",
178 clnt_sperror(client
, "pmap_getmaps rpc problem"));
180 CLNT_DESTROY(client
);
182 address
->sin_port
= 0;
183 return ((struct pmaplist
*)head
);
187 * pmapper remote-call-service interface.
188 * This routine is used to call the pmapper remote call service
189 * which will look up a service program in the port maps, and then
190 * remotely call that routine with the given parameters. This allows
191 * programs to do a lookup and call in one step.
194 pmap_rmtcall(struct sockaddr_in
*addr
, rpcprog_t prog
, rpcvers_t vers
,
195 rpcproc_t proc
, xdrproc_t xdrargs
, caddr_t argsp
, xdrproc_t xdrres
,
196 caddr_t resp
, struct timeval tout
, rpcport_t
*port_ptr
)
200 struct p_rmtcallargs a
;
201 struct p_rmtcallres r
;
203 short tmp
= addr
->sin_port
;
205 addr
->sin_port
= htons(PMAPPORT
);
206 client
= clntudp_create(addr
, PMAPPROG
, PMAPVERS
, rmttimeout
, &fd
);
207 if (client
!= NULL
) {
211 a
.args
.args_val
= argsp
;
212 a
.xdr_args
= xdrargs
;
213 r
.res
.res_val
= resp
;
215 stat
= CLNT_CALL(client
, PMAPPROC_CALLIT
,
216 (xdrproc_t
)xdr_rmtcallargs
,
217 (caddr_t
)&a
, (xdrproc_t
)xdr_rmtcallres
,
219 CLNT_DESTROY(client
);
223 addr
->sin_port
= tmp
;