+ return nfs_get_tcpclient(sap, salen, program, version,
+ timeout, 0);
+ case 0:
+ case IPPROTO_UDP:
+ return nfs_get_udpclient(sap, salen, program, version,
+ timeout, 0);
+ }
+
+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
+ return NULL;
+}
+
+/**
+ * nfs_get_priv_rpcclient - acquire an RPC client
+ * @sap: pointer to socket address of RPC server
+ * @salen: length of socket address
+ * @transport: IPPROTO_ value of transport protocol to use
+ * @program: RPC program number
+ * @version: RPC version number
+ * @timeout: pointer to request timeout (must not be NULL)
+ *
+ * Set up an RPC client for communicating with an RPC program @program
+ * and @version on the server @sap over @transport. A privileged
+ * source port is used.
+ *
+ * Returns a pointer to a prepared RPC client if successful, and
+ * @timeout is initialized; caller must destroy a non-NULL returned RPC
+ * client. Otherwise returns NULL, and rpc_createerr.cf_stat is set to
+ * reflect the error.
+ */
+CLIENT *nfs_get_priv_rpcclient(const struct sockaddr *sap,
+ const socklen_t salen,
+ const unsigned short transport,
+ const rpcprog_t program,
+ const rpcvers_t version,
+ struct timeval *timeout)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)sap;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
+
+ switch (sap->sa_family) {
+ case AF_LOCAL:
+ return nfs_get_localclient(sap, salen, program,
+ version, timeout);
+ case AF_INET:
+ if (sin->sin_port == 0) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
+ return NULL;
+ }
+ break;
+ case AF_INET6:
+ if (sin6->sin6_port == 0) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
+ return NULL;
+ }
+ break;
+ default:
+ rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+ return NULL;
+ }
+
+ switch (transport) {
+ case IPPROTO_TCP:
+ return nfs_get_tcpclient(sap, salen, program, version,
+ timeout, 1);