static int xdr_encode_unmon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) { p = xdr_encode_common(rqstp, p, argp); if (IS_ERR(p)) return PTR_ERR(p); rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); return 0; }
static int xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) { p = xdr_encode_common(rqstp, p, argp); if (IS_ERR(p)) return PTR_ERR(p); *p++ = argp->addr; *p++ = argp->vers; *p++ = argp->proto; *p++ = 0; rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); return 0; }
/* * Create NSM client for the local host */ static struct rpc_clnt * nsm_create(void) { struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK), .sin_port = 0, }; struct rpc_create_args args = { .protocol = IPPROTO_UDP, .address = (struct sockaddr *)&sin, .addrsize = sizeof(sin), .servername = "localhost", .program = &nsm_program, .version = SM_VERSION, .authflavor = RPC_AUTH_NULL, .flags = (RPC_CLNT_CREATE_ONESHOT), }; return rpc_create(&args); } /* * XDR functions for NSM. */ static __be32 * xdr_encode_common(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) { char buffer[20], *name; /* * Use the dotted-quad IP address of the remote host as * identifier. Linux statd always looks up the canonical * hostname first for whatever remote hostname it receives, * so this works alright. */ if (nsm_use_hostnames) { name = argp->mon_name; } else { sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr)); name = buffer; } if (!(p = xdr_encode_string(p, name)) || !(p = xdr_encode_string(p, utsname()->nodename))) return ERR_PTR(-EIO); *p++ = htonl(argp->prog); *p++ = htonl(argp->vers); *p++ = htonl(argp->proc); return p; } static int xdr_encode_mon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) { p = xdr_encode_common(rqstp, p, argp); if (IS_ERR(p)) return PTR_ERR(p); /* Surprise - there may even be room for an IPv6 address now */ *p++ = argp->addr; *p++ = 0; *p++ = 0; *p++ = 0; rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); return 0; }