/* Note that passing in INADDR_ANY does not create the same service registration as IN6ADDR_ANY. The former advertises an RPC service on any IPv4 address, but not on IPv6. The latter advertises the service on all IPv4 and IPv6 addresses.  */
int rpcb_v4_register(const u32 program, const u32 version, const struct sockaddr *address, const char *netid)
/* Note that passing in INADDR_ANY does not create the same service registration as IN6ADDR_ANY. The former advertises an RPC service on any IPv4 address, but not on IPv6. The latter advertises the service on all IPv4 and IPv6 addresses.  */
int rpcb_v4_register(const u32 program, const u32 version, const struct sockaddr *address, const char *netid)
{
	struct rpcbind_args map = {
		.r_prog		= program,
		.r_vers		= version,
		.r_netid	= netid,
		.r_owner	= RPCB_OWNER_STRING,
	};
	struct rpc_message msg = {
		.rpc_argp	= &map,
	};
	int error;
	error = rpcb_create_local();
	if (error)
		return error;
	if (rpcb_local_clnt4 == NULL)
		return -EPROTONOSUPPORT;
	if (address == NULL)
		return rpcb_unregister_all_protofamilies(&msg);
	switch (address->sa_family) {
	case AF_INET:
		return rpcb_register_inet4(address, &msg);
	case AF_INET6:
		return rpcb_register_inet6(address, &msg);
	}
	return -EAFNOSUPPORT;
}