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