#include #include #include /* __constant_hton* */ #include #include #include "nfsmount.h" #include "sunrpc.h" struct portmap_call { struct rpc_call rpc; __u32 program; __u32 version; __u32 proto; __u32 port; }; struct portmap_reply { struct rpc_reply rpc; __u32 port; }; static struct portmap_call call = { .rpc.program = __constant_htonl(RPC_PMAP_PROGRAM), .rpc.prog_vers = __constant_htonl(RPC_PMAP_VERSION), .rpc.proc = __constant_htonl(PMAP_PROC_GETPORT), }; __u32 portmap(__u32 server, __u32 program, __u32 version, __u32 proto) { struct portmap_reply reply; struct client *clnt; struct rpc rpc; __u32 port = 0; if ((clnt = tcp_client(server, RPC_PMAP_PORT, 0)) == NULL) { if ((clnt = udp_client(server, RPC_PMAP_PORT, 0)) == 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: %d < %d\n", rpc.reply_len, sizeof(reply)); goto bail; } port = ntohl(reply.port); bail: DEBUG(("Port for %d/%d[%s]: %d\n", program, version, proto == IPPROTO_TCP ? "tcp" : "udp", port)); if (clnt) { client_free(clnt); } return port; }