| @@ -1,63 +1,70 @@ | | | @@ -1,63 +1,70 @@ |
1 | /* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */ | | 1 | /* $NetBSD: t_rpc.c,v 1.4 2015/11/06 15:23:23 christos Exp $ */ |
2 | | | 2 | |
3 | #include <sys/cdefs.h> | | 3 | #include <sys/cdefs.h> |
4 | __RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $"); | | 4 | __RCSID("$NetBSD: t_rpc.c,v 1.4 2015/11/06 15:23:23 christos Exp $"); |
5 | | | 5 | |
6 | #include <sys/types.h> | | 6 | #include <sys/types.h> |
7 | #include <sys/socket.h> | | 7 | #include <sys/socket.h> |
8 | #include <rpc/rpc.h> | | 8 | #include <rpc/rpc.h> |
| | | 9 | #include <rpc/raw.h> |
9 | #include <stdlib.h> | | 10 | #include <stdlib.h> |
10 | #include <err.h> | | 11 | #include <err.h> |
11 | #include <netdb.h> | | 12 | #include <netdb.h> |
12 | #include <stdio.h> | | 13 | #include <stdio.h> |
13 | #include <unistd.h> | | 14 | #include <unistd.h> |
14 | | | 15 | |
15 | | | 16 | |
16 | #ifndef TEST | | 17 | #ifndef TEST |
17 | #include <atf-c.h> | | 18 | #include <atf-c.h> |
18 | | | 19 | |
19 | #define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) | | 20 | #define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) |
20 | | | 21 | |
21 | #define SKIPX(ev, msg, ...) do { \ | | 22 | #define SKIPX(ev, msg, ...) do { \ |
22 | atf_tc_skip(msg, __VA_ARGS__); \ | | 23 | atf_tc_skip(msg, __VA_ARGS__); \ |
23 | return; \ | | 24 | return; \ |
24 | } while(/*CONSTCOND*/0) | | 25 | } while(/*CONSTCOND*/0) |
25 | | | 26 | |
26 | #else | | 27 | #else |
27 | #define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) | | 28 | #define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) |
28 | #define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) | | 29 | #define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) |
29 | #endif | | 30 | #endif |
30 | | | 31 | |
| | | 32 | #ifdef DEBUG |
| | | 33 | #define DPRINTF(...) printf(__VA_ARGS__) |
| | | 34 | #else |
| | | 35 | #define DPRINTF(...) |
| | | 36 | #endif |
| | | 37 | |
31 | | | 38 | |
32 | #define RPCBPROC_NULL 0 | | 39 | #define RPCBPROC_NULL 0 |
33 | | | 40 | |
34 | static int | | 41 | static int |
35 | reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) | | 42 | reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) |
36 | { | | 43 | { |
37 | char host[NI_MAXHOST]; | | 44 | char host[NI_MAXHOST]; |
38 | struct sockaddr *sock = raddrp->buf; | | 45 | struct sockaddr *sock = raddrp->buf; |
39 | int error; | | 46 | int error; |
40 | | | 47 | |
41 | | | 48 | |
42 | error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0); | | 49 | error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0); |
43 | if (error) | | 50 | if (error) |
44 | warnx("Cannot resolve address (%s)", gai_strerror(error)); | | 51 | warnx("Cannot resolve address (%s)", gai_strerror(error)); |
45 | else | | 52 | else |
46 | printf("response from: %s\n", host); | | 53 | printf("response from: %s\n", host); |
47 | return 0; | | 54 | return 0; |
48 | } | | 55 | } |
49 | | | 56 | |
50 | extern bool __rpc_control(int, void *); | | 57 | extern bool_t __rpc_control(int, void *); |
51 | | | 58 | |
52 | static void | | 59 | static void |
53 | onehost(const char *host, const char *transp) | | 60 | onehost(const char *host, const char *transp) |
54 | { | | 61 | { |
55 | CLIENT *clnt; | | 62 | CLIENT *clnt; |
56 | struct netbuf addr; | | 63 | struct netbuf addr; |
57 | struct timeval tv; | | 64 | struct timeval tv; |
58 | | | 65 | |
59 | /* | | 66 | /* |
60 | * Magic! | | 67 | * Magic! |
61 | */ | | 68 | */ |
62 | tv.tv_sec = 0; | | 69 | tv.tv_sec = 0; |
63 | tv.tv_usec = 500000; | | 70 | tv.tv_usec = 500000; |
| @@ -66,65 +73,149 @@ onehost(const char *host, const char *tr | | | @@ -66,65 +73,149 @@ onehost(const char *host, const char *tr |
66 | | | 73 | |
67 | if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL) | | 74 | if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL) |
68 | SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror("")); | | 75 | SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror("")); |
69 | | | 76 | |
70 | tv.tv_sec = 1; | | 77 | tv.tv_sec = 1; |
71 | tv.tv_usec = 0; | | 78 | tv.tv_usec = 0; |
72 | if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) | | 79 | if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) |
73 | != RPC_SUCCESS) | | 80 | != RPC_SUCCESS) |
74 | ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); | | 81 | ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); |
75 | clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); | | 82 | clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); |
76 | reply(NULL, &addr, NULL); | | 83 | reply(NULL, &addr, NULL); |
77 | } | | 84 | } |
78 | | | 85 | |
| | | 86 | #define PROGNUM 0x81 |
| | | 87 | #define VERSNUM 0x01 |
| | | 88 | #define PLUSONE 1 |
| | | 89 | |
| | | 90 | static struct timeval tout = {0, 0}; |
| | | 91 | |
| | | 92 | static void |
| | | 93 | server(struct svc_req *rqstp, SVCXPRT *transp) |
| | | 94 | { |
| | | 95 | int num; |
| | | 96 | |
| | | 97 | DPRINTF("Starting server\n"); |
| | | 98 | |
| | | 99 | switch (rqstp->rq_proc) { |
| | | 100 | case NULLPROC: |
| | | 101 | if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) |
| | | 102 | ERRX(EXIT_FAILURE, "svc_sendreply failed"); |
| | | 103 | return; |
| | | 104 | case PLUSONE: |
| | | 105 | break; |
| | | 106 | default: |
| | | 107 | svcerr_noproc(transp); |
| | | 108 | return; |
| | | 109 | } |
| | | 110 | |
| | | 111 | if (!svc_getargs(transp, (xdrproc_t)xdr_int, (void *)&num)) { |
| | | 112 | svcerr_decode(transp); |
| | | 113 | return; |
| | | 114 | } |
| | | 115 | DPRINTF("About to increment\n"); |
| | | 116 | num++; |
| | | 117 | if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (void *)&num)) |
| | | 118 | ERRX(EXIT_FAILURE, "svc_sendreply failed"); |
| | | 119 | DPRINTF("Leaving server procedure.\n"); |
| | | 120 | } |
| | | 121 | |
| | | 122 | int |
| | | 123 | rawtest(const char *arg) |
| | | 124 | { |
| | | 125 | CLIENT *clnt; |
| | | 126 | SVCXPRT *svc; |
| | | 127 | int num, resp; |
| | | 128 | enum clnt_stat rv; |
| | | 129 | |
| | | 130 | if (arg) |
| | | 131 | num = atoi(arg); |
| | | 132 | else |
| | | 133 | num = 0; |
| | | 134 | |
| | | 135 | svc = svc_raw_create(); |
| | | 136 | if (svc == NULL) |
| | | 137 | ERRX(EXIT_FAILURE, "Can't not create server"); |
| | | 138 | if (!svc_reg(svc, PROGNUM, VERSNUM, server, NULL)) |
| | | 139 | ERRX(EXIT_FAILURE, "Can't not register server"); |
| | | 140 | |
| | | 141 | clnt = clnt_raw_create(PROGNUM, VERSNUM); |
| | | 142 | if (clnt == NULL) |
| | | 143 | ERRX(EXIT_FAILURE, "%s", |
| | | 144 | clnt_spcreateerror("clnt_raw_create")); |
| | | 145 | rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, |
| | | 146 | (xdrproc_t)xdr_int, (void *)&resp, tout); |
| | | 147 | if (rv != RPC_SUCCESS) |
| | | 148 | ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); |
| | | 149 | DPRINTF("Got %d\n", resp); |
| | | 150 | clnt_destroy(clnt); |
| | | 151 | svc_destroy(svc); |
| | | 152 | if (++num != resp) |
| | | 153 | ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); |
| | | 154 | |
| | | 155 | return EXIT_SUCCESS; |
| | | 156 | } |
| | | 157 | |
| | | 158 | |
79 | #ifdef TEST | | 159 | #ifdef TEST |
80 | static void | | 160 | static void |
81 | allhosts(void) | | 161 | allhosts(const char *transp) |
82 | { | | 162 | { |
83 | enum clnt_stat clnt_stat; | | 163 | enum clnt_stat clnt_stat; |
84 | | | 164 | |
85 | clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, | | 165 | clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, |
86 | (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, | | 166 | (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, |
87 | NULL, (resultproc_t)reply, transp); | | 167 | NULL, (resultproc_t)reply, transp); |
88 | if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) | | 168 | if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) |
89 | ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); | | 169 | ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); |
90 | } | | 170 | } |
91 | | | 171 | |
92 | int | | 172 | int |
93 | main(int argc, char *argv[]) | | 173 | main(int argc, char *argv[]) |
94 | { | | 174 | { |
95 | int ch; | | 175 | int ch; |
96 | const char *transp = "udp"; | | 176 | const char *transp = "udp"; |
97 | | | 177 | |
98 | | | 178 | |
99 | while ((ch = getopt(argc, argv, "ut")) != -1) | | 179 | while ((ch = getopt(argc, argv, "rtu")) != -1) |
100 | switch (ch) { | | 180 | switch (ch) { |
101 | case 't': | | 181 | case 't': |
102 | transp = "tcp"; | | 182 | transp = "tcp"; |
103 | break; | | 183 | break; |
104 | case 'u': | | 184 | case 'u': |
105 | transp = "udp"; | | 185 | transp = "udp"; |
106 | break; | | 186 | break; |
| | | 187 | case 'r': |
| | | 188 | transp = NULL; |
| | | 189 | break; |
107 | default: | | 190 | default: |
108 | fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n", | | 191 | fprintf(stderr, "Usage: %s -[r|t|u] [<hostname>...]\n", |
109 | getprogname()); | | 192 | getprogname()); |
110 | return EXIT_FAILURE; | | 193 | return EXIT_FAILURE; |
111 | } | | 194 | } |
112 | | | 195 | |
113 | if (argc == optind) | | 196 | if (argc == optind) { |
114 | allhosts(); | | 197 | if (transp) |
115 | else | | 198 | allhosts(transp); |
116 | for (; optind < argc; optind++) | | 199 | else |
117 | onehost(argv[optind], transp); | | 200 | rawtest(NULL); |
| | | 201 | } else { |
| | | 202 | for (; optind < argc; optind++) { |
| | | 203 | if (transp) |
| | | 204 | onehost(argv[optind], transp); |
| | | 205 | else |
| | | 206 | rawtest(argv[optind]); |
| | | 207 | } |
| | | 208 | } |
118 | | | 209 | |
119 | return EXIT_SUCCESS; | | 210 | return EXIT_SUCCESS; |
120 | } | | 211 | } |
121 | | | 212 | |
122 | #else | | 213 | #else |
123 | | | 214 | |
124 | ATF_TC(get_svc_addr_tcp); | | 215 | ATF_TC(get_svc_addr_tcp); |
125 | ATF_TC_HEAD(get_svc_addr_tcp, tc) | | 216 | ATF_TC_HEAD(get_svc_addr_tcp, tc) |
126 | { | | 217 | { |
127 | atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp"); | | 218 | atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp"); |
128 | | | 219 | |
129 | } | | 220 | } |
130 | | | 221 | |
| @@ -136,22 +227,34 @@ ATF_TC_BODY(get_svc_addr_tcp, tc) | | | @@ -136,22 +227,34 @@ ATF_TC_BODY(get_svc_addr_tcp, tc) |
136 | | | 227 | |
137 | ATF_TC(get_svc_addr_udp); | | 228 | ATF_TC(get_svc_addr_udp); |
138 | ATF_TC_HEAD(get_svc_addr_udp, tc) | | 229 | ATF_TC_HEAD(get_svc_addr_udp, tc) |
139 | { | | 230 | { |
140 | atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp"); | | 231 | atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp"); |
141 | } | | 232 | } |
142 | | | 233 | |
143 | ATF_TC_BODY(get_svc_addr_udp, tc) | | 234 | ATF_TC_BODY(get_svc_addr_udp, tc) |
144 | { | | 235 | { |
145 | onehost("localhost", "udp"); | | 236 | onehost("localhost", "udp"); |
146 | | | 237 | |
147 | } | | 238 | } |
148 | | | 239 | |
| | | 240 | ATF_TC(raw); |
| | | 241 | ATF_TC_HEAD(raw, tc) |
| | | 242 | { |
| | | 243 | atf_tc_set_md_var(tc, "descr", "Checks svc raw"); |
| | | 244 | } |
| | | 245 | |
| | | 246 | ATF_TC_BODY(raw, tc) |
| | | 247 | { |
| | | 248 | rawtest(NULL); |
| | | 249 | |
| | | 250 | } |
149 | ATF_TP_ADD_TCS(tp) | | 251 | ATF_TP_ADD_TCS(tp) |
150 | { | | 252 | { |
151 | ATF_TP_ADD_TC(tp, get_svc_addr_udp); | | 253 | ATF_TP_ADD_TC(tp, get_svc_addr_udp); |
152 | ATF_TP_ADD_TC(tp, get_svc_addr_tcp); | | 254 | ATF_TP_ADD_TC(tp, get_svc_addr_tcp); |
| | | 255 | ATF_TP_ADD_TC(tp, raw); |
153 | | | 256 | |
154 | return atf_no_error(); | | 257 | return atf_no_error(); |
155 | } | | 258 | } |
156 | | | 259 | |
157 | #endif | | 260 | #endif |