1272343Sngie/* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */ 2272343Sngie 3272343Sngie#include <sys/cdefs.h> 4272343Sngie__RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $"); 5272343Sngie 6272343Sngie#include <sys/types.h> 7272343Sngie#include <sys/socket.h> 8272343Sngie#include <rpc/rpc.h> 9272343Sngie#include <stdlib.h> 10272343Sngie#include <err.h> 11272343Sngie#include <netdb.h> 12272343Sngie#include <stdio.h> 13272343Sngie#include <unistd.h> 14272343Sngie 15272343Sngie 16272343Sngie#ifndef TEST 17272343Sngie#include <atf-c.h> 18272343Sngie 19272343Sngie#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) 20272343Sngie 21272343Sngie#define SKIPX(ev, msg, ...) do { \ 22272343Sngie atf_tc_skip(msg, __VA_ARGS__); \ 23272343Sngie return; \ 24272343Sngie} while(/*CONSTCOND*/0) 25272343Sngie 26272343Sngie#else 27272343Sngie#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) 28272343Sngie#define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) 29272343Sngie#endif 30272343Sngie 31272343Sngie 32272343Sngie#define RPCBPROC_NULL 0 33272343Sngie 34272343Sngiestatic int 35272343Sngiereply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) 36272343Sngie{ 37272343Sngie char host[NI_MAXHOST]; 38272343Sngie struct sockaddr *sock = raddrp->buf; 39272343Sngie int error; 40272343Sngie 41272343Sngie 42272343Sngie error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0); 43272343Sngie if (error) 44272343Sngie warnx("Cannot resolve address (%s)", gai_strerror(error)); 45272343Sngie else 46272343Sngie printf("response from: %s\n", host); 47272343Sngie return 0; 48272343Sngie} 49272343Sngie 50276478Sngie#ifdef __FreeBSD__ 51276478Sngie#define __rpc_control rpc_control 52276478Sngie#endif 53276478Sngie 54272343Sngieextern bool __rpc_control(int, void *); 55272343Sngie 56272343Sngiestatic void 57272343Sngieonehost(const char *host, const char *transp) 58272343Sngie{ 59272343Sngie CLIENT *clnt; 60272343Sngie struct netbuf addr; 61272343Sngie struct timeval tv; 62272343Sngie 63272343Sngie /* 64272343Sngie * Magic! 65272343Sngie */ 66272343Sngie tv.tv_sec = 0; 67272343Sngie tv.tv_usec = 500000; 68272343Sngie#define CLCR_SET_RPCB_TIMEOUT 2 69272343Sngie __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv); 70272343Sngie 71272343Sngie if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL) 72272343Sngie SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror("")); 73272343Sngie 74272343Sngie tv.tv_sec = 1; 75272343Sngie tv.tv_usec = 0; 76291177Sngie#ifdef __FreeBSD__ 77291177Sngie if (clnt_call(clnt, RPCBPROC_NULL, (xdrproc_t)xdr_void, NULL, 78291177Sngie (xdrproc_t)xdr_void, NULL, tv) 79291177Sngie != RPC_SUCCESS) 80291177Sngie#else 81272343Sngie if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) 82272343Sngie != RPC_SUCCESS) 83291177Sngie#endif 84272343Sngie ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); 85272343Sngie clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); 86272343Sngie reply(NULL, &addr, NULL); 87272343Sngie} 88272343Sngie 89272343Sngie#ifdef TEST 90272343Sngiestatic void 91272343Sngieallhosts(void) 92272343Sngie{ 93272343Sngie enum clnt_stat clnt_stat; 94272343Sngie 95272343Sngie clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, 96272343Sngie (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, 97272343Sngie NULL, (resultproc_t)reply, transp); 98272343Sngie if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) 99272343Sngie ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); 100272343Sngie} 101272343Sngie 102272343Sngieint 103272343Sngiemain(int argc, char *argv[]) 104272343Sngie{ 105272343Sngie int ch; 106272343Sngie const char *transp = "udp"; 107272343Sngie 108272343Sngie 109272343Sngie while ((ch = getopt(argc, argv, "ut")) != -1) 110272343Sngie switch (ch) { 111272343Sngie case 't': 112272343Sngie transp = "tcp"; 113272343Sngie break; 114272343Sngie case 'u': 115272343Sngie transp = "udp"; 116272343Sngie break; 117272343Sngie default: 118272343Sngie fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n", 119272343Sngie getprogname()); 120272343Sngie return EXIT_FAILURE; 121272343Sngie } 122272343Sngie 123272343Sngie if (argc == optind) 124272343Sngie allhosts(); 125272343Sngie else 126272343Sngie for (; optind < argc; optind++) 127272343Sngie onehost(argv[optind], transp); 128272343Sngie 129272343Sngie return EXIT_SUCCESS; 130272343Sngie} 131272343Sngie 132272343Sngie#else 133272343Sngie 134272343SngieATF_TC(get_svc_addr_tcp); 135272343SngieATF_TC_HEAD(get_svc_addr_tcp, tc) 136272343Sngie{ 137272343Sngie atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp"); 138272343Sngie 139272343Sngie} 140272343Sngie 141272343SngieATF_TC_BODY(get_svc_addr_tcp, tc) 142272343Sngie{ 143272343Sngie onehost("localhost", "tcp"); 144272343Sngie 145272343Sngie} 146272343Sngie 147272343SngieATF_TC(get_svc_addr_udp); 148272343SngieATF_TC_HEAD(get_svc_addr_udp, tc) 149272343Sngie{ 150272343Sngie atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp"); 151272343Sngie} 152272343Sngie 153272343SngieATF_TC_BODY(get_svc_addr_udp, tc) 154272343Sngie{ 155272343Sngie onehost("localhost", "udp"); 156272343Sngie 157272343Sngie} 158272343Sngie 159272343SngieATF_TP_ADD_TCS(tp) 160272343Sngie{ 161272343Sngie ATF_TP_ADD_TC(tp, get_svc_addr_udp); 162272343Sngie ATF_TP_ADD_TC(tp, get_svc_addr_tcp); 163272343Sngie 164272343Sngie return atf_no_error(); 165272343Sngie} 166272343Sngie 167272343Sngie#endif 168