#include #include #include /* __constant_hton* */ #include #include #include "nfsmount.h" #include "sunrpc.h" struct portmap_call { struct rpc_call rpc; uint32_t program; uint32_t version; uint32_t proto; uint32_t port; }; struct portmap_reply { struct rpc_reply rpc; uint32_t port; }; static struct portmap_call call = { .rpc = { .program = __constant_htonl(RPC_PMAP_PROGRAM), .prog_vers = __constant_htonl(RPC_PMAP_VERSION), .proc = __constant_htonl(PMAP_PROC_GETPORT), } }; uint32_t portmap(uint32_t server, uint32_t program, uint32_t version, uint32_t proto) { struct portmap_reply reply; struct client *clnt; struct rpc rpc; uint32_t port = 0; clnt = tcp_client(server, RPC_PMAP_PORT, 0); if (clnt == NULL) { clnt = udp_client(server, RPC_PMAP_PORT, 0); if (clnt == NULL) goto bail; } call.program = htonl(program); call.version = htonl(version); call.proto = htonl(proto); rpc.call = (struct rpc_call *)&call; rpc.call_len = sizeof(call); rpc.reply = (struct rpc_reply *)&reply; rpc.reply_len = sizeof(reply); if (rpc_call(clnt, &rpc) < 0) goto bail; if (rpc.reply_len < sizeof(reply)) { fprintf(stderr, "incomplete reply: %zu < %zu\n", rpc.reply_len, sizeof(reply)); goto bail; } port = ntohl(reply.port); bail: dprintf("Port for %d/%d[%s]: %d\n", program, version, proto == IPPROTO_TCP ? "tcp" : "udp", port); if (clnt) client_free(clnt); return port; }