1 /* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */ 2 3 #include <sys/cdefs.h> 4 __RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $"); 5 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <rpc/rpc.h> 9 #include <stdlib.h> 10 #include <err.h> 11 #include <netdb.h> 12 #include <stdio.h> 13 #include <unistd.h> 14 15 16 #ifndef TEST 17 #include <atf-c.h> 18 19 #define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) 20 21 #define SKIPX(ev, msg, ...) do { \ 22 atf_tc_skip(msg, __VA_ARGS__); \ 23 return; \ 24 } while(/*CONSTCOND*/0) 25 26 #else 27 #define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) 28 #define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) 29 #endif 30 31 32 #define RPCBPROC_NULL 0 33 34 static int 35 reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) 36 { 37 char host[NI_MAXHOST]; 38 struct sockaddr *sock = raddrp->buf; 39 int error; 40 41 42 error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0); 43 if (error) 44 warnx("Cannot resolve address (%s)", gai_strerror(error)); 45 else 46 printf("response from: %s\n", host); 47 return 0; 48 } 49 50 #ifdef __FreeBSD__ 51 #define __rpc_control rpc_control 52 #endif 53 54 extern bool __rpc_control(int, void *); 55 56 static void 57 onehost(const char *host, const char *transp) 58 { 59 CLIENT *clnt; 60 struct netbuf addr; 61 struct timeval tv; 62 63 /* 64 * Magic! 65 */ 66 tv.tv_sec = 0; 67 tv.tv_usec = 500000; 68 #define CLCR_SET_RPCB_TIMEOUT 2 69 __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv); 70 71 if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL) 72 SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror("")); 73 74 tv.tv_sec = 1; 75 tv.tv_usec = 0; 76 #ifdef __FreeBSD__ 77 if (clnt_call(clnt, RPCBPROC_NULL, (xdrproc_t)xdr_void, NULL, 78 (xdrproc_t)xdr_void, NULL, tv) 79 != RPC_SUCCESS) 80 #else 81 if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) 82 != RPC_SUCCESS) 83 #endif 84 ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); 85 clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); 86 reply(NULL, &addr, NULL); 87 } 88 89 #ifdef TEST 90 static void 91 allhosts(void) 92 { 93 enum clnt_stat clnt_stat; 94 95 clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, 96 (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, 97 NULL, (resultproc_t)reply, transp); 98 if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) 99 ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); 100 } 101 102 int 103 main(int argc, char *argv[]) 104 { 105 int ch; 106 const char *transp = "udp"; 107 108 109 while ((ch = getopt(argc, argv, "ut")) != -1) 110 switch (ch) { 111 case 't': 112 transp = "tcp"; 113 break; 114 case 'u': 115 transp = "udp"; 116 break; 117 default: 118 fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n", 119 getprogname()); 120 return EXIT_FAILURE; 121 } 122 123 if (argc == optind) 124 allhosts(); 125 else 126 for (; optind < argc; optind++) 127 onehost(argv[optind], transp); 128 129 return EXIT_SUCCESS; 130 } 131 132 #else 133 134 ATF_TC(get_svc_addr_tcp); 135 ATF_TC_HEAD(get_svc_addr_tcp, tc) 136 { 137 atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp"); 138 139 } 140 141 ATF_TC_BODY(get_svc_addr_tcp, tc) 142 { 143 onehost("localhost", "tcp"); 144 145 } 146 147 ATF_TC(get_svc_addr_udp); 148 ATF_TC_HEAD(get_svc_addr_udp, tc) 149 { 150 atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp"); 151 } 152 153 ATF_TC_BODY(get_svc_addr_udp, tc) 154 { 155 onehost("localhost", "udp"); 156 157 } 158 159 ATF_TP_ADD_TCS(tp) 160 { 161 ATF_TP_ADD_TC(tp, get_svc_addr_udp); 162 ATF_TP_ADD_TC(tp, get_svc_addr_tcp); 163 164 return atf_no_error(); 165 } 166 167 #endif 168