Remove building with NOCRYPTO option
[minix.git] / minix / tests / test91.c
blob13e996cdc6c83213e0936167dd8853baa6746617
1 /* Advanced tests for TCP and UDP sockets (LWIP) - by D.C. van Moolenbroek */
2 /*
3 * This is a somewhat random collection of in-depth tests, complementing the
4 * more general functionality tests in test80 and test81. The overall test set
5 * is still by no means expected to be "complete." The subtests are in random
6 * order.
7 */
8 #include <stdlib.h>
9 #include <string.h>
10 #include <signal.h>
11 #include <sys/ioctl.h>
12 #include <sys/mman.h>
13 #include <sys/param.h>
14 #include <sys/wait.h>
15 #include <sys/queue.h>
16 #include <sys/socket.h>
17 #include <net/route.h>
18 #include <netinet/in.h>
19 #include <netinet/ip.h>
20 #include <netinet/ip_var.h>
21 #include <netinet/tcp.h>
22 #include <netinet/tcp_fsm.h>
23 #include <netinet/tcp_timer.h>
24 #include <netinet/tcp_var.h>
25 #include <netinet/udp.h>
26 #include <netinet6/in6_pcb.h>
27 #include <netinet6/in6_var.h>
28 #include <arpa/inet.h>
29 #include <ifaddrs.h>
30 #include <machine/vmparam.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <assert.h>
35 #include "common.h"
36 #include "socklib.h"
38 #define ITERATIONS 1
40 static const enum state tcp_states[] = {
41 S_NEW, S_N_SHUT_R, S_BOUND, S_LISTENING,
42 S_L_SHUT_R, S_L_SHUT_W, S_L_SHUT_RW, S_CONNECTING,
43 S_C_SHUT_R, S_C_SHUT_W, S_C_SHUT_RW, S_CONNECTED,
44 S_ACCEPTED, S_SHUT_R, S_SHUT_W, S_SHUT_RW,
45 S_RSHUT_R, S_RSHUT_W, S_RSHUT_RW, S_SHUT2_R,
46 S_SHUT2_W, S_SHUT2_RW, S_PRE_EOF, S_AT_EOF,
47 S_POST_EOF, S_PRE_SHUT_R, S_EOF_SHUT_R, S_POST_SHUT_R,
48 S_PRE_SHUT_W, S_EOF_SHUT_W, S_POST_SHUT_W, S_PRE_SHUT_RW,
49 S_EOF_SHUT_RW, S_POST_SHUT_RW, S_PRE_RESET, S_AT_RESET,
50 S_POST_RESET, S_FAILED, S_POST_FAILED
53 static const int tcp_results[][__arraycount(tcp_states)] = {
54 [C_ACCEPT] = {
55 -EINVAL, -EINVAL, -EINVAL, -EAGAIN,
56 -ECONNABORTED, -ECONNABORTED, -ECONNABORTED, -EINVAL,
57 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
58 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
59 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
60 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
61 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
62 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
63 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
64 -EINVAL, -EINVAL, -EINVAL,
66 [C_BIND] = {
67 0, 0, -EINVAL, -EINVAL,
68 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
69 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
70 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
71 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
72 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
73 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
74 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
75 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
76 -EINVAL, -EINVAL, -EINVAL,
78 [C_CONNECT] = {
79 -EINPROGRESS, -EINPROGRESS, -EINPROGRESS, -EOPNOTSUPP,
80 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EALREADY,
81 -EALREADY, -EINVAL, -EINVAL, -EISCONN,
82 -EISCONN, -EISCONN, -EISCONN, -EISCONN,
83 -EISCONN, -EISCONN, -EISCONN, -EISCONN,
84 -EINVAL, -EINVAL, -EISCONN, -EISCONN,
85 -EISCONN, -EISCONN, -EISCONN, -EISCONN,
86 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
87 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
88 -EINVAL, -EINVAL, -EINVAL,
90 [C_GETPEERNAME] = {
91 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
92 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
93 -ENOTCONN, -ENOTCONN, -ENOTCONN, 0,
94 0, 0, 0, 0,
95 0, 0, 0, 0,
96 -ENOTCONN, -ENOTCONN, 0, 0,
97 0, 0, 0, 0,
98 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
99 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
100 -ENOTCONN, -ENOTCONN, -ENOTCONN,
102 [C_GETSOCKNAME] = {
103 0, 0, 0, 0,
104 -EINVAL, -EINVAL, -EINVAL, 0,
105 0, -EINVAL, -EINVAL, 0,
106 0, 0, 0, 0,
107 0, 0, 0, 0,
108 -EINVAL, -EINVAL, 0, 0,
109 0, 0, 0, 0,
110 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
111 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
112 -EINVAL, -EINVAL, -EINVAL,
114 [C_GETSOCKOPT_ERR] = {
115 0, 0, 0, 0,
116 0, 0, 0, 0,
117 0, 0, 0, 0,
118 0, 0, 0, 0,
119 0, 0, 0, 0,
120 0, 0, 0, 0,
121 0, 0, 0, 0,
122 0, 0, 0, 0,
123 0, 0, -ECONNRESET, -ECONNRESET,
124 0, -ECONNREFUSED, 0,
126 [C_GETSOCKOPT_KA] = {
127 0, 0, 0, 0,
128 0, 0, 0, 0,
129 0, 0, 0, 0,
130 0, 0, 0, 0,
131 0, 0, 0, 0,
132 0, 0, 0, 0,
133 0, 0, 0, 0,
134 0, 0, 0, 0,
135 0, 0, 0, 0,
136 0, 0, 0,
138 [C_GETSOCKOPT_RB] = {
139 0, 0, 0, 0,
140 -ECONNRESET, -ECONNRESET, -ECONNRESET, 0,
141 0, -ECONNRESET, -ECONNRESET, 0,
142 0, 0, 0, 0,
143 0, 0, 0, 0,
144 -ECONNRESET, -ECONNRESET, 0, 0,
145 0, 0, 0, 0,
146 -ECONNRESET, -ECONNRESET, -ECONNRESET, -ECONNRESET,
147 -ECONNRESET, -ECONNRESET, -ECONNRESET, -ECONNRESET,
148 -ECONNRESET, -ECONNRESET, -ECONNRESET,
150 [C_IOCTL_NREAD] = {
151 0, 0, 0, 0,
152 0, 0, 0, 0,
153 0, 0, 0, 0,
154 0, 0, 0, 0,
155 0, 0, 0, 0,
156 0, 0, 1, 0,
157 0, 0, 0, 0,
158 1, 0, 0, 0,
159 0, 0, 1, 0,
160 0, 0, 0,
162 [C_LISTEN] = {
163 0, 0, 0, 0,
164 0, 0, 0, -EINVAL,
165 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
166 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
167 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
168 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
169 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
170 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
171 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
172 -EINVAL, -EINVAL, -EINVAL,
174 [C_RECV] = {
175 -ENOTCONN, 0, -ENOTCONN, -ENOTCONN,
176 0, 0, 0, -EAGAIN,
177 0, 0, 0, -EAGAIN,
178 -EAGAIN, 0, -EAGAIN, 0,
179 -EAGAIN, 0, 0, 0,
180 0, 0, 1, 0,
181 0, 0, 0, 0,
182 1, 0, 0, 0,
183 0, 0, 1, -ECONNRESET,
184 0, -ECONNREFUSED, 0,
186 [C_RECVFROM] = {
187 -ENOTCONN, 0, -ENOTCONN, -ENOTCONN,
188 0, 0, 0, -EAGAIN,
189 0, 0, 0, -EAGAIN,
190 -EAGAIN, 0, -EAGAIN, 0,
191 -EAGAIN, 0, 0, 0,
192 0, 0, 1, 0,
193 0, 0, 0, 0,
194 1, 0, 0, 0,
195 0, 0, 1, -ECONNRESET,
196 0, -ECONNREFUSED, 0,
198 [C_SEND] = {
199 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
200 -EPIPE, -EPIPE, -EPIPE, -EAGAIN,
201 -EAGAIN, -EPIPE, -EPIPE, 1,
202 1, 1, -EPIPE, -EPIPE,
203 1, 1, 1, 1,
204 -EPIPE, -EPIPE, 1, 1,
205 1, 1, 1, 1,
206 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
207 -EPIPE, -EPIPE, -ECONNRESET, -ECONNRESET,
208 -EPIPE, -ECONNREFUSED, -EPIPE,
210 [C_SENDTO] = {
211 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
212 -EPIPE, -EPIPE, -EPIPE, -EAGAIN,
213 -EAGAIN, -EPIPE, -EPIPE, 1,
214 1, 1, -EPIPE, -EPIPE,
215 1, 1, 1, 1,
216 -EPIPE, -EPIPE, 1, 1,
217 1, 1, 1, 1,
218 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
219 -EPIPE, -EPIPE, -ECONNRESET, -ECONNRESET,
220 -EPIPE, -ECONNREFUSED, -EPIPE,
222 [C_SELECT_R] = {
223 1, 1, 1, 0,
224 1, 1, 1, 0,
225 1, 1, 1, 0,
226 0, 1, 0, 1,
227 0, 1, 1, 1,
228 1, 1, 1, 1,
229 1, 1, 1, 1,
230 1, 1, 1, 1,
231 1, 1, 1, 1,
232 1, 1, 1,
234 [C_SELECT_W] = {
235 1, 1, 1, 1,
236 1, 1, 1, 0,
237 0, 1, 1, 1,
238 1, 1, 1, 1,
239 1, 1, 1, 1,
240 1, 1, 1, 1,
241 1, 1, 1, 1,
242 1, 1, 1, 1,
243 1, 1, 1, 1,
244 1, 1, 1,
246 [C_SELECT_X] = {
247 0, 0, 0, 0,
248 0, 0, 0, 0,
249 0, 0, 0, 0,
250 0, 0, 0, 0,
251 0, 0, 0, 0,
252 0, 0, 0, 0,
253 0, 0, 0, 0,
254 0, 0, 0, 0,
255 0, 0, 0, 0,
256 0, 0, 0,
258 [C_SETSOCKOPT_BC] = {
259 0, 0, 0, 0,
260 0, 0, 0, 0,
261 0, 0, 0, 0,
262 0, 0, 0, 0,
263 0, 0, 0, 0,
264 0, 0, 0, 0,
265 0, 0, 0, 0,
266 0, 0, 0, 0,
267 0, 0, 0, 0,
268 0, 0, 0,
270 [C_SETSOCKOPT_KA] = {
271 0, 0, 0, 0,
272 0, 0, 0, 0,
273 0, 0, 0, 0,
274 0, 0, 0, 0,
275 0, 0, 0, 0,
276 0, 0, 0, 0,
277 0, 0, 0, 0,
278 0, 0, 0, 0,
279 0, 0, 0, 0,
280 0, 0, 0,
282 [C_SETSOCKOPT_L] = {
283 0, 0, 0, 0,
284 0, 0, 0, 0,
285 0, 0, 0, 0,
286 0, 0, 0, 0,
287 0, 0, 0, 0,
288 0, 0, 0, 0,
289 0, 0, 0, 0,
290 0, 0, 0, 0,
291 0, 0, 0, 0,
292 0, 0, 0,
294 [C_SETSOCKOPT_RA] = {
295 0, 0, 0, 0,
296 0, 0, 0, 0,
297 0, 0, 0, 0,
298 0, 0, 0, 0,
299 0, 0, 0, 0,
300 0, 0, 0, 0,
301 0, 0, 0, 0,
302 0, 0, 0, 0,
303 0, 0, 0, 0,
304 0, 0, 0,
306 [C_SHUTDOWN_R] = {
307 0, 0, 0, 0,
308 0, 0, 0, 0,
309 0, 0, 0, 0,
310 0, 0, 0, 0,
311 0, 0, 0, 0,
312 0, 0, 0, 0,
313 0, 0, 0, 0,
314 0, 0, 0, 0,
315 0, 0, 0, 0,
316 0, 0, 0,
318 [C_SHUTDOWN_RW] = {
319 -ENOTCONN, -ENOTCONN, -ENOTCONN, 0,
320 -ENOTCONN, -ENOTCONN, -ENOTCONN, 0,
321 0, -ENOTCONN, -ENOTCONN, 0,
322 0, 0, 0, 0,
323 0, 0, 0, 0,
324 -ENOTCONN, -ENOTCONN, 0, 0,
325 0, 0, 0, 0,
326 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
327 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
328 -ENOTCONN, -ENOTCONN, -ENOTCONN,
330 [C_SHUTDOWN_W] = {
331 -ENOTCONN, -ENOTCONN, -ENOTCONN, 0,
332 -ENOTCONN, -ENOTCONN, -ENOTCONN, 0,
333 0, -ENOTCONN, -ENOTCONN, 0,
334 0, 0, 0, 0,
335 0, 0, 0, 0,
336 -ENOTCONN, -ENOTCONN, 0, 0,
337 0, 0, 0, 0,
338 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
339 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
340 -ENOTCONN, -ENOTCONN, -ENOTCONN,
345 * Set up a TCP socket file descriptor in the requested state and pass it to
346 * socklib_sweep_call() along with local and remote addresses and their length.
348 static int
349 tcp_sweep(int domain, int type, int protocol, enum state state, enum call call)
351 struct sockaddr_in sinA, sinB, sinC, sinD;
352 struct sockaddr_in6 sin6A, sin6B, sin6C, sin6D;
353 struct sockaddr *addrA, *addrB, *addrC, *addrD;
354 socklen_t addr_len, len;
355 struct linger l;
356 fd_set fds;
357 char buf[1];
358 int r, fd, fd2, fd3, tmpfd, val;
360 if (domain == AF_INET) {
361 memset(&sin6A, 0, sizeof(sin6A));
362 sinA.sin_family = domain;
363 sinA.sin_port = htons(TEST_PORT_A);
364 sinA.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
366 memcpy(&sinB, &sinA, sizeof(sinB));
367 sinB.sin_port = htons(0);
369 memcpy(&sinC, &sinA, sizeof(sinC));
370 sinC.sin_addr.s_addr = inet_addr(TEST_BLACKHOLE_IPV4);
372 memcpy(&sinD, &sinA, sizeof(sinD));
373 sinD.sin_port = htons(TEST_PORT_B);
375 addrA = (struct sockaddr *)&sinA;
376 addrB = (struct sockaddr *)&sinB;
377 addrC = (struct sockaddr *)&sinC;
378 addrD = (struct sockaddr *)&sinD;
379 addr_len = sizeof(sinA);
380 } else {
381 assert(domain == AF_INET6);
383 memset(&sin6A, 0, sizeof(sin6A));
384 sin6A.sin6_family = domain;
385 sin6A.sin6_port = htons(TEST_PORT_A);
386 memcpy(&sin6A.sin6_addr, &in6addr_loopback,
387 sizeof(sin6A.sin6_addr));
389 memcpy(&sin6B, &sin6A, sizeof(sin6B));
390 sin6B.sin6_port = htons(0);
392 memcpy(&sin6C, &sin6A, sizeof(sin6C));
393 if (inet_pton(domain, TEST_BLACKHOLE_IPV6,
394 &sin6C.sin6_addr) != 1) e(0);
396 memcpy(&sin6D, &sin6A, sizeof(sin6D));
397 sin6D.sin6_port = htons(TEST_PORT_B);
399 addrA = (struct sockaddr *)&sin6A;
400 addrB = (struct sockaddr *)&sin6B;
401 addrC = (struct sockaddr *)&sin6C;
402 addrD = (struct sockaddr *)&sin6D;
403 addr_len = sizeof(sin6A);
406 /* Create a bound remote socket. */
407 if ((fd2 = socket(domain, type | SOCK_NONBLOCK, protocol)) < 0) e(0);
409 if (bind(fd2, addrB, addr_len) != 0) e(0);
411 len = addr_len;
412 if (getsockname(fd2, addrB, &len) != 0) e(0);
413 if (len != addr_len) e(0);
415 if (listen(fd2, 1) != 0) e(0);
417 fd3 = -1;
419 switch (state) {
420 case S_NEW:
421 case S_N_SHUT_R:
422 if ((fd = socket(domain, type | SOCK_NONBLOCK,
423 protocol)) < 0) e(0);
425 val = 1;
426 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
427 sizeof(val)) != 0) e(0);
429 if (state == S_N_SHUT_R && shutdown(fd, SHUT_RD)) e(0);
431 break;
433 case S_BOUND:
434 case S_LISTENING:
435 case S_L_SHUT_R:
436 case S_L_SHUT_W:
437 case S_L_SHUT_RW:
438 if ((fd = socket(domain, type | SOCK_NONBLOCK,
439 protocol)) < 0) e(0);
441 val = 1;
442 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
443 sizeof(val)) != 0) e(0);
445 if (bind(fd, addrA, addr_len) != 0) e(0);
447 if (state == S_BOUND)
448 break;
450 if (listen(fd, 1) != 0) e(0);
452 switch (state) {
453 case S_L_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
454 case S_L_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
455 case S_L_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
456 default: break;
459 break;
461 case S_CONNECTING:
462 case S_C_SHUT_R:
463 case S_C_SHUT_W:
464 case S_C_SHUT_RW:
465 if ((fd = socket(domain, type | SOCK_NONBLOCK,
466 protocol)) < 0) e(0);
468 if (connect(fd, addrC, addr_len) != -1) e(0);
469 if (errno != EINPROGRESS) e(0);
471 switch (state) {
472 case S_C_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
473 case S_C_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
474 case S_C_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
475 default: break;
478 break;
480 case S_CONNECTED:
481 case S_ACCEPTED:
482 case S_SHUT_R:
483 case S_SHUT_W:
484 case S_SHUT_RW:
485 case S_RSHUT_R:
486 case S_RSHUT_W:
487 case S_RSHUT_RW:
488 case S_SHUT2_R:
489 case S_SHUT2_W:
490 case S_SHUT2_RW:
491 if ((fd = socket(domain, type | SOCK_NONBLOCK,
492 protocol)) < 0) e(0);
494 if (connect(fd, addrB, addr_len) != -1) e(0);
495 if (errno != EINPROGRESS) e(0);
497 /* Just to make sure, wait for the socket to be acceptable. */
498 FD_ZERO(&fds);
499 FD_SET(fd2, &fds);
500 if (select(fd2 + 1, &fds, NULL, NULL, NULL) != 1) e(0);
502 len = addr_len;
503 if ((fd3 = accept(fd2, addrC, &len)) < 0) e(0);
505 /* Just to make sure, wait for the socket to be connected. */
506 FD_ZERO(&fds);
507 FD_SET(fd, &fds);
508 if (select(fd + 1, NULL, &fds, NULL, NULL) != 1) e(0);
510 switch (state) {
511 case S_SHUT_R:
512 case S_SHUT2_R: if (shutdown(fd, SHUT_RD)) e(0); break;
513 case S_SHUT_W:
514 case S_SHUT2_W: if (shutdown(fd, SHUT_WR)) e(0); break;
515 case S_SHUT_RW:
516 case S_SHUT2_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
517 default: break;
520 switch (state) {
521 case S_RSHUT_R:
522 case S_SHUT2_R: if (shutdown(fd3, SHUT_RD)) e(0); break;
523 case S_RSHUT_W:
524 case S_SHUT2_W: if (shutdown(fd3, SHUT_WR)) e(0); break;
525 case S_RSHUT_RW:
526 case S_SHUT2_RW: if (shutdown(fd3, SHUT_RDWR)) e(0); break;
527 default: break;
530 if (state == S_ACCEPTED) {
531 tmpfd = fd;
532 fd = fd3;
533 fd3 = tmpfd;
536 break;
538 case S_PRE_EOF:
539 case S_AT_EOF:
540 case S_POST_EOF:
541 case S_PRE_SHUT_R:
542 case S_EOF_SHUT_R:
543 case S_POST_SHUT_R:
544 case S_PRE_SHUT_W:
545 case S_EOF_SHUT_W:
546 case S_POST_SHUT_W:
547 case S_PRE_SHUT_RW:
548 case S_EOF_SHUT_RW:
549 case S_POST_SHUT_RW:
550 case S_PRE_RESET:
551 case S_AT_RESET:
552 case S_POST_RESET:
553 if ((fd = socket(domain, type | SOCK_NONBLOCK,
554 protocol)) < 0) e(0);
556 if (connect(fd, addrB, addr_len) != -1) e(0);
557 if (errno != EINPROGRESS) e(0);
559 /* Just to make sure, wait for the socket to be acceptable. */
560 FD_ZERO(&fds);
561 FD_SET(fd2, &fds);
562 if (select(fd2 + 1, &fds, NULL, NULL, NULL) != 1) e(0);
564 len = addr_len;
565 if ((fd3 = accept(fd2, addrC, &len)) < 0) e(0);
567 if (send(fd3, "", 1, 0) != 1) e(0);
569 switch (state) {
570 case S_PRE_RESET:
571 case S_AT_RESET:
572 case S_POST_RESET:
573 l.l_onoff = 1;
574 l.l_linger = 0;
576 if (setsockopt(fd3, SOL_SOCKET, SO_LINGER, &l,
577 sizeof(l)) != 0) e(0);
579 break;
580 default:
581 break;
584 if (close(fd3) != 0) e(0);
585 fd3 = -1;
587 /* Just to make sure, wait for the socket to receive data. */
588 FD_ZERO(&fds);
589 FD_SET(fd, &fds);
590 if (select(fd + 1, &fds, NULL, NULL, NULL) != 1) e(0);
592 switch (state) {
593 case S_AT_EOF:
594 case S_EOF_SHUT_R:
595 case S_EOF_SHUT_W:
596 case S_EOF_SHUT_RW:
597 case S_AT_RESET:
598 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
599 break;
600 case S_POST_EOF:
601 case S_POST_SHUT_R:
602 case S_POST_SHUT_W:
603 case S_POST_SHUT_RW:
604 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
605 if (recv(fd, buf, sizeof(buf), 0) != 0) e(0);
606 break;
607 case S_POST_RESET:
608 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
609 (void)recv(fd, buf, sizeof(buf), 0);
610 break;
611 default:
612 break;
615 switch (state) {
616 case S_PRE_SHUT_R:
617 case S_EOF_SHUT_R:
618 case S_POST_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
619 case S_PRE_SHUT_W:
620 case S_EOF_SHUT_W:
621 case S_POST_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
622 case S_PRE_SHUT_RW:
623 case S_EOF_SHUT_RW:
624 case S_POST_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
625 default: break;
628 break;
630 case S_FAILED:
631 case S_POST_FAILED:
632 if ((fd = socket(domain, type | SOCK_NONBLOCK,
633 protocol)) < 0) e(0);
635 if (connect(fd, addrD, addr_len) != -1) e(0);
636 if (errno != EINPROGRESS) e(0);
638 FD_ZERO(&fds);
639 FD_SET(fd, &fds);
640 if (select(fd + 1, &fds, NULL, NULL, NULL) != 1) e(0);
642 if (state == S_POST_FAILED) {
643 if (recv(fd, buf, sizeof(buf), 0) != -1) e(0);
644 if (errno != ECONNREFUSED) e(0);
647 break;
649 default:
650 fd = -1;
651 e(0);
654 r = socklib_sweep_call(call, fd, addrA, addrB, addr_len);
656 if (close(fd) != 0) e(0);
657 if (fd2 != -1 && close(fd2) != 0) e(0);
658 if (fd3 != -1 && close(fd3) != 0) e(0);
660 return r;
663 static const enum state udp_states[] = {
664 S_NEW, S_N_SHUT_R, S_N_SHUT_W, S_N_SHUT_RW,
665 S_BOUND, S_CONNECTED, S_SHUT_R, S_SHUT_W,
666 S_SHUT_RW, S_RSHUT_R, S_RSHUT_W, S_RSHUT_RW,
667 S_SHUT2_R, S_SHUT2_W, S_SHUT2_RW, S_PRE_RESET,
668 S_AT_RESET, S_POST_RESET
671 static const int udp_results[][__arraycount(udp_states)] = {
672 [C_ACCEPT] = {
673 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
674 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
675 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
676 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
677 -EOPNOTSUPP, -EOPNOTSUPP,
679 [C_BIND] = {
680 0, 0, 0, 0,
681 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
682 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
683 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
684 -EINVAL, -EINVAL,
686 [C_CONNECT] = {
687 0, 0, 0, 0,
688 0, 0, 0, 0,
689 0, 0, 0, 0,
690 0, 0, 0, 0,
691 0, 0,
693 [C_GETPEERNAME] = {
694 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
695 -ENOTCONN, 0, 0, 0,
696 0, 0, 0, 0,
697 0, 0, 0, 0,
698 0, 0,
700 [C_GETSOCKNAME] = {
701 0, 0, 0, 0,
702 0, 0, 0, 0,
703 0, 0, 0, 0,
704 0, 0, 0, 0,
705 0, 0,
707 [C_GETSOCKOPT_ERR] = {
708 0, 0, 0, 0,
709 0, 0, 0, 0,
710 0, 0, 0, 0,
711 0, 0, 0, 0,
712 0, 0,
714 [C_GETSOCKOPT_KA] = {
715 0, 0, 0, 0,
716 0, 0, 0, 0,
717 0, 0, 0, 0,
718 0, 0, 0, 0,
719 0, 0,
721 [C_GETSOCKOPT_RB] = {
722 0, 0, 0, 0,
723 0, 0, 0, 0,
724 0, 0, 0, 0,
725 0, 0, 0, 0,
726 0, 0,
728 [C_IOCTL_NREAD] = {
729 0, 0, 0, 0,
730 0, 0, 0, 0,
731 0, 0, 0, 0,
732 0, 0, 0, 1,
733 0, 0,
735 [C_LISTEN] = {
736 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
737 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
738 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
739 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
740 -EOPNOTSUPP, -EOPNOTSUPP,
742 [C_RECV] = {
743 -EAGAIN, 0, -EAGAIN, 0,
744 -EAGAIN, -EAGAIN, 0, -EAGAIN,
745 0, -EAGAIN, -EAGAIN, -EAGAIN,
746 0, -EAGAIN, 0, 1,
747 -EAGAIN, -EAGAIN,
749 [C_RECVFROM] = {
750 -EAGAIN, 0, -EAGAIN, 0,
751 -EAGAIN, -EAGAIN, 0, -EAGAIN,
752 0, -EAGAIN, -EAGAIN, -EAGAIN,
753 0, -EAGAIN, 0, 1,
754 -EAGAIN, -EAGAIN,
756 [C_SEND] = {
757 -EDESTADDRREQ, -EDESTADDRREQ, -EPIPE, -EPIPE,
758 -EDESTADDRREQ, 1, 1, -EPIPE,
759 -EPIPE, 1, 1, 1,
760 1, -EPIPE, -EPIPE, 1,
761 1, 1,
763 [C_SENDTO] = {
764 1, 1, -EPIPE, -EPIPE,
765 1, 1, 1, -EPIPE,
766 -EPIPE, 1, 1, 1,
767 1, -EPIPE, -EPIPE, 1,
768 1, 1,
770 [C_SELECT_R] = {
771 0, 1, 0, 1,
772 0, 0, 1, 0,
773 1, 0, 0, 0,
774 1, 0, 1, 1,
775 0, 0,
777 [C_SELECT_W] = {
778 1, 1, 1, 1,
779 1, 1, 1, 1,
780 1, 1, 1, 1,
781 1, 1, 1, 1,
782 1, 1,
784 [C_SELECT_X] = {
785 0, 0, 0, 0,
786 0, 0, 0, 0,
787 0, 0, 0, 0,
788 0, 0, 0, 0,
789 0, 0,
791 [C_SETSOCKOPT_BC] = {
792 0, 0, 0, 0,
793 0, 0, 0, 0,
794 0, 0, 0, 0,
795 0, 0, 0, 0,
796 0, 0,
798 [C_SETSOCKOPT_KA] = {
799 0, 0, 0, 0,
800 0, 0, 0, 0,
801 0, 0, 0, 0,
802 0, 0, 0, 0,
803 0, 0,
805 [C_SETSOCKOPT_L] = {
806 0, 0, 0, 0,
807 0, 0, 0, 0,
808 0, 0, 0, 0,
809 0, 0, 0, 0,
810 0, 0,
812 [C_SETSOCKOPT_RA] = {
813 0, 0, 0, 0,
814 0, 0, 0, 0,
815 0, 0, 0, 0,
816 0, 0, 0, 0,
817 0, 0,
819 [C_SHUTDOWN_R] = {
820 0, 0, 0, 0,
821 0, 0, 0, 0,
822 0, 0, 0, 0,
823 0, 0, 0, 0,
824 0, 0,
826 [C_SHUTDOWN_RW] = {
827 0, 0, 0, 0,
828 0, 0, 0, 0,
829 0, 0, 0, 0,
830 0, 0, 0, 0,
831 0, 0,
833 [C_SHUTDOWN_W] = {
834 0, 0, 0, 0,
835 0, 0, 0, 0,
836 0, 0, 0, 0,
837 0, 0, 0, 0,
838 0, 0,
843 * Set up a UDP socket file descriptor in the requested state and pass it to
844 * socklib_sweep_call() along with local and remote addresses and their length.
846 static int
847 udp_sweep(int domain, int type, int protocol, enum state state, enum call call)
849 struct sockaddr_in sinA, sinB;
850 struct sockaddr_in6 sin6A, sin6B;
851 struct sockaddr *addrA, *addrB;
852 socklen_t addr_len;
853 char buf[1];
854 int r, fd, fd2;
856 if (domain == AF_INET) {
857 memset(&sinA, 0, sizeof(sinA));
858 sinA.sin_family = domain;
859 sinA.sin_port = htons(TEST_PORT_A);
860 sinA.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
862 memcpy(&sinB, &sinA, sizeof(sinB));
863 sinB.sin_port = htons(TEST_PORT_B);
865 addrA = (struct sockaddr *)&sinA;
866 addrB = (struct sockaddr *)&sinB;
867 addr_len = sizeof(sinA);
868 } else {
869 assert(domain == AF_INET6);
871 memset(&sin6A, 0, sizeof(sin6A));
872 sin6A.sin6_family = domain;
873 sin6A.sin6_port = htons(TEST_PORT_A);
874 memcpy(&sin6A.sin6_addr, &in6addr_loopback,
875 sizeof(sin6A.sin6_addr));
877 memcpy(&sin6B, &sin6A, sizeof(sin6B));
878 sin6B.sin6_port = htons(TEST_PORT_B);
880 addrA = (struct sockaddr *)&sin6A;
881 addrB = (struct sockaddr *)&sin6B;
882 addr_len = sizeof(sin6A);
885 /* Create a bound remote socket. */
886 if ((fd2 = socket(domain, type | SOCK_NONBLOCK, protocol)) < 0) e(0);
888 if (bind(fd2, addrB, addr_len) != 0) e(0);
890 switch (state) {
891 case S_NEW:
892 case S_N_SHUT_R:
893 case S_N_SHUT_W:
894 case S_N_SHUT_RW:
895 if ((fd = socket(domain, type | SOCK_NONBLOCK,
896 protocol)) < 0) e(0);
898 switch (state) {
899 case S_N_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
900 case S_N_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
901 case S_N_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
902 default: break;
905 break;
907 case S_BOUND:
908 case S_CONNECTED:
909 case S_SHUT_R:
910 case S_SHUT_W:
911 case S_SHUT_RW:
912 case S_RSHUT_R:
913 case S_RSHUT_W:
914 case S_RSHUT_RW:
915 case S_SHUT2_R:
916 case S_SHUT2_W:
917 case S_SHUT2_RW:
918 case S_PRE_RESET:
919 case S_AT_RESET:
920 case S_POST_RESET:
921 if ((fd = socket(domain, type | SOCK_NONBLOCK,
922 protocol)) < 0) e(0);
924 if (bind(fd, addrA, addr_len) != 0) e(0);
926 if (state == S_BOUND)
927 break;
929 if (connect(fd, addrB, addr_len) != 0) e(0);
931 switch (state) {
932 case S_SHUT_R:
933 case S_SHUT2_R: if (shutdown(fd, SHUT_RD)) e(0); break;
934 case S_SHUT_W:
935 case S_SHUT2_W: if (shutdown(fd, SHUT_WR)) e(0); break;
936 case S_SHUT_RW:
937 case S_SHUT2_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
938 default: break;
941 switch (state) {
942 case S_RSHUT_R:
943 case S_SHUT2_R: if (shutdown(fd2, SHUT_RD)) e(0); break;
944 case S_RSHUT_W:
945 case S_SHUT2_W: if (shutdown(fd2, SHUT_WR)) e(0); break;
946 case S_RSHUT_RW:
947 case S_SHUT2_RW: if (shutdown(fd2, SHUT_RDWR)) e(0); break;
948 case S_PRE_RESET:
949 case S_AT_RESET:
950 case S_POST_RESET:
951 if (sendto(fd2, "", 1, 0, addrA, addr_len) != 1) e(0);
953 if (close(fd2) != 0) e(0);
954 fd2 = -1;
956 if (state != S_PRE_RESET) {
957 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
959 if (state == S_POST_RESET) {
960 (void)recv(fd, buf, sizeof(buf), 0);
962 default:
963 break;
966 break;
968 default:
969 fd = -1;
970 e(0);
973 r = socklib_sweep_call(call, fd, addrA, addrB, addr_len);
975 if (close(fd) != 0) e(0);
976 if (fd2 != -1 && close(fd2) != 0) e(0);
978 return r;
982 * Sweep test for socket calls versus socket states of TCP and UDP sockets.
984 static void
985 test91a(void)
988 subtest = 1;
990 socklib_sweep(AF_INET, SOCK_STREAM, 0, tcp_states,
991 __arraycount(tcp_states), (const int *)tcp_results, tcp_sweep);
993 socklib_sweep(AF_INET6, SOCK_STREAM, 0, tcp_states,
994 __arraycount(tcp_states), (const int *)tcp_results, tcp_sweep);
996 socklib_sweep(AF_INET, SOCK_DGRAM, 0, udp_states,
997 __arraycount(udp_states), (const int *)udp_results, udp_sweep);
999 socklib_sweep(AF_INET6, SOCK_DGRAM, 0, udp_states,
1000 __arraycount(udp_states), (const int *)udp_results, udp_sweep);
1003 #define F_SKIP -1 /* skip this entry */
1004 #define F_NO 0 /* binding or connecting should fail */
1005 #define F_YES 1 /* binding or connecting should succeed */
1006 #define F_DUAL 2 /* always fails on IPV6_V6ONLY sockets */
1007 #define F_ZONE 4 /* binding works only if a scope ID is given */
1008 #define F_UDP 8 /* do not test on TCP sockets */
1009 #define F_BAD 16 /* operations on this address result in EINVAL */
1011 static const struct {
1012 const char *addr;
1013 int may_bind;
1014 int may_connect; /* UDP only */
1015 } addrs_v4[] = {
1016 { "0.0.0.0", F_YES, F_NO },
1017 { "0.0.0.1", F_NO, F_SKIP },
1018 { "127.0.0.1", F_YES, F_YES },
1019 { "127.0.0.255", F_NO, F_YES },
1020 { "127.255.255.255", F_NO, F_YES },
1021 { "172.31.255.254", F_NO, F_SKIP }, /* may be valid.. */
1022 { "224.0.0.0", F_YES | F_UDP, F_SKIP },
1023 { "239.255.255.255", F_YES | F_UDP, F_SKIP },
1024 { "240.0.0.0", F_NO, F_SKIP },
1025 { "255.255.255.255", F_NO, F_SKIP },
1028 static const struct {
1029 const char *addr;
1030 int may_bind;
1031 int may_connect; /* UDP only */
1032 } addrs_v6[] = {
1033 { "::0", F_YES, F_NO },
1034 { "::1", F_YES, F_YES },
1035 { "::2", F_NO, F_YES },
1036 { "::127.0.0.1", F_NO, F_YES },
1037 { "::ffff:7f00:1", F_YES | F_DUAL, F_YES | F_DUAL },
1038 { "::ffff:7f00:ff", F_NO | F_DUAL, F_YES | F_DUAL },
1039 { "100::1", F_NO, F_SKIP },
1040 { "2fff:ffff::", F_NO, F_SKIP },
1041 { "fc00::1", F_NO, F_SKIP },
1042 { "fe00::1", F_NO, F_SKIP },
1043 { "fe80::1", F_YES | F_ZONE, F_YES | F_ZONE },
1044 { "fec0::1", F_NO, F_SKIP },
1045 { "ff01::1", F_YES | F_ZONE | F_UDP, F_YES | F_ZONE },
1046 { "ff02::1", F_YES | F_ZONE | F_UDP, F_YES | F_ZONE },
1047 { "ff02::2", F_YES | F_ZONE | F_UDP, F_YES | F_ZONE },
1048 { "ff0e::1", F_YES | F_UDP, F_SKIP },
1049 { "ffff::1", F_NO | F_UDP | F_BAD, F_NO | F_BAD },
1053 * Test binding sockets of a particular type to various addresses.
1055 static void
1056 sub91b(int type)
1058 struct sockaddr_in sin, lsin;
1059 struct sockaddr_in6 sin6, lsin6;
1060 socklen_t len;
1061 unsigned int i, ifindex;
1062 int r, fd, val;
1064 ifindex = if_nametoindex(LOOPBACK_IFNAME);
1066 /* Test binding IPv4 sockets to IPv4 addresses. */
1067 for (i = 0; i < __arraycount(addrs_v4); i++) {
1068 if (type == SOCK_STREAM && (addrs_v4[i].may_bind & F_UDP))
1069 continue;
1071 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
1073 memset(&sin, 0, sizeof(sin));
1074 sin.sin_family = AF_INET;
1075 if (inet_pton(AF_INET, addrs_v4[i].addr, &sin.sin_addr) != 1)
1076 e(0);
1078 r = bind(fd, (struct sockaddr *)&sin, sizeof(sin));
1079 if (r == -1 && errno != EADDRNOTAVAIL) e(0);
1080 if (r + 1 != !!(addrs_v4[i].may_bind & F_YES)) e(0);
1082 len = sizeof(lsin);
1083 if (getsockname(fd, (struct sockaddr *)&lsin, &len) != 0) e(0);
1084 if (lsin.sin_len != sizeof(lsin)) e(0);
1085 if (lsin.sin_family != AF_INET) e(0);
1086 if (r == 0) {
1087 if (lsin.sin_port == 0) e(0);
1088 if (lsin.sin_addr.s_addr != sin.sin_addr.s_addr) e(0);
1089 } else {
1090 if (lsin.sin_port != 0) e(0);
1091 if (lsin.sin_addr.s_addr != htonl(INADDR_ANY)) e(0);
1094 /* Rebinding never works; binding after a failed bind does. */
1095 sin.sin_addr.s_addr = htonl(INADDR_ANY);
1096 r = bind(fd, (struct sockaddr *)&sin, sizeof(sin));
1097 if (r == -1 && errno != EINVAL) e(0);
1098 if (!!r != !!(addrs_v4[i].may_bind & F_YES)) e(0);
1100 if (close(fd) != 0) e(0);
1103 /* Test binding IPv6 sockets to IPv6 addresses. */
1104 for (i = 0; i < __arraycount(addrs_v6); i++) {
1105 if (type == SOCK_STREAM && (addrs_v6[i].may_bind & F_UDP))
1106 continue;
1108 /* Try without IPV6_V6ONLY. */
1109 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
1111 /* IPV6_V6ONLY may or may not be enabled by default.. */
1112 val = 0;
1113 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1114 sizeof(val)) != 0) e(0);
1116 memset(&sin6, 0, sizeof(sin6));
1117 sin6.sin6_family = AF_INET6;
1118 if (inet_pton(AF_INET6, addrs_v6[i].addr,
1119 &sin6.sin6_addr) != 1) e(0);
1121 if (addrs_v6[i].may_bind & F_ZONE) {
1122 if (bind(fd, (struct sockaddr *)&sin6,
1123 sizeof(sin6)) != -1) e(0);
1124 if (errno != EADDRNOTAVAIL) e(0);
1126 sin6.sin6_scope_id = ifindex;
1129 r = bind(fd, (struct sockaddr *)&sin6, sizeof(sin6));
1130 if (r == -1) {
1131 if (addrs_v6[i].may_bind & F_BAD) {
1132 if (errno != EINVAL) e(0);
1133 } else {
1134 if (errno != EADDRNOTAVAIL) e(0);
1137 if (r + 1 != !!(addrs_v6[i].may_bind & F_YES)) e(0);
1139 len = sizeof(lsin6);
1140 if (getsockname(fd, (struct sockaddr *)&lsin6, &len) != 0)
1141 e(0);
1142 if (lsin6.sin6_len != sizeof(lsin6)) e(0);
1143 if (lsin6.sin6_family != AF_INET6) e(0);
1144 if (r == 0) {
1145 if (lsin6.sin6_port == 0) e(0);
1146 if (memcmp(&lsin6.sin6_addr, &sin6.sin6_addr,
1147 sizeof(lsin6.sin6_addr))) e(0);
1148 if (lsin6.sin6_scope_id !=
1149 ((addrs_v6[i].may_bind & F_ZONE) ? ifindex : 0))
1150 e(0);
1151 } else {
1152 if (lsin6.sin6_port != 0) e(0);
1153 if (!IN6_IS_ADDR_UNSPECIFIED(&lsin6.sin6_addr)) e(0);
1154 if (lsin6.sin6_scope_id != 0) e(0);
1157 if (close(fd) != 0) e(0);
1159 /* Try with IPV6_V6ONLY. */
1160 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
1162 val = 1;
1163 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1164 sizeof(val)) != 0) e(0);
1166 r = bind(fd, (struct sockaddr *)&sin6, sizeof(sin6));
1167 if (r == -1) {
1168 if (addrs_v6[i].may_bind & (F_BAD | F_DUAL)) {
1169 if (errno != EINVAL) e(0);
1170 } else
1171 if (errno != EADDRNOTAVAIL) e(0);
1173 if (r + 1 !=
1174 ((addrs_v6[i].may_bind & (F_YES | F_DUAL)) == F_YES)) e(0);
1176 if (close(fd) != 0) e(0);
1179 /* Test binding an IPv6 socket to an IPv4 address. */
1180 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
1182 memset(&sin, 0, sizeof(sin));
1183 sin.sin_family = AF_INET;
1184 sin.sin_addr.s_addr = htonl(INADDR_ANY);
1186 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1187 if (errno != EINVAL) e(0);
1189 assert(sizeof(sin) <= sizeof(sin6));
1190 memset(&sin6, 0, sizeof(sin6));
1191 memcpy(&sin6, &sin, sizeof(sin));
1192 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != -1) e(0);
1193 if (errno != EAFNOSUPPORT) e(0);
1195 if (close(fd) != 0) e(0);
1197 /* Test binding an IPv4 socket to an IPv6 address. */
1198 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
1200 memset(&sin6, 0, sizeof(sin6));
1201 sin6.sin6_family = AF_INET6;
1202 memcpy(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr));
1204 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != -1) e(0);
1205 if (errno != EINVAL) e(0);
1207 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin)) != -1) e(0);
1208 if (errno != EAFNOSUPPORT) e(0);
1210 if (close(fd) != 0) e(0);
1212 /* Test binding a socket to AF_UNSPEC. */
1213 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
1215 memset(&sin, 0, sizeof(sin));
1216 sin.sin_family = AF_UNSPEC;
1218 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1219 if (errno != EAFNOSUPPORT) e(0);
1221 if (close(fd) != 0) e(0);
1225 * Test binding sockets to various addresses.
1227 static void
1228 test91b(void)
1231 subtest = 2;
1233 sub91b(SOCK_STREAM);
1235 sub91b(SOCK_DGRAM);
1239 * Test connecting TCP sockets to various addresses. We cannot test much here,
1240 * because we do not actually want this test to generate outgoing traffic. In
1241 * effect, we test calls that should fail only.
1243 static void
1244 sub91c_tcp(void)
1246 struct sockaddr_in sin;
1247 struct sockaddr_in6 sin6;
1248 int fd, val;
1251 * Test connecting to address zero (0.0.0.0 and ::0). Apparently the
1252 * traditional BSD behavior for IPv4 is to use the first interface's
1253 * local address as destination instead, but our implementation does
1254 * not support that at this time: these 'any' addresses always result
1255 * in connection failures right away, hopefully eliminating some tricky
1256 * implementation boundary cases.
1258 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
1260 memset(&sin, 0, sizeof(sin));
1261 sin.sin_family = AF_INET;
1262 sin.sin_port = htons(TEST_PORT_A);
1263 sin.sin_addr.s_addr = htonl(INADDR_ANY);
1265 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1266 if (errno != EHOSTUNREACH && errno != ENETUNREACH) e(0);
1268 if (close(fd) != 0) e(0);
1270 if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
1272 memset(&sin6, 0, sizeof(sin6));
1273 sin6.sin6_family = AF_INET6;
1274 sin6.sin6_port = htons(TEST_PORT_A);
1275 memcpy(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr));
1277 if (connect(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != -1) e(0);
1278 if (errno != EHOSTUNREACH && errno != ENETUNREACH) e(0);
1280 if (close(fd) != 0) e(0);
1283 * Test connecting to an IPv6-mapped IPv4 address on an IPv6 socket
1284 * with INET6_V6ONLY enabled.
1286 if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
1288 val = 1;
1289 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
1290 e(0);
1292 memset(&sin6, 0, sizeof(sin6));
1293 sin6.sin6_family = AF_INET6;
1294 sin6.sin6_port = htons(TEST_PORT_A);
1295 if (inet_pton(AF_INET6, "::ffff:"LOOPBACK_IPV4, &sin6.sin6_addr) != 1)
1296 e(0);
1298 if (connect(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != -1) e(0);
1299 if (errno != EINVAL) e(0);
1301 if (close(fd) != 0) e(0);
1303 /* Test connecting to an AF_UNSPEC address. */
1304 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
1306 memset(&sin, 0, sizeof(sin));
1307 sin.sin_family = AF_UNSPEC;
1309 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1310 if (errno != EAFNOSUPPORT) e(0);
1312 if (close(fd) != 0) e(0);
1314 /* Test connecting to port zero. */
1315 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
1317 memset(&sin, 0, sizeof(sin));
1318 sin.sin_family = AF_INET;
1319 sin.sin_port = htons(0);
1320 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1322 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1323 if (errno != EADDRNOTAVAIL) e(0);
1325 if (close(fd) != 0) e(0);
1329 * Test connecting UDP sockets to various addresses.
1331 static void
1332 sub91c_udp(void)
1334 struct sockaddr_in sin, rsin;
1335 struct sockaddr_in6 sin6, rsin6;
1336 socklen_t len;
1337 unsigned int i, ifindex;
1338 int r, fd, val;
1340 ifindex = if_nametoindex(LOOPBACK_IFNAME);
1342 /* Test connecting IPv4 sockets to IPv4 addresses. */
1343 for (i = 0; i < __arraycount(addrs_v4); i++) {
1344 if (addrs_v4[i].may_connect == F_SKIP)
1345 continue;
1347 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
1349 memset(&sin, 0, sizeof(sin));
1350 sin.sin_family = AF_INET;
1351 sin.sin_port = htons(TEST_PORT_A);
1352 if (inet_pton(AF_INET, addrs_v4[i].addr, &sin.sin_addr) != 1)
1353 e(0);
1355 r = connect(fd, (struct sockaddr *)&sin, sizeof(sin));
1356 if (r + 1 != !!(addrs_v4[i].may_connect & F_YES)) e(0);
1358 len = sizeof(rsin);
1359 if (r == 0) {
1360 if (getpeername(fd, (struct sockaddr *)&rsin,
1361 &len) != 0) e(0);
1362 if (rsin.sin_len != sizeof(rsin)) e(0);
1363 if (rsin.sin_family != AF_INET) e(0);
1364 if (rsin.sin_port != htons(TEST_PORT_A)) e(0);
1365 if (rsin.sin_addr.s_addr != sin.sin_addr.s_addr) e(0);
1366 } else {
1367 if (getpeername(fd, (struct sockaddr *)&rsin,
1368 &len) != -1) e(0);
1369 if (errno != ENOTCONN) e(0);
1372 sin.sin_addr.s_addr = htonl(INADDR_ANY);
1373 r = bind(fd, (struct sockaddr *)&sin, sizeof(sin));
1374 if (r == -1 && errno != EINVAL) e(0);
1375 if (r + 1 != !(addrs_v4[i].may_connect & F_YES)) e(0);
1377 if (close(fd) != 0) e(0);
1380 /* Test connecting IPv6 sockets to IPv6 addresses. */
1381 for (i = 0; i < __arraycount(addrs_v6); i++) {
1382 if (addrs_v6[i].may_connect == F_SKIP)
1383 continue;
1385 /* Try without IPV6_V6ONLY. */
1386 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
1388 /* IPV6_V6ONLY may or may not be enabled by default.. */
1389 val = 0;
1390 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1391 sizeof(val)) != 0) e(0);
1393 memset(&sin6, 0, sizeof(sin6));
1394 sin6.sin6_family = AF_INET6;
1395 sin6.sin6_port = htons(TEST_PORT_A);
1396 if (inet_pton(AF_INET6, addrs_v6[i].addr,
1397 &sin6.sin6_addr) != 1) e(0);
1398 sin6.sin6_scope_id = ifindex;
1400 r = connect(fd, (struct sockaddr *)&sin6, sizeof(sin6));
1401 if (r + 1 != !!(addrs_v6[i].may_connect & F_YES)) e(0);
1403 len = sizeof(rsin6);
1404 if (r == 0) {
1405 if (getpeername(fd, (struct sockaddr *)&rsin6,
1406 &len) != 0) e(0);
1407 if (rsin6.sin6_len != sizeof(rsin6)) e(0);
1408 if (rsin6.sin6_family != AF_INET6) e(0);
1409 if (rsin6.sin6_port != htons(TEST_PORT_A)) e(0);
1410 if (memcmp(&rsin6.sin6_addr, &sin6.sin6_addr,
1411 sizeof(rsin6.sin6_addr))) e(0);
1412 if (rsin6.sin6_scope_id !=
1413 ((addrs_v6[i].may_connect & F_ZONE) ? ifindex : 0))
1414 e(0);
1415 } else {
1416 if (getpeername(fd, (struct sockaddr *)&rsin,
1417 &len) != -1) e(0);
1418 if (errno != ENOTCONN) e(0);
1421 if (close(fd) != 0) e(0);
1423 /* Try with IPV6_V6ONLY. */
1424 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
1426 val = 1;
1427 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1428 sizeof(val)) != 0) e(0);
1430 r = connect(fd, (struct sockaddr *)&sin6, sizeof(sin6));
1431 if (r == -1 && errno != EINVAL && errno != EHOSTUNREACH) e(0);
1432 if (r + 1 !=
1433 ((addrs_v6[i].may_connect & (F_YES | F_DUAL)) == F_YES))
1434 e(0);
1436 if (close(fd) != 0) e(0);
1439 /* Test connecting an IPv6 socket to an IPv4 address. */
1440 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
1442 memset(&sin, 0, sizeof(sin));
1443 sin.sin_family = AF_INET;
1444 sin.sin_port = htons(TEST_PORT_A);
1445 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1447 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1448 if (errno != EINVAL) e(0);
1450 assert(sizeof(sin) <= sizeof(sin6));
1451 memset(&sin6, 0, sizeof(sin6));
1452 memcpy(&sin6, &sin, sizeof(sin));
1453 if (connect(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != -1) e(0);
1454 if (errno != EAFNOSUPPORT) e(0);
1456 if (close(fd) != 0) e(0);
1458 /* Test connecting an IPv4 socket to an IPv6 address. */
1459 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
1461 memset(&sin6, 0, sizeof(sin6));
1462 sin6.sin6_family = AF_INET6;
1463 memcpy(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr));
1465 if (connect(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != -1) e(0);
1466 if (errno != EINVAL) e(0);
1468 if (connect(fd, (struct sockaddr *)&sin6, sizeof(sin)) != -1) e(0);
1469 if (errno != EAFNOSUPPORT) e(0);
1471 if (close(fd) != 0) e(0);
1473 /* Test unconnecting a socket using AF_UNSPEC. */
1474 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
1476 memset(&sin, 0, sizeof(sin));
1477 sin.sin_family = AF_INET;
1478 sin.sin_port = htons(TEST_PORT_A);
1479 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1481 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
1483 memset(&sin, 0, sizeof(sin));
1484 sin.sin_family = AF_UNSPEC;
1486 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
1488 len = sizeof(rsin);
1489 if (getpeername(fd, (struct sockaddr *)&rsin, &len) != -1) e(0);
1490 if (errno != ENOTCONN) e(0);
1492 if (close(fd) != 0) e(0);
1494 /* Test connecting to port zero. */
1495 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
1497 memset(&sin, 0, sizeof(sin));
1498 sin.sin_family = AF_INET;
1499 sin.sin_port = htons(0);
1500 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1502 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1503 if (errno != EADDRNOTAVAIL) e(0);
1505 if (close(fd) != 0) e(0);
1509 * Test connecting sockets to various addresses.
1511 static void
1512 test91c(void)
1515 subtest = 3;
1517 sub91c_tcp();
1519 sub91c_udp();
1523 * Test binding with IPv4/IPv6 on the same port for the given socket type.
1525 static void
1526 sub91d(int type)
1528 struct sockaddr_in sin;
1529 struct sockaddr_in6 sin6;
1530 int r, fd, fd2, val;
1532 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
1534 memset(&sin, 0, sizeof(sin));
1535 sin.sin_family = AF_INET;
1536 sin.sin_port = htons(TEST_PORT_A);
1537 sin.sin_addr.s_addr = htonl(INADDR_ANY);
1539 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
1541 /* IPv4 bound; IPv6 bind without IPV6_V6ONLY may or may not work. */
1542 if ((fd2 = socket(AF_INET6, type, 0)) < 0) e(0);
1544 val = 0;
1545 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
1546 e(0);
1548 memset(&sin6, 0, sizeof(sin6));
1549 sin6.sin6_family = AF_INET6;
1550 sin6.sin6_port = htons(TEST_PORT_A);
1551 memcpy(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr));
1553 r = bind(fd2, (struct sockaddr *)&sin6, sizeof(sin6));
1554 if (r == -1 && errno != EADDRINUSE) e(0);
1556 if (close(fd2) != 0) e(0);
1558 /* IPv4 bound; IPv6 bind with IPV6_V6ONLY should work. */
1559 if ((fd2 = socket(AF_INET6, type, 0)) < 0) e(0);
1561 val = 1;
1562 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != 0)
1563 e(0);
1564 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
1565 e(0);
1567 memset(&sin6, 0, sizeof(sin6));
1568 sin6.sin6_family = AF_INET6;
1569 sin6.sin6_port = htons(TEST_PORT_A);
1570 memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
1572 if (bind(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
1574 if (close(fd2) != 0) e(0);
1575 if (close(fd) != 0) e(0);
1577 /* IPv6 bound with IPV6_V6ONLY; IPv4 bind may or may not work. */
1578 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
1580 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != 0)
1581 e(0);
1582 val = 0;
1583 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
1584 e(0);
1586 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
1588 if ((fd2 = socket(AF_INET, type, 0)) < 0) e(0);
1590 r = bind(fd2, (struct sockaddr *)&sin, sizeof(sin));
1591 if (r == -1 && errno != EADDRINUSE) e(0);
1593 if (close(fd2) != 0) e(0);
1594 if (close(fd) != 0) e(0);
1596 /* IPv6 bound with IPV6_V6ONLY; IPv4 bind should work. */
1597 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
1599 val = 1;
1600 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != 0)
1601 e(0);
1602 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
1603 e(0);
1605 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
1607 if ((fd2 = socket(AF_INET, type, 0)) < 0) e(0);
1609 if (bind(fd2, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
1611 if (close(fd2) != 0) e(0);
1612 if (close(fd) != 0) e(0);
1616 * Test binding with IPv4/IPv6 on the same port, and IPV6_V6ONLY.
1618 static void
1619 test91d(void)
1622 subtest = 4;
1624 sub91d(SOCK_STREAM);
1626 sub91d(SOCK_DGRAM);
1630 * Test sending large and small UDP packets.
1632 static void
1633 test91e(void)
1635 struct sockaddr_in sin;
1636 struct msghdr msg;
1637 struct iovec iov;
1638 char *buf;
1639 unsigned int i, j;
1640 int r, fd, fd2, val;
1642 subtest = 5;
1644 if ((buf = malloc(65536)) == NULL) e(0);
1646 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
1648 memset(&sin, 0, sizeof(sin));
1649 sin.sin_family = AF_INET;
1650 sin.sin_port = htons(TEST_PORT_A);
1651 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1653 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
1655 val = 65536;
1656 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
1657 e(0);
1659 if ((fd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
1662 * A maximum send buffer size of a full packet size's worth may always
1663 * be set, although this is not necessarily the actual maximum.
1665 val = 65535;
1666 if (setsockopt(fd2, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0)
1667 e(0);
1669 /* Find the largest possible packet size that can actually be sent. */
1670 for (i = 0; i < val; i += sizeof(int)) {
1671 j = i ^ 0xdeadbeef;
1672 memcpy(&buf[i], &j, sizeof(j));
1675 for (val = 65536; val > 0; val--) {
1676 if ((r = sendto(fd2, buf, val, 0, (struct sockaddr *)&sin,
1677 sizeof(sin))) == val)
1678 break;
1679 if (r != -1) e(0);
1680 if (errno != EMSGSIZE) e(0);
1683 if (val != 65535 - sizeof(struct udphdr) - sizeof(struct ip)) e(0);
1685 memset(buf, 0, val);
1686 buf[val] = 'X';
1688 memset(&iov, 0, sizeof(iov));
1689 iov.iov_base = buf;
1690 iov.iov_len = val + 1;
1691 memset(&msg, 0, sizeof(msg));
1692 msg.msg_iov = &iov;
1693 msg.msg_iovlen = 1;
1694 if (recvmsg(fd, &msg, 0) != val) e(0);
1695 if (msg.msg_flags != 0) e(0);
1697 for (i = 0; i < val; i += sizeof(int)) {
1698 j = i ^ 0xdeadbeef;
1699 if (memcmp(&buf[i], &j, MIN(sizeof(j), val - i))) e(0);
1701 if (buf[val] != 'X') e(0);
1703 if (sendto(fd2, buf, val, 0, (struct sockaddr *)&sin, sizeof(sin)) !=
1704 val) e(0);
1707 * Make sure that there are no off-by-one errors in the receive code,
1708 * and that MSG_TRUNC is set (only) when not the whole packet was
1709 * received.
1711 memset(&iov, 0, sizeof(iov));
1712 iov.iov_base = buf;
1713 iov.iov_len = val;
1714 memset(&msg, 0, sizeof(msg));
1715 msg.msg_iov = &iov;
1716 msg.msg_iovlen = 1;
1717 if (recvmsg(fd, &msg, 0) != val) e(0);
1718 if (msg.msg_flags != 0) e(0);
1720 if (sendto(fd2, buf, val, 0, (struct sockaddr *)&sin, sizeof(sin)) !=
1721 val) e(0);
1723 buf[val - 1] = 'Y';
1725 memset(&iov, 0, sizeof(iov));
1726 iov.iov_base = buf;
1727 iov.iov_len = val - 1;
1728 memset(&msg, 0, sizeof(msg));
1729 msg.msg_iov = &iov;
1730 msg.msg_iovlen = 1;
1731 if (recvmsg(fd, &msg, 0) != val - 1) e(0);
1732 if (msg.msg_flags != MSG_TRUNC) e(0);
1734 for (i = 0; i < val - 1; i += sizeof(int)) {
1735 j = i ^ 0xdeadbeef;
1736 if (memcmp(&buf[i], &j, MIN(sizeof(j), val - 1 - i))) e(0);
1738 if (buf[val - 1] != 'Y') e(0);
1740 if (sendto(fd2, buf, val, 0, (struct sockaddr *)&sin, sizeof(sin)) !=
1741 val) e(0);
1743 buf[0] = 'Z';
1745 memset(&iov, 0, sizeof(iov));
1746 iov.iov_base = buf;
1747 iov.iov_len = 0;
1748 memset(&msg, 0, sizeof(msg));
1749 msg.msg_iov = &iov;
1750 msg.msg_iovlen = 1;
1751 if (recvmsg(fd, &msg, 0) != 0) e(0);
1752 if (msg.msg_flags != MSG_TRUNC) e(0);
1753 if (buf[0] != 'Z') e(0);
1755 /* Make sure that zero-sized packets can be sent and received. */
1756 if (sendto(fd2, buf, 0, 0, (struct sockaddr *)&sin, sizeof(sin)) != 0)
1757 e(0);
1760 * Note how we currently assume that packets sent over localhost will
1761 * arrive immediately, so that we can use MSG_DONTWAIT to avoid that
1762 * the test freezes.
1764 memset(&msg, 0, sizeof(msg));
1765 msg.msg_iov = &iov;
1766 msg.msg_iovlen = 1;
1767 if (recvmsg(fd, &msg, MSG_DONTWAIT) != 0) e(0);
1768 if (msg.msg_flags != 0) e(0);
1769 if (buf[0] != 'Z') e(0);
1771 if (recv(fd, buf, val, MSG_DONTWAIT) != -1) e(0);
1772 if (errno != EWOULDBLOCK) e(0);
1775 * When sending lots of small packets, ensure that fewer packets arrive
1776 * than we sent. This sounds weird, but we cannot actually check the
1777 * internal TCP/IP buffer granularity and yet we want to make sure that
1778 * the receive queue is measured in terms of buffers rather than packet
1779 * sizes. In addition, we check that older packets are favored,
1780 * instead discarding new ones when the receive buffer is full.
1782 for (i = 0; i < 65536 / sizeof(j); i++) {
1783 j = i;
1784 if (sendto(fd2, &j, sizeof(j), 0, (struct sockaddr *)&sin,
1785 sizeof(sin)) != sizeof(j)) e(0);
1788 for (i = 0; i < 1025; i++) {
1789 r = recv(fd, &j, sizeof(j), MSG_DONTWAIT);
1790 if (r == -1) {
1791 if (errno != EWOULDBLOCK) e(0);
1792 break;
1794 if (r != sizeof(j)) e(0);
1795 if (i != j) e(0);
1797 if (i == 1025) e(0);
1799 if (close(fd2) != 0) e(0);
1800 if (close(fd) != 0) e(0);
1802 free(buf);
1806 * Test setting and retrieving IP-level options for the given socket type. For
1807 * TCP sockets, we cannot test whether they are actually applied, but for UDP
1808 * sockets, we do a more complete test later on.
1810 static void
1811 sub91f(int type)
1813 socklen_t len;
1814 int fd, val, def;
1816 /* Test IPv4 first. */
1817 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
1819 /* Test obtaining the default TOS and TTL values. */
1820 len = sizeof(val);
1821 if (getsockopt(fd, IPPROTO_IP, IP_TOS, &val, &len) != 0) e(0);
1822 if (len != sizeof(val)) e(0);
1823 if (val != 0) e(0);
1825 len = sizeof(def);
1826 if (getsockopt(fd, IPPROTO_IP, IP_TTL, &def, &len) != 0) e(0);
1827 if (len != sizeof(def)) e(0);
1828 if (def < 16 || def > UINT8_MAX) e(0);
1830 /* Test changing the TOS field. */
1831 for (val = 0; val <= UINT8_MAX; val++)
1832 if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof(val)) != 0)
1833 e(0);
1834 val = -1; /* not a special value for IPv4 */
1835 if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof(val)) != -1) e(0);
1836 if (errno != EINVAL) e(0);
1837 val = UINT8_MAX + 1;
1838 if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof(val)) != -1) e(0);
1839 if (errno != EINVAL) e(0);
1841 len = sizeof(val);
1842 if (getsockopt(fd, IPPROTO_IP, IP_TOS, &val, &len) != 0) e(0);
1843 if (len != sizeof(val)) e(0);
1844 if (val != UINT8_MAX) e(0);
1846 /* Test changing the TTL field. */
1847 for (val = 0; val <= UINT8_MAX; val++)
1848 if (setsockopt(fd, IPPROTO_IP, IP_TTL, &val, sizeof(val)) != 0)
1849 e(0);
1850 val = 39;
1851 if (setsockopt(fd, IPPROTO_IP, IP_TTL, &val, sizeof(val)) != 0) e(0);
1852 val = -1; /* not a special value for IPv4 */
1853 if (setsockopt(fd, IPPROTO_IP, IP_TTL, &val, sizeof(val)) != -1) e(0);
1854 if (errno != EINVAL) e(0);
1855 val = UINT8_MAX + 1;
1856 if (setsockopt(fd, IPPROTO_IP, IP_TTL, &val, sizeof(val)) != -1) e(0);
1857 if (errno != EINVAL) e(0);
1859 len = sizeof(val);
1860 if (getsockopt(fd, IPPROTO_IP, IP_TTL, &val, &len) != 0) e(0);
1861 if (len != sizeof(val)) e(0);
1862 if (val != 39) e(0);
1864 /* It must not be possible to set IPv6 options on IPv4 sockets. */
1865 val = 0;
1866 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) != -1)
1867 e(0);
1868 if (errno != ENOPROTOOPT) e(0);
1869 if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
1870 sizeof(val)) != -1) e(0);
1871 if (errno != ENOPROTOOPT) e(0);
1873 len = sizeof(val);
1874 if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, &len) != -1) e(0);
1875 if (errno != ENOPROTOOPT) e(0);
1876 if (getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val, &len) != -1)
1877 e(0);
1878 if (errno != ENOPROTOOPT) e(0);
1880 if (close(fd) != 0) e(0);
1882 /* Test IPv6 next. */
1883 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
1885 /* Test obtaining the default TCLASS and HOPS values. */
1886 len = sizeof(val);
1887 if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, &len) != 0) e(0);
1888 if (len != sizeof(val)) e(0);
1889 if (val != 0) e(0);
1891 len = sizeof(def);
1892 if (getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &def, &len) != 0)
1893 e(0);
1894 if (len != sizeof(def)) e(0);
1895 if (def < 16 || def > UINT8_MAX) e(0);
1897 /* Test changing the TCLASS field. */
1898 for (val = 0; val <= UINT8_MAX; val++)
1899 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val,
1900 sizeof(val)) != 0) e(0);
1901 val = -2;
1902 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) != -1)
1903 e(0);
1904 if (errno != EINVAL) e(0);
1905 val = UINT8_MAX + 1;
1906 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) != -1)
1907 e(0);
1908 if (errno != EINVAL) e(0);
1910 len = sizeof(val);
1911 if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, &len) != 0) e(0);
1912 if (len != sizeof(val)) e(0);
1913 if (val != UINT8_MAX) e(0);
1915 val = -1; /* reset to default */
1916 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) != 0)
1917 e(0);
1919 len = sizeof(val);
1920 if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, &len) != 0) e(0);
1921 if (len != sizeof(val)) e(0);
1922 if (val != 0) e(0);
1924 /* Test changing the HOPS field. */
1925 for (val = 0; val <= UINT8_MAX; val++)
1926 if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
1927 sizeof(val)) != 0) e(0);
1928 val = 49;
1929 if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
1930 sizeof(val)) != 0) e(0);
1931 val = -2;
1932 if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
1933 sizeof(val)) != -1) e(0);
1934 if (errno != EINVAL) e(0);
1935 val = UINT8_MAX + 1;
1936 if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
1937 sizeof(val)) != -1) e(0);
1938 if (errno != EINVAL) e(0);
1940 len = sizeof(val);
1941 if (getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val, &len) != 0)
1942 e(0);
1943 if (len != sizeof(val)) e(0);
1944 if (val != 49) e(0);
1946 val = -1; /* reset to default */
1947 if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
1948 sizeof(val)) != 0) e(0);
1950 len = sizeof(val);
1951 if (getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val, &len) != 0)
1952 e(0);
1953 if (len != sizeof(val)) e(0);
1954 if (val != def) e(0);
1956 /* It must not be possible to set IPv4 options on IPv6 sockets. */
1957 val = 0;
1958 if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof(val)) != -1) e(0);
1959 if (errno != ENOPROTOOPT) e(0);
1960 if (setsockopt(fd, IPPROTO_IP, IP_TTL, &val, sizeof(val)) != -1) e(0);
1961 if (errno != ENOPROTOOPT) e(0);
1963 len = sizeof(val);
1964 if (getsockopt(fd, IPPROTO_IP, IP_TOS, &val, &len) != -1) e(0);
1965 if (errno != ENOPROTOOPT) e(0);
1966 if (getsockopt(fd, IPPROTO_IP, IP_TTL, &val, &len) != -1) e(0);
1967 if (errno != ENOPROTOOPT) e(0);
1969 if (close(fd) != 0) e(0);
1973 * Test setting and retrieving IP-level options.
1975 static void
1976 test91f(void)
1979 subtest = 6;
1981 sub91f(SOCK_STREAM);
1983 sub91f(SOCK_DGRAM);
1987 * Test setting and retrieving IP-level options on UDP sockets and packets.
1988 * As part of this, ensure that the maximum set of supported control options
1989 * can be both sent and received, both for IPv4 and IPv6. Any options that are
1990 * newly added to the service and may be combined with the existing ones should
1991 * be added to this subtest as well. The control data handling code is shared
1992 * between UDP and RAW, so there is no need to repeat this test for the latter.
1994 static void
1995 test91g(void)
1997 struct sockaddr_in6 sin6;
1998 struct sockaddr_in sin;
1999 struct iovec iov;
2000 struct msghdr msg;
2001 struct cmsghdr *cmsg, cmsg2;
2002 struct in_pktinfo ipi;
2003 struct in6_pktinfo ipi6;
2004 unsigned int ifindex;
2005 char buf[1];
2006 union {
2007 struct cmsghdr cmsg;
2008 char buf[256];
2009 } control;
2010 uint8_t byte;
2011 size_t size;
2012 int fd, fd2, val, seen_tos, seen_ttl, seen_pktinfo;
2014 subtest = 7;
2016 ifindex = if_nametoindex(LOOPBACK_IFNAME);
2017 if (ifindex == 0) e(0);
2019 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
2021 memset(&sin, 0, sizeof(sin));
2022 sin.sin_family = AF_INET;
2023 sin.sin_port = htons(TEST_PORT_A);
2024 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2026 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
2028 val = 1;
2029 /* Strangely, IP_RECVTOS is not a thing.. */
2030 if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &val, sizeof(val)) != 0)
2031 e(0);
2032 if (setsockopt(fd, IPPROTO_IP, IP_RECVPKTINFO, &val, sizeof(val)) != 0)
2033 e(0);
2035 if ((fd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
2037 iov.iov_base = "A";
2038 iov.iov_len = 1;
2040 val = 39;
2041 control.cmsg.cmsg_len = CMSG_LEN(sizeof(val));
2042 control.cmsg.cmsg_level = IPPROTO_IP;
2043 control.cmsg.cmsg_type = IP_TTL;
2044 memcpy(CMSG_DATA(&control.cmsg), &val, sizeof(val));
2046 memset(&msg, 0, sizeof(msg));
2047 msg.msg_name = (struct sockaddr *)&sin;
2048 msg.msg_namelen = sizeof(sin);
2049 msg.msg_iov = &iov;
2050 msg.msg_iovlen = 1;
2051 msg.msg_control = control.buf;
2052 msg.msg_controllen = control.cmsg.cmsg_len;
2054 if (sendmsg(fd2, &msg, 0) != 1) e(0);
2056 iov.iov_base = buf;
2057 iov.iov_len = sizeof(buf);
2059 memset(&msg, 0, sizeof(msg));
2060 msg.msg_iov = &iov;
2061 msg.msg_iovlen = 1;
2062 msg.msg_control = control.buf;
2063 msg.msg_controllen = sizeof(control);
2065 if (recvmsg(fd, &msg, 0) != 1) e(0);
2066 if (buf[0] != 'A') e(0);
2068 seen_ttl = seen_pktinfo = 0;
2069 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
2070 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
2071 if (cmsg->cmsg_level != IPPROTO_IP) e(0);
2072 switch (cmsg->cmsg_type) {
2073 case IP_TTL:
2074 /* The odd one out, using a uint8_t.. */
2075 if (seen_ttl++) e(0);
2076 if (cmsg->cmsg_len != CMSG_LEN(sizeof(byte))) e(0);
2077 memcpy(&byte, CMSG_DATA(cmsg), sizeof(byte));
2078 if (byte != 39) e(0);
2079 break;
2080 case IP_PKTINFO:
2081 if (seen_pktinfo++) e(0);
2082 if (cmsg->cmsg_len != CMSG_LEN(sizeof(ipi))) e(0);
2083 memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi));
2084 if (ipi.ipi_addr.s_addr != sin.sin_addr.s_addr) e(0);
2085 if (ipi.ipi_ifindex != ifindex) e(0);
2086 break;
2087 default:
2088 e(0);
2091 if (!seen_ttl) e(0);
2092 if (!seen_pktinfo) e(0);
2094 /* Test that we can provide all supported IPv4 options at once. */
2095 iov.iov_base = "B";
2096 iov.iov_len = 1;
2098 val = 1;
2099 control.cmsg.cmsg_len = CMSG_LEN(sizeof(val));
2100 control.cmsg.cmsg_level = IPPROTO_IP;
2101 control.cmsg.cmsg_type = IP_TOS;
2102 memcpy(CMSG_DATA(&control.cmsg), &val, sizeof(val));
2104 size = CMSG_SPACE(sizeof(val));
2106 if ((cmsg = CMSG_NXTHDR(&msg, &control.cmsg)) == NULL) e(0);
2107 val = 41;
2108 cmsg2.cmsg_len = CMSG_LEN(sizeof(val));
2109 cmsg2.cmsg_level = IPPROTO_IP;
2110 cmsg2.cmsg_type = IP_TTL;
2111 memcpy(cmsg, &cmsg2, sizeof(cmsg2));
2112 memcpy(CMSG_DATA(cmsg), &val, sizeof(val));
2114 size += CMSG_SPACE(sizeof(val));
2116 memset(&msg, 0, sizeof(msg));
2117 msg.msg_name = (struct sockaddr *)&sin;
2118 msg.msg_namelen = sizeof(sin);
2119 msg.msg_iov = &iov;
2120 msg.msg_iovlen = 1;
2121 msg.msg_control = control.buf;
2122 msg.msg_controllen = size;
2124 if (sendmsg(fd2, &msg, 0) != 1) e(0);
2126 iov.iov_base = buf;
2127 iov.iov_len = sizeof(buf);
2129 memset(&msg, 0, sizeof(msg));
2130 msg.msg_iov = &iov;
2131 msg.msg_iovlen = 1;
2132 msg.msg_control = control.buf;
2133 msg.msg_controllen = sizeof(control);
2135 if (recvmsg(fd, &msg, 0) != 1) e(0);
2136 if (buf[0] != 'B') e(0);
2138 /* Check just the TTL this time. */
2139 seen_ttl = 0;
2140 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
2141 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
2142 if (cmsg->cmsg_level != IPPROTO_IP) e(0);
2143 if (cmsg->cmsg_type == IP_TTL) {
2144 /* The odd one out, using a uint8_t.. */
2145 if (seen_ttl++) e(0);
2146 if (cmsg->cmsg_len != CMSG_LEN(sizeof(byte))) e(0);
2147 memcpy(&byte, CMSG_DATA(cmsg), sizeof(byte));
2148 if (byte != 41) e(0);
2151 if (!seen_ttl) e(0);
2153 if (close(fd2) != 0) e(0);
2154 if (close(fd) != 0) e(0);
2156 /* That was IPv4, onto IPv6.. */
2157 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
2159 memset(&sin6, 0, sizeof(sin6));
2160 sin6.sin6_family = AF_INET6;
2161 sin6.sin6_port = htons(TEST_PORT_A);
2162 memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
2164 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
2166 val = 1;
2167 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, &val,
2168 sizeof(val)) != 0) e(0);
2169 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val,
2170 sizeof(val)) != 0) e(0);
2171 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val,
2172 sizeof(val)) != 0) e(0);
2174 if ((fd2 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
2176 val = 94;
2177 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) != 0)
2178 e(0);
2180 iov.iov_base = "C";
2181 iov.iov_len = 1;
2183 val = 39;
2184 control.cmsg.cmsg_len = CMSG_LEN(sizeof(val));
2185 control.cmsg.cmsg_level = IPPROTO_IPV6;
2186 control.cmsg.cmsg_type = IPV6_HOPLIMIT;
2187 memcpy(CMSG_DATA(&control.cmsg), &val, sizeof(val));
2189 memset(&msg, 0, sizeof(msg));
2190 msg.msg_name = (struct sockaddr *)&sin6;
2191 msg.msg_namelen = sizeof(sin6);
2192 msg.msg_iov = &iov;
2193 msg.msg_iovlen = 1;
2194 msg.msg_control = control.buf;
2195 msg.msg_controllen = control.cmsg.cmsg_len;
2197 if (sendmsg(fd2, &msg, 0) != 1) e(0);
2199 iov.iov_base = buf;
2200 iov.iov_len = sizeof(buf);
2202 memset(&msg, 0, sizeof(msg));
2203 msg.msg_iov = &iov;
2204 msg.msg_iovlen = 1;
2205 msg.msg_control = control.buf;
2206 msg.msg_controllen = sizeof(control);
2208 if (recvmsg(fd, &msg, 0) != 1) e(0);
2209 if (buf[0] != 'C') e(0);
2211 seen_tos = seen_ttl = seen_pktinfo = 0;
2212 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
2213 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
2214 if (cmsg->cmsg_level != IPPROTO_IPV6) e(0);
2215 switch (cmsg->cmsg_type) {
2216 case IPV6_TCLASS:
2217 if (seen_tos++) e(0);
2218 if (cmsg->cmsg_len != CMSG_LEN(sizeof(val))) e(0);
2219 memcpy(&val, CMSG_DATA(cmsg), sizeof(val));
2220 if (val != 94) e(0);
2221 break;
2222 case IPV6_HOPLIMIT:
2223 if (seen_ttl++) e(0);
2224 if (cmsg->cmsg_len != CMSG_LEN(sizeof(val))) e(0);
2225 memcpy(&val, CMSG_DATA(cmsg), sizeof(val));
2226 if (val != 39) e(0);
2227 break;
2228 case IPV6_PKTINFO:
2229 if (seen_pktinfo++) e(0);
2230 if (cmsg->cmsg_len != CMSG_LEN(sizeof(ipi6))) e(0);
2231 memcpy(&ipi6, CMSG_DATA(cmsg), sizeof(ipi6));
2232 if (memcmp(&ipi6.ipi6_addr, &in6addr_loopback,
2233 sizeof(ipi6.ipi6_addr))) e(0);
2234 if (ipi6.ipi6_ifindex != ifindex) e(0);
2235 break;
2236 default:
2237 e(0);
2240 if (!seen_tos) e(0);
2241 if (!seen_ttl) e(0);
2242 if (!seen_pktinfo) e(0);
2245 * Test that (for IPv6) an option of -1 overrides setsockopt.
2246 * Also test that we can provide all supported IPv6 options at once.
2248 val = 0;
2249 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val,
2250 sizeof(val)) != 0) e(0);
2252 iov.iov_base = "D";
2253 iov.iov_len = 1;
2255 memset(&msg, 0, sizeof(msg));
2256 msg.msg_control = control.buf;
2257 msg.msg_controllen = sizeof(control.buf);
2259 val = -1;
2260 control.cmsg.cmsg_len = CMSG_LEN(sizeof(val));
2261 control.cmsg.cmsg_level = IPPROTO_IPV6;
2262 control.cmsg.cmsg_type = IPV6_TCLASS;
2263 memcpy(CMSG_DATA(&control.cmsg), &val, sizeof(val));
2265 size = CMSG_SPACE(sizeof(val));
2267 if ((cmsg = CMSG_NXTHDR(&msg, &control.cmsg)) == NULL) e(0);
2268 val = 78;
2269 cmsg2.cmsg_len = CMSG_LEN(sizeof(val));
2270 cmsg2.cmsg_level = IPPROTO_IPV6;
2271 cmsg2.cmsg_type = IPV6_HOPLIMIT;
2272 memcpy(cmsg, &cmsg2, sizeof(cmsg2));
2273 memcpy(CMSG_DATA(cmsg), &val, sizeof(val));
2275 size += CMSG_SPACE(sizeof(val));
2277 if ((cmsg = CMSG_NXTHDR(&msg, cmsg)) == NULL) e(0);
2278 cmsg2.cmsg_len = CMSG_LEN(sizeof(ipi6));
2279 cmsg2.cmsg_level = IPPROTO_IPV6;
2280 cmsg2.cmsg_type = IPV6_PKTINFO;
2281 memcpy(cmsg, &cmsg2, sizeof(cmsg2));
2282 memset(&ipi6, 0, sizeof(ipi6));
2283 memcpy(CMSG_DATA(cmsg), &ipi6, sizeof(ipi6));
2285 size += CMSG_SPACE(sizeof(ipi6));
2287 if (size > sizeof(control.buf)) e(0);
2289 memset(&msg, 0, sizeof(msg));
2290 msg.msg_name = (struct sockaddr *)&sin6;
2291 msg.msg_namelen = sizeof(sin6);
2292 msg.msg_iov = &iov;
2293 msg.msg_iovlen = 1;
2294 msg.msg_control = control.buf;
2295 msg.msg_controllen = size;
2297 if (sendmsg(fd2, &msg, 0) != 1) e(0);
2299 iov.iov_base = buf;
2300 iov.iov_len = sizeof(buf);
2302 memset(&msg, 0, sizeof(msg));
2303 msg.msg_iov = &iov;
2304 msg.msg_iovlen = 1;
2305 msg.msg_control = control.buf;
2306 msg.msg_controllen = sizeof(control);
2308 if (recvmsg(fd, &msg, 0) != 1) e(0);
2309 if (buf[0] != 'D') e(0);
2311 seen_tos = seen_ttl = 0;
2312 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
2313 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
2314 if (cmsg->cmsg_level != IPPROTO_IPV6) e(0);
2315 switch (cmsg->cmsg_type) {
2316 case IPV6_TCLASS:
2317 if (seen_tos++) e(0);
2318 if (cmsg->cmsg_len != CMSG_LEN(sizeof(val))) e(0);
2319 memcpy(&val, CMSG_DATA(cmsg), sizeof(val));
2320 if (val != 0) e(0);
2321 break;
2322 case IPV6_HOPLIMIT:
2323 if (seen_ttl++) e(0);
2324 if (cmsg->cmsg_len != CMSG_LEN(sizeof(val))) e(0);
2325 memcpy(&val, CMSG_DATA(cmsg), sizeof(val));
2326 if (val != 78) e(0);
2327 break;
2328 default:
2329 e(0);
2332 if (!seen_tos) e(0);
2333 if (!seen_ttl) e(0);
2335 if (close(fd2) != 0) e(0);
2336 if (close(fd) != 0) e(0);
2340 * Test receiving IPv4 packets on IPv6 sockets.
2342 static void
2343 test91h(void)
2345 struct sockaddr_in6 sin6;
2346 struct sockaddr_in sin;
2347 struct iovec iov;
2348 struct msghdr msg;
2349 struct cmsghdr *cmsg;
2350 struct in6_pktinfo ipi6;
2351 unsigned int ifindex;
2352 char buf[1], buf2[256];
2353 int fd, fd2, val;
2355 subtest = 8;
2357 ifindex = if_nametoindex(LOOPBACK_IFNAME);
2358 if (ifindex == 0) e(0);
2360 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
2362 val = 0;
2363 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
2364 e(0);
2366 val = 1;
2367 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val,
2368 sizeof(val)) != 0) e(0);
2370 memset(&sin6, 0, sizeof(sin6));
2371 sin6.sin6_family = AF_INET6;
2372 sin6.sin6_port = htons(TEST_PORT_A);
2374 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
2376 if ((fd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
2378 memset(&sin, 0, sizeof(sin));
2379 sin.sin_family = AF_INET;
2380 sin.sin_port = htons(TEST_PORT_A);
2381 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2383 if (sendto(fd2, "A", 1, 0, (struct sockaddr *)&sin, sizeof(sin)) != 1)
2384 e(0);
2386 iov.iov_base = buf;
2387 iov.iov_len = sizeof(buf);
2389 memset(&msg, 0, sizeof(msg));
2390 msg.msg_name = (struct sockaddr *)&sin6;
2391 msg.msg_namelen = sizeof(sin6);
2392 msg.msg_iov = &iov;
2393 msg.msg_iovlen = 1;
2394 msg.msg_control = buf2;
2395 msg.msg_controllen = sizeof(buf2);
2397 if (recvmsg(fd, &msg, 0) != 1) e(0);
2398 if (buf[0] != 'A') e(0);
2400 if (msg.msg_namelen != sizeof(sin6)) e(0);
2401 if (sin6.sin6_family != AF_INET6) e(0);
2402 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
2403 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
2404 e(0);
2406 if ((cmsg = CMSG_FIRSTHDR(&msg)) == NULL) e(0);
2407 if (cmsg->cmsg_level != IPPROTO_IPV6) e(0);
2408 if (cmsg->cmsg_type != IPV6_PKTINFO) e(0);
2409 if (cmsg->cmsg_len != CMSG_LEN(sizeof(ipi6))) e(0);
2412 * The packet was sent from loopback to loopback, both with IPv4-mapped
2413 * IPv6 addresses, so we can simply compare source and destination.
2415 memcpy(&ipi6, CMSG_DATA(cmsg), sizeof(ipi6));
2416 if (memcmp(&sin6.sin6_addr, &ipi6.ipi6_addr, sizeof(sin6.sin6_addr)))
2417 e(0);
2418 if (ipi6.ipi6_ifindex != ifindex) e(0);
2420 if (CMSG_NXTHDR(&msg, cmsg) != NULL) e(0);
2423 * Sqeeze in a quick test to see what happens if the receiver end does
2424 * not provide a control buffer after having requested control data,
2425 * because a half-complete version of this test triggered a bug there..
2427 if (sendto(fd2, "B", 1, 0, (struct sockaddr *)&sin, sizeof(sin)) != 1)
2428 e(0);
2430 if (recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL) != 1) e(0);
2431 if (buf[0] != 'B') e(0);
2433 if (close(fd2) != 0) e(0);
2434 if (close(fd) != 0) e(0);
2438 * Test that binding a socket of the given type to a privileged port is
2439 * disallowed.
2441 static void
2442 sub91i(int type)
2444 struct sockaddr_in sin;
2445 struct sockaddr_in6 sin6;
2446 int fd, port;
2448 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
2450 memset(&sin, 0, sizeof(sin));
2451 sin.sin_family = AF_INET;
2452 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2454 for (port = IPPORT_RESERVED - 1; port >= 0; port--) {
2455 sin.sin_port = htons(port);
2457 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
2458 if (errno == EADDRINUSE) continue;
2459 if (errno != EACCES) e(0);
2460 break;
2463 for (port = IPPORT_RESERVED; port <= UINT16_MAX; port++) {
2464 sin.sin_port = htons(port);
2466 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) == 0)
2467 break;
2468 if (errno != EADDRINUSE) e(0);
2471 if (close(fd) != 0) e(0);
2473 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
2475 memset(&sin6, 0, sizeof(sin6));
2476 sin6.sin6_family = AF_INET6;
2477 memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
2479 for (port = IPV6PORT_RESERVED - 1; port >= 0; port--) {
2480 sin6.sin6_port = htons(port);
2482 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != -1)
2483 e(0);
2484 if (errno == EADDRINUSE) continue;
2485 if (errno != EACCES) e(0);
2486 break;
2489 for (port = IPV6PORT_RESERVED; port <= UINT16_MAX; port++) {
2490 sin6.sin6_port = htons(port);
2492 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) == 0)
2493 break;
2494 if (errno != EADDRINUSE) e(0);
2497 if (close(fd) != 0) e(0);
2501 * Test that binding to privileged ports is disallowed for non-root users.
2502 * Also make sure that such users cannot create raw sockets at all. This test
2503 * is not to be run by root, but for convenience we first try to drop
2504 * privileges for the duration of the test anyway.
2506 static void
2507 test91i(void)
2509 int i;
2511 subtest = 9;
2513 (void)seteuid(1);
2515 sub91i(SOCK_STREAM);
2517 sub91i(SOCK_DGRAM);
2519 for (i = 0; i < IPPROTO_MAX; i++) {
2520 if (socket(AF_INET, SOCK_RAW, i) != -1) e(0);
2521 if (errno != EACCES) e(0);
2522 if (socket(AF_INET6, SOCK_RAW, i) != -1) e(0);
2523 if (errno != EACCES) e(0);
2526 (void)seteuid(0);
2530 * Test setting and getting basic UDP/RAW multicast transmission options.
2532 static void
2533 test91j(void)
2536 subtest = 10;
2538 socklib_multicast_tx_options(SOCK_DGRAM);
2542 * Test TCP socket state changes related to the listen queue. This test is
2543 * derived from test90y, but sufficiently different to be its own copy.
2545 static void
2546 test91k(void)
2548 struct sockaddr_in6 sin6A, sin6B, sin6C;
2549 socklen_t len;
2550 struct timeval tv;
2551 struct linger l;
2552 fd_set fds;
2553 char buf[7];
2554 int fd, fd2, fd3, fd4, val, fl;
2556 subtest = 11;
2558 if ((fd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0) e(0);
2560 val = 1;
2561 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != 0)
2562 e(0);
2564 memset(&sin6A, 0, sizeof(sin6A));
2565 sin6A.sin6_family = AF_INET6;
2566 sin6A.sin6_port = htons(TEST_PORT_A);
2567 memcpy(&sin6A.sin6_addr, &in6addr_loopback, sizeof(sin6A.sin6_addr));
2569 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2572 * Any socket options should be inherited from the listening socket at
2573 * connect time, and not be re-inherited at accept time, to the extent
2574 * that they are inherited at all. TCP/IP level options are not.
2576 val = 123;
2577 if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)) != 0)
2578 e(0);
2579 val = 32768;
2580 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
2581 e(0);
2583 if (listen(fd, 5) != 0) e(0);
2585 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2587 memset(&sin6B, 0, sizeof(sin6B));
2588 sin6B.sin6_family = AF_INET6;
2589 sin6B.sin6_port = htons(0);
2590 memcpy(&sin6B.sin6_addr, &in6addr_loopback, sizeof(sin6B.sin6_addr));
2592 val = 1;
2593 if (setsockopt(fd2, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) != 0)
2594 e(0);
2596 if (bind(fd2, (struct sockaddr *)&sin6B, sizeof(sin6B)) != 0) e(0);
2598 len = sizeof(sin6B);
2599 if (getsockname(fd2, (struct sockaddr *)&sin6B, &len) != 0) e(0);
2600 if (len != sizeof(sin6B)) e(0);
2601 if (sin6B.sin6_port == htons(0)) e(0);
2603 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2605 val = 456;
2606 if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)) != 0)
2607 e(0);
2608 val = 16384;
2609 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
2610 e(0);
2613 * Obtaining the peer name should work. As always, the name should be
2614 * inherited from the listening socket.
2616 len = sizeof(sin6C);
2617 if (getpeername(fd2, (struct sockaddr *)&sin6C, &len) != 0) e(0);
2618 if (sin6C.sin6_len != sizeof(sin6C)) e(0);
2619 if (sin6C.sin6_family != AF_INET6) e(0);
2620 if (sin6C.sin6_port != htons(TEST_PORT_A)) e(0);
2621 if (memcmp(&sin6C.sin6_addr, &in6addr_loopback,
2622 sizeof(sin6C.sin6_addr)) != 0) e(0);
2625 * Sending to the socket should work, and it should be possible to
2626 * receive the data from the other side once accepted.
2628 if (send(fd2, "Hello, ", 7, 0) != 7) e(0);
2629 if (send(fd2, "world!", 6, 0) != 6) e(0);
2631 /* Shutdown settings should be visible after accepting, too. */
2632 if (shutdown(fd2, SHUT_RDWR) != 0) e(0);
2634 memset(&sin6C, 0, sizeof(sin6C));
2635 len = sizeof(sin6C);
2636 if ((fd3 = accept(fd, (struct sockaddr *)&sin6C, &len)) < 0) e(0);
2637 if (sin6C.sin6_len != sizeof(sin6C)) e(0);
2638 if (sin6C.sin6_family != AF_INET6) e(0);
2639 if (sin6C.sin6_port != sin6B.sin6_port) e(0);
2640 if (memcmp(&sin6C.sin6_addr, &in6addr_loopback,
2641 sizeof(sin6C.sin6_addr)) != 0) e(0);
2643 len = sizeof(val);
2644 if (getsockopt(fd3, SOL_SOCKET, SO_SNDLOWAT, &val, &len) != 0) e(0);
2645 if (len != sizeof(val)) e(0);
2646 if (val != 123) e(0);
2648 len = sizeof(val);
2649 if (getsockopt(fd3, SOL_SOCKET, SO_RCVBUF, &val, &len) != 0) e(0);
2650 if (len != sizeof(val)) e(0);
2651 if (val != 32768) e(0);
2653 if ((fl = fcntl(fd3, F_GETFL)) == -1) e(0);
2654 if (!(fl & O_NONBLOCK)) e(0);
2655 if (fcntl(fd3, F_SETFL, fl & ~O_NONBLOCK) != 0) e(0);
2657 if (recv(fd3, buf, 7, 0) != 7) e(0);
2658 if (memcmp(buf, "Hello, ", 7) != 0) e(0);
2659 if (recv(fd3, buf, 7, 0) != 6) e(0);
2660 if (memcmp(buf, "world!", 6) != 0) e(0);
2662 if (recv(fd3, buf, sizeof(buf), 0) != 0) e(0);
2665 * Unlike in the UDS test, the other side's shutdown-for-reading is not
2666 * visible to this side, so sending data should work just fine until we
2667 * close or shut down the socket ourselves. The other side will simply
2668 * discard the incoming data.
2670 if (send(fd3, "", 1, MSG_NOSIGNAL) != 1) e(0);
2672 if (close(fd2) != 0) e(0);
2673 if (close(fd3) != 0) e(0);
2676 * If the connection pending acceptance is closed, the connection must
2677 * remain on the queue, and the accepting party will read EOF from it.
2678 * Try once without pending data, once with pending data.
2680 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2682 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2684 if (close(fd2) != 0) e(0);
2686 len = sizeof(sin6B);
2687 if ((fd3 = accept(fd, (struct sockaddr *)&sin6B, &len)) < 0) e(0);
2689 len = sizeof(val);
2690 if (getsockopt(fd3, SOL_SOCKET, SO_SNDLOWAT, &val, &len) != 0) e(0);
2691 if (len != sizeof(val)) e(0);
2692 if (val != 456) e(0);
2694 len = sizeof(val);
2695 if (getsockopt(fd3, SOL_SOCKET, SO_RCVBUF, &val, &len) != 0) e(0);
2696 if (len != sizeof(val)) e(0);
2697 if (val != 16384) e(0);
2699 if (recv(fd3, buf, sizeof(buf), 0) != 0) e(0);
2701 if (close(fd3) != 0) e(0);
2703 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2705 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2707 if (send(fd2, "Hello!", 6, 0) != 6) e(0);
2708 if (close(fd2) != 0) e(0);
2710 len = sizeof(sin6B);
2711 if ((fd3 = accept(fd, (struct sockaddr *)&sin6B, &len)) < 0) e(0);
2713 if (recv(fd3, buf, sizeof(buf), 0) != 6) e(0);
2714 if (memcmp(buf, "Hello!", 6) != 0) e(0);
2716 if (recv(fd3, buf, sizeof(buf), 0) != 0) e(0);
2718 if (close(fd3) != 0) e(0);
2721 * If the connection pending acceptance is aborted, the listening
2722 * socket should pretend as though the connection was never there.
2724 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2726 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2728 FD_ZERO(&fds);
2729 FD_SET(fd, &fds);
2730 tv.tv_sec = 0;
2731 tv.tv_usec = 0;
2732 if (select(fd + 1, &fds, NULL, NULL, &tv) != 1) e(0);
2733 if (!FD_ISSET(fd, &fds)) e(0);
2735 memset(&l, 0, sizeof(l));
2736 l.l_onoff = 1;
2737 l.l_linger = 0;
2738 if (setsockopt(fd2, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) e(0);
2740 if (close(fd2) != 0) e(0);
2742 if (select(fd + 1, &fds, NULL, NULL, &tv) != 0) e(0);
2743 if (FD_ISSET(fd, &fds)) e(0);
2745 len = sizeof(sin6B);
2746 if (accept(fd, (struct sockaddr *)&sin6B, &len) != -1) e(0);
2747 if (errno != EWOULDBLOCK) e(0);
2750 * Try the same thing, but now with the connection sandwiched between
2751 * two different pending connections, which should be left intact.
2753 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2755 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2757 if (send(fd2, "A", 1, 0) != 1) e(0);
2759 if ((fd3 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2761 if (connect(fd3, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2763 if (send(fd3, "B", 1, 0) != 1) e(0);
2765 if ((fd4 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2767 if (connect(fd4, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2769 if (send(fd4, "C", 1, 0) != 1) e(0);
2771 if (setsockopt(fd3, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) e(0);
2773 if (close(fd3) != 0) e(0);
2775 len = sizeof(sin6B);
2776 if ((fd3 = accept(fd, (struct sockaddr *)&sin6B, &len)) < 0) e(0);
2778 if (recv(fd3, buf, sizeof(buf), 0) != 1) e(0);
2779 if (buf[0] != 'A') e(0);
2781 if (close(fd3) != 0) e(0);
2782 if (close(fd2) != 0) e(0);
2784 FD_ZERO(&fds);
2785 FD_SET(fd, &fds);
2786 tv.tv_sec = 0;
2787 tv.tv_usec = 0;
2788 if (select(fd + 1, &fds, NULL, NULL, &tv) != 1) e(0);
2789 if (!FD_ISSET(fd, &fds)) e(0);
2791 len = sizeof(sin6B);
2792 if ((fd3 = accept(fd, (struct sockaddr *)&sin6B, &len)) < 0) e(0);
2794 if (recv(fd3, buf, sizeof(buf), 0) != 1) e(0);
2795 if (buf[0] != 'C') e(0);
2797 if (close(fd3) != 0) e(0);
2798 if (close(fd4) != 0) e(0);
2800 if (select(fd + 1, &fds, NULL, NULL, &tv) != 0) e(0);
2801 if (FD_ISSET(fd, &fds)) e(0);
2803 len = sizeof(sin6B);
2804 if (accept(fd, (struct sockaddr *)&sin6B, &len) != -1) e(0);
2805 if (errno != EWOULDBLOCK) e(0);
2808 * If the listening socket was closed, the sockets pending acceptance
2809 * should be reset.
2811 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2813 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2815 if ((fd3 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
2817 if (connect(fd3, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2819 if (close(fd) != 0) e(0);
2821 if (recv(fd2, buf, sizeof(buf), 0) != -1) e(0);
2822 if (errno != ECONNRESET) e(0);
2824 if (recv(fd2, buf, sizeof(buf), 0) != 0) e(0);
2826 if (recv(fd3, buf, sizeof(buf), 0) != -1) e(0);
2827 if (errno != ECONNRESET) e(0);
2829 if (recv(fd3, buf, sizeof(buf), 0) != 0) e(0);
2831 if (close(fd3) != 0) e(0);
2833 if (close(fd2) != 0) e(0);
2837 * Obtain a pair of connected TCP socket.
2839 static int
2840 get_tcp_pair(int domain, int type, int protocol, int fd[2])
2842 struct sockaddr_in6 sin6;
2843 struct sockaddr_in sin;
2844 struct sockaddr *addr;
2845 socklen_t addr_len, len;
2846 int lfd, val;
2848 if (domain == AF_INET6) {
2849 memset(&sin6, 0, sizeof(sin6));
2850 sin6.sin6_family = AF_INET6;
2851 memcpy(&sin6.sin6_addr, &in6addr_loopback,
2852 sizeof(sin6.sin6_addr));
2854 addr = (struct sockaddr *)&sin6;
2855 addr_len = sizeof(sin6);
2856 } else {
2857 assert(domain == AF_INET);
2859 memset(&sin, 0, sizeof(sin));
2860 sin.sin_family = AF_INET;
2861 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2863 addr = (struct sockaddr *)&sin;
2864 addr_len = sizeof(sin);
2867 if ((lfd = socket(domain, type, protocol)) < 0) e(0);
2869 if (bind(lfd, addr, addr_len) != 0) e(0);
2871 len = addr_len;
2872 if (getsockname(lfd, addr, &len) != 0) e(0);
2873 if (len != addr_len) e(0);
2875 if (listen(lfd, 1) != 0) e(0);
2877 if ((fd[0] = socket(domain, type, protocol)) < 0) e(0);
2879 val = 1;
2880 if (setsockopt(fd[0], IPPROTO_TCP, TCP_NODELAY, &val,
2881 sizeof(val)) != 0) e(0);
2883 if (connect(fd[0], addr, addr_len) != 0) e(0);
2885 len = addr_len;
2886 if ((fd[1] = accept(lfd, addr, &len)) < 0) e(0);
2887 if (len != addr_len) e(0);
2889 if (setsockopt(fd[1], IPPROTO_TCP, TCP_NODELAY, &val,
2890 sizeof(val)) != 0) e(0);
2892 if (close(lfd) != 0) e(0);
2894 return 0;
2898 * Test large transfers and MSG_WAITALL.
2900 static void
2901 test91l(void)
2903 int fd[2];
2905 subtest = 12;
2907 get_tcp_pair(AF_INET6, SOCK_STREAM, 0, fd);
2909 socklib_large_transfers(fd);
2911 get_tcp_pair(AF_INET, SOCK_STREAM, 0, fd);
2913 socklib_large_transfers(fd);
2917 * A randomized producer-consumer test for stream sockets. As part of this,
2918 * we also perform very basic bulk functionality tests of FIONREAD, MSG_PEEK,
2919 * MSG_DONTWAIT, and MSG_WAITALL.
2921 static void
2922 test91m(void)
2924 int fd[2];
2926 subtest = 13;
2928 get_tcp_pair(AF_INET6, SOCK_STREAM, 0, fd);
2930 socklib_producer_consumer(fd);
2932 get_tcp_pair(AF_INET, SOCK_STREAM, 0, fd);
2934 socklib_producer_consumer(fd);
2938 * Cause a receive call on the peer side of the connection of 'fd' to be
2939 * aborted in a protocol-specific way. Return -1 to indicate that the given
2940 * file descriptor has been closed.
2942 static int
2943 test91_reset(int fd, const char * data __unused, size_t len __unused)
2945 struct linger l;
2947 l.l_onoff = 1;
2948 l.l_linger = 0;
2949 if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) e(0);
2951 if (close(fd) != 0) e(0);
2953 return -1;
2957 * Test for receiving on stream sockets. In particular, test SO_RCVLOWAT,
2958 * MSG_PEEK, MSG_DONTWAIT, and MSG_WAITALL.
2960 static void
2961 test91n(void)
2964 subtest = 14;
2966 socklib_stream_recv(get_tcp_pair, AF_INET, SOCK_STREAM,
2967 test91_reset);
2971 * Return the send and receive buffer sizes for sockets of the given type. The
2972 * two individual values are stored in 'sndbuf' and 'rcvbuf', for each that is
2973 * not NULL, and the sum is returned from the call.
2975 static int
2976 get_buf_sizes(int type, int * sndbufp, int * rcvbufp)
2978 socklen_t len;
2979 int fd, sndbuf, rcvbuf;
2981 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
2983 len = sizeof(sndbuf);
2984 if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len) != 0) e(0);
2985 if (len != sizeof(sndbuf)) e(0);
2986 if (sndbufp != NULL)
2987 *sndbufp = sndbuf;
2989 len = sizeof(rcvbuf);
2990 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len) != 0) e(0);
2991 if (len != sizeof(rcvbuf)) e(0);
2992 if (rcvbufp != NULL)
2993 *rcvbufp = rcvbuf;
2995 if (close(fd) != 0) e(0);
2997 return sndbuf + rcvbuf;
3001 * The following constant should be set to the window size used within lwIP.
3002 * There is currently no way to obtain this constant from the LWIP service, nor
3003 * would that be information that should ever be used by general applications,
3004 * but we need it to fill socket receive queues in a reliable way. TODO: find
3005 * a better solution for this general problem.
3007 #define WINDOW_SIZE 16384 /* TCP_WND in lwipopt.h, keep in sync! */
3009 #define CHUNK 4096 /* base I/O chunk size */
3010 #define USLEEP_TIME 250000 /* increase on wimpy platforms if needed */
3013 * Fill the receive of socket 'rfd' with data, and if 'fill_send' is non-zero,
3014 * also the send queue of socket 'sfd'. If 'fill_send' is zero, 'delta' may be
3015 * a non-zero value indicating how many bytes extra (delta > 0) or fewer
3016 * (delta < 0) should be sent compared to the receive queue size.
3018 static void
3019 fill_tcp_bufs(int sfd, int rfd, int fill_send, int delta)
3021 unsigned char buf[CHUNK], c;
3022 socklen_t len;
3023 int sndbuf, rcvbuf, mss, chunk, left, res;
3025 assert(!fill_send || delta == 0);
3027 (void)get_buf_sizes(SOCK_STREAM, &sndbuf, &rcvbuf);
3029 len = sizeof(mss);
3030 if (getsockopt(sfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len) != 0) e(0);
3032 left = rcvbuf;
3033 if (delta < 0)
3034 left += delta;
3036 memset(buf, 0, sizeof(buf));
3039 * In general, TCP is not designed for what we want to do here, which
3040 * is to control the contents of the receive buffer down to the last
3041 * byte. We already assume that the caller has disabled the Nagle
3042 * algorithm, but we still have to deal with other algorithms that
3043 * effectively get in the way of full control of the receive buffer.
3045 * In particular, we have to work around an issue where lwIP decides to
3046 * start shrinking the window earlier than necessary. This issue
3047 * triggers during the transition from a fully open window to a reduced
3048 * window. If no acknowledgement is sent when exactly that point is
3049 * reached, the next acknowlegment will not announce the full size of
3050 * the remainder of the window. This appears to be part of the silly
3051 * window avoidance logic, so it is probably intentional behavior and
3052 * thus we have to work around it.
3054 * So far it appears that filling up just the window size does the job,
3055 * as long as the last segment is a full MSS-sized segment and each
3056 * segment is acknowledged (which is why we send data in the other
3057 * direction). Anything short of that may trigger edge cases that, in
3058 * some cases, show up only on slow platforms (e.g. BeagleBones).
3060 * Note that while test91z also fills up receive queues using its own
3061 * algorithm, it sets the receive queue to the window size, thereby
3062 * avoiding the need for this more complicated algorithm.
3064 for (left = rcvbuf - WINDOW_SIZE; left > 0; left -= chunk) {
3065 chunk = (left % mss != 0) ? (left % mss) : mss;
3066 assert(chunk <= left);
3068 if (send(sfd, buf, chunk, 0) != chunk) e(0);
3070 if (send(rfd, ".", 1, 0) != 1) e(0);
3072 if (recv(sfd, &c, 1, 0) != 1) e(0);
3073 if (c != '.') e(0);
3076 /* We are done with the hard part. Now fill up the rest. */
3077 if (fill_send)
3078 delta = sndbuf;
3080 for (left = WINDOW_SIZE + delta; left > 0; left -= res) {
3081 chunk = MIN(left, sizeof(buf));
3083 res = send(sfd, buf, chunk, 0);
3085 if (res <= 0) e(0);
3086 if (res > chunk) e(0);
3091 * Signal handler which just needs to exist, so that invoking it will interrupt
3092 * an ongoing system call.
3094 static void
3095 test91_got_signal(int sig __unused)
3098 /* Nothing. */
3102 * Test for sending on stream sockets. The quick summary here is that send()
3103 * should basically act as the mirror of recv(MSG_WAITALL), i.e., it should
3104 * keep suspending until all data is sent (or the call is interrupted or no
3105 * more can possibly be sent), and, SO_SNDLOWAT, mirroring SO_RCVLOWAT, acts as
3106 * an admission test for the send: nothing is sent until there is room in the
3107 * send buffer (i.e., the peer's receive buffer) for at least the low send
3108 * watermark, or the whole send request length, whichever is smaller. In
3109 * addition, select(2) should use the same threshold.
3111 * This test is a copy of test90v, and would be in socklib instead, were it not
3112 * for the fact that TCP's segmentation and silly window avoidance make it
3113 * impossible to perform the same exact, byte-granular test. Instead, this TCP
3114 * implementation paints with a somewhat broader brush, using send and receive
3115 * chunk sizes large enough to overcome the normally desirable TCP features
3116 * that are now getting in the way. As a result, this copy of the test is not
3117 * only somewhat less effective but also a bit more reliant on specific (TCP)
3118 * settings, although the whole test is still way too useful to skip at all.
3120 static void
3121 sub91o(int iroom, int istate, int slowat, int len, int bits, int act)
3123 struct sigaction sa;
3124 struct timeval tv;
3125 char buf[CHUNK * 4];
3126 fd_set fds;
3127 pid_t pid;
3128 int fd[2], min, flags, res, err;
3129 int pfd[2], orig_iroom, eroom, tstate, fl, status;
3131 if (get_tcp_pair(AF_INET6, SOCK_STREAM, 0, fd) != 0) e(0);
3134 * Set up the initial condition on the sockets.
3136 fill_tcp_bufs(fd[0], fd[1], 1 /*fill_send*/, 0 /*delta*/);
3139 * Receive a bit more than we send, to free up enough room (the MSS) to
3140 * get things going again.
3142 orig_iroom = iroom;
3143 iroom += iroom / 2;
3144 if (iroom > 0)
3145 if (recv(fd[1], buf, iroom, 0) != iroom) e(0);
3147 switch (istate) {
3148 case 0: break;
3149 case 1: if (shutdown(fd[0], SHUT_WR) != 0) e(0); break;
3150 case 2: if (close(fd[1]) != 0) e(0); break;
3153 if (setsockopt(fd[0], SOL_SOCKET, SO_SNDLOWAT, &slowat,
3154 sizeof(slowat)) != 0) e(0);
3156 /* SO_SNDLOWAT is always bounded by the actual send length. */
3157 min = MIN(len, slowat);
3159 flags = MSG_NOSIGNAL;
3160 if (bits & 1) flags |= MSG_DONTWAIT;
3163 * Do a quick select test to see if its result indeed matches whether
3164 * the available space in the "send" buffer meets the threshold.
3166 FD_ZERO(&fds);
3167 FD_SET(fd[0], &fds);
3168 tv.tv_sec = 0;
3169 tv.tv_usec = 0;
3170 res = select(fd[0] + 1, NULL, &fds, NULL, &tv);
3171 if (res < 0 || res > 1) e(0);
3172 if (res != (iroom >= slowat || istate > 0)) e(0);
3173 if (res == 1 && !FD_ISSET(fd[0], &fds)) e(0);
3176 * Cut short a whole lot of cases, to avoid the overhead of forking,
3177 * namely when we know the call should return immediately. This is the
3178 * case when the socket state disallows further sending, or when all
3179 * data could be sent, or when the call was non-blocking. The low
3180 * send watermark only helps determine whether anything was sent here.
3182 if (istate > 0 || iroom >= len || (flags & MSG_DONTWAIT)) {
3183 res = send(fd[0], buf, len, flags);
3185 if (istate > 0) {
3186 if (res != -1) e(0);
3187 if (errno != EPIPE && errno != ECONNRESET) e(0);
3188 } else if (iroom >= len) {
3189 if (res != len) e(0);
3190 } else if (iroom >= min) {
3191 if (res < orig_iroom || res > iroom) e(0);
3192 } else {
3193 if (res != -1) e(0);
3194 if (errno != EWOULDBLOCK) e(0);
3197 /* Early cleanup and return to avoid even more code clutter. */
3198 if (istate != 2 && close(fd[1]) != 0) e(0);
3199 if (close(fd[0]) != 0) e(0);
3201 return;
3205 * Now starts the interesting stuff: the send call should now block,
3206 * even though if we add MSG_DONTWAIT it may not return EWOULDBLOCK,
3207 * because MSG_DONTWAIT prevents the send from blocking after partial
3208 * completion. As such, we can only test our expectations by letting
3209 * the call block, in a child process, and waiting. We do test as much
3210 * of the above assumption as we can for safety right here, but this is
3211 * not a substitute for actually blocking even in these cases!
3213 if (iroom < min) {
3214 if (send(fd[0], buf, len, flags | MSG_DONTWAIT) != -1) e(0);
3215 if (errno != EWOULDBLOCK) e(0);
3219 * If (act < 9), we receive 0, 1, or 2 bytes from the receive queue
3220 * before forcing the send call to terminate in one of three ways.
3222 * If (act == 9), we use a signal to interrupt the send call.
3224 if (act < 9) {
3225 eroom = (act % 3) * (CHUNK + CHUNK / 2 - 1);
3226 tstate = act / 3;
3227 } else
3228 eroom = tstate = 0;
3230 if (pipe2(pfd, O_NONBLOCK) != 0) e(0);
3232 pid = fork();
3233 switch (pid) {
3234 case 0:
3235 errct = 0;
3237 if (close(fd[1]) != 0) e(0);
3238 if (close(pfd[0]) != 0) e(0);
3240 if (act == 9) {
3241 memset(&sa, 0, sizeof(sa));
3242 sa.sa_handler = test91_got_signal;
3243 if (sigaction(SIGUSR1, &sa, NULL) != 0) e(0);
3246 res = send(fd[0], buf, len, flags);
3247 err = errno;
3249 if (write(pfd[1], &res, sizeof(res)) != sizeof(res)) e(0);
3250 if (write(pfd[1], &err, sizeof(err)) != sizeof(err)) e(0);
3252 exit(errct);
3253 case -1:
3254 e(0);
3257 if (close(pfd[1]) != 0) e(0);
3260 * Allow the child to enter the blocking send(2), and check the pipe
3261 * to see if it is really blocked.
3263 if (usleep(USLEEP_TIME) != 0) e(0);
3265 if (read(pfd[0], &res, sizeof(res)) != -1) e(0);
3266 if (errno != EAGAIN) e(0);
3268 if (eroom > 0) {
3269 if (recv(fd[1], buf, eroom, 0) != eroom) e(0);
3272 * The threshold for the send is now met if the entire request
3273 * has been satisfied.
3275 if (iroom + eroom >= len) {
3276 if ((fl = fcntl(pfd[0], F_GETFL, 0)) == -1) e(0);
3277 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0)
3278 e(0);
3280 if (read(pfd[0], &res, sizeof(res)) != sizeof(res))
3281 e(0);
3282 if (read(pfd[0], &err, sizeof(err)) != sizeof(err))
3283 e(0);
3285 if (res != len) e(0);
3287 /* Bail out. */
3288 goto cleanup;
3292 if (act < 9) {
3294 * Now test various ways to terminate the send call.
3296 * For other socket drivers, there should also be a case where
3297 * a socket error is raised instead. For UDS there is no way
3298 * to do that on stream-type sockets, not even with SO_LINGER.
3300 switch (tstate) {
3301 case 0: if (shutdown(fd[0], SHUT_WR) != 0) e(0); break;
3302 case 1: if (close(fd[1]) != 0) e(0); fd[1] = -1; break;
3303 case 2: fd[1] = test91_reset(fd[1], NULL, 0); break;
3305 } else
3306 if (kill(pid, SIGUSR1) != 0) e(0);
3308 if ((fl = fcntl(pfd[0], F_GETFL, 0)) == -1) e(0);
3309 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0) e(0);
3311 if (read(pfd[0], &res, sizeof(res)) != sizeof(res)) e(0);
3312 if (read(pfd[0], &err, sizeof(err)) != sizeof(err)) e(0);
3315 * If the send met the threshold before being terminate or interrupted,
3316 * we should at least have sent something. Otherwise, the send was
3317 * never admitted and should return EPIPE or ECONNRESET (if the send
3318 * was terminated) or EINTR (if the child was killed).
3320 if (iroom + eroom >= min) {
3321 if (res < MIN(orig_iroom, len)) e(0);
3322 if (res > MIN(iroom + eroom, len)) e(0);
3323 } else {
3324 if (res != -1) e(0);
3325 if (act < 9) {
3326 if (err != EPIPE && err != ECONNRESET) e(0);
3327 } else
3328 if (err != EINTR) e(0);
3331 cleanup:
3332 if (close(pfd[0]) != 0) e(0);
3334 if (wait(&status) != pid) e(0);
3335 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
3337 if (fd[1] != -1 && close(fd[1]) != 0) e(0);
3338 if (close(fd[0]) != 0) e(0);
3342 * Test for sending on stream sockets. In particular, test SO_SNDLOWAT and
3343 * MSG_DONTWAIT.
3345 static void
3346 test91o(void)
3348 int iroom, istate, slowat, len, bits, act;
3350 subtest = 15;
3352 /* Insanity. */
3353 for (iroom = 0; iroom <= CHUNK * 2; iroom += CHUNK)
3354 for (istate = 0; istate <= 2; istate++)
3355 for (slowat = CHUNK; slowat <= CHUNK * 2;
3356 slowat += CHUNK)
3357 for (len = CHUNK; len <= CHUNK * 2;
3358 len += CHUNK)
3359 for (bits = 0; bits < 2; bits++)
3360 for (act = 0; act <= 9; act++)
3361 sub91o(iroom, istate,
3362 slowat, len, bits,
3363 act);
3367 * Test filling up the TCP receive queue. In particular, verify that one bug I
3368 * ran into (lwIP bug #49128) is resolved.
3370 static void
3371 test91p(void)
3373 char buf[CHUNK];
3374 size_t total, left;
3375 ssize_t res;
3376 int fd[2];
3378 subtest = 16;
3380 if (get_tcp_pair(AF_INET, SOCK_STREAM, 0, fd) != 0) e(0);
3383 * Fill up the sockets' queues.
3385 total = get_buf_sizes(SOCK_STREAM, NULL, NULL);
3387 fill_tcp_bufs(fd[0], fd[1], 1 /*fill_send*/, 0 /*delta*/);
3390 * Wait long enough for the zero window probing to kick in, which used
3391 * to cause an ACK storm livelock (lwIP bug #49128).
3393 sleep(1);
3396 * Actually sleep a bit longer, so that the polling timer kicks in and
3397 * at least attempts to send more. This is merely an attempt to
3398 * exercise some of the polling code, and should not have any actual
3399 * effect on the rest of the test.
3401 sleep(5);
3404 * Make sure all the data still arrives.
3406 for (left = total; left > 0; left -= res) {
3407 res = recv(fd[1], buf, sizeof(buf), 0);
3408 if (res <= 0) e(0);
3409 if (res > left) e(0);
3412 if (recv(fd[1], buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3413 if (errno != EWOULDBLOCK) e(0);
3416 * Attempt to shut down the socket for writing after filling up the
3417 * send queue. The TCP FIN should then arrive after all the data.
3419 for (left = total; left > 0; left -= res) {
3420 res = send(fd[0], buf, MIN(left, sizeof(buf)), 0);
3421 if (res <= 0) e(0);
3422 if (res > left) e(0);
3425 if (shutdown(fd[0], SHUT_WR) != 0) e(0);
3427 for (left = total; left > 0; left -= res) {
3428 res = recv(fd[1], buf, sizeof(buf), 0);
3429 if (res <= 0) e(0);
3430 if (res > left) e(0);
3433 if (recv(fd[1], buf, sizeof(buf), 0) != 0) e(0);
3435 if (send(fd[1], "A", 1, 0) != 1) e(0);
3437 if (recv(fd[0], buf, sizeof(buf), 0) != 1) e(0);
3438 if (buf[0] != 'A') e(0);
3440 if (close(fd[1]) != 0) e(0);
3441 if (close(fd[0]) != 0) e(0);
3445 * Attempt to fill up a TCP send queue with small amounts of data. While it
3446 * may or may not be possible to fill up the entire send queue with small
3447 * requests, but at least trying should not cause any problems, like the one I
3448 * filed as lwIP bug #49218.
3450 static void
3451 test91q(void)
3453 ssize_t res;
3454 size_t count;
3455 char c, c2;
3456 int fd[2];
3458 subtest = 17;
3460 if (get_tcp_pair(AF_INET6, SOCK_STREAM, 0, fd) != 0) e(0);
3462 count = 0;
3463 for (c = 0; (res = send(fd[0], &c, sizeof(c), MSG_DONTWAIT)) > 0; c++)
3464 count += res;
3465 if (res != -1) e(0);
3466 if (errno != EWOULDBLOCK) e(0);
3467 if (count < CHUNK) e(0);
3469 if (shutdown(fd[0], SHUT_WR) != 0) e(0);
3471 for (c2 = 0; count > 0; count--, c2++) {
3472 if (recv(fd[1], &c, sizeof(c), 0) != 1) e(0);
3473 if (c != c2) e(0);
3476 if (recv(fd[1], &c, sizeof(c), 0) != 0) e(0);
3478 if (close(fd[0]) != 0) e(0);
3479 if (close(fd[1]) != 0) e(0);
3483 * Test that SO_RCVLOWAT is limited to the size of the receive buffer.
3485 static void
3486 sub91r_recv(int fill_delta, int rlowat_delta, int exp_delta)
3488 char *buf;
3489 size_t buflen;
3490 int fd[2], rlowat, rcvlen, res;
3492 if (get_tcp_pair(AF_INET, SOCK_STREAM, 0, fd) != 0) e(0);
3495 * Fill up the socket's receive queue, possibly minus one byte.
3497 (void)get_buf_sizes(SOCK_STREAM, NULL, &rcvlen);
3499 buflen = MAX(CHUNK, rcvlen + 1);
3500 if ((buf = malloc(buflen)) == NULL) e(0);
3502 fill_tcp_bufs(fd[1], fd[0], 0 /*fill_send*/, fill_delta);
3504 rlowat = rcvlen + rlowat_delta;
3505 if (setsockopt(fd[0], SOL_SOCKET, SO_RCVLOWAT, &rlowat,
3506 sizeof(rlowat)) != 0) e(0);
3508 if (ioctl(fd[0], FIONREAD, &res) != 0) e(0);
3509 if (res != rcvlen + fill_delta) e(0);
3511 res = recv(fd[0], buf, rcvlen + 1, MSG_DONTWAIT);
3512 if (exp_delta < 0) {
3513 if (res != -1) e(0);
3514 if (errno != EWOULDBLOCK) e(0);
3515 } else
3516 if (res != rcvlen - exp_delta) e(0);
3518 free(buf);
3520 if (close(fd[0]) != 0) e(0);
3521 if (close(fd[1]) != 0) e(0);
3525 * Test that SO_SNDLOWAT is limited to the size of the send buffer.
3527 static void
3528 sub91r_send(int fill, int slowat_delta, int exp_delta)
3530 char *buf;
3531 size_t buflen;
3532 int fd[2], sndlen, slowat, res;
3534 if (get_tcp_pair(AF_INET6, SOCK_STREAM, 0, fd) != 0) e(0);
3537 * Fill up the socket's receive queue, and possibly put one extra byte
3538 * in the other socket's send queue.
3540 (void)get_buf_sizes(SOCK_STREAM, &sndlen, NULL);
3542 buflen = MAX(CHUNK, sndlen + 1);
3543 if ((buf = malloc(buflen)) == NULL) e(0);
3545 memset(buf, 0, buflen);
3547 fill_tcp_bufs(fd[0], fd[1], 0 /*fill_send*/, 0 /*delta*/);
3549 slowat = sndlen + slowat_delta;
3551 if (fill > 0) {
3552 memset(buf, 0, fill);
3554 if (send(fd[0], buf, fill, 0) != fill) e(0);
3557 if (setsockopt(fd[0], SOL_SOCKET, SO_SNDLOWAT, &slowat,
3558 sizeof(slowat)) != 0) e(0);
3560 res = send(fd[0], buf, sndlen + 1, MSG_DONTWAIT);
3561 if (exp_delta < 0) {
3562 if (res != -1) e(0);
3563 if (errno != EWOULDBLOCK) e(0);
3564 } else
3565 if (res != sndlen - exp_delta) e(0);
3567 free(buf);
3569 if (close(fd[0]) != 0) e(0);
3570 if (close(fd[1]) != 0) e(0);
3574 * Test that on stream sockets, SO_RCVLOWAT and SO_SNDLOWAT are limited to
3575 * their respective buffer sizes. This test is derived from test90w, but
3576 * merging the two into socklib would get too messy unfortunately.
3578 static void
3579 test91r(void)
3582 subtest = 18;
3585 * With the receive buffer filled except for one byte, all data should
3586 * be retrieved unless the threshold is not met.
3588 sub91r_recv(-1, -1, 1);
3589 sub91r_recv(-1, 0, -1);
3590 sub91r_recv(-1, 1, -1);
3593 * With the receive buffer filled completely, all data should be
3594 * retrieved in all cases.
3596 sub91r_recv(0, -1, 0);
3597 sub91r_recv(0, 0, 0);
3598 sub91r_recv(0, 1, 0);
3601 * With a send buffer that contains one byte, all data should be sent
3602 * unless the threshold is not met.
3604 sub91r_send(1, -1, 1);
3605 sub91r_send(1, 0, -1);
3606 sub91r_send(1, 1, -1);
3609 * With the send buffer filled completely, all data should be sent
3610 * in all cases.
3612 sub91r_send(0, -1, 0);
3613 sub91r_send(0, 0, 0);
3614 sub91r_send(0, 1, 0);
3618 * Test sending and receiving with bad pointers on a TCP socket.
3620 static void
3621 sub91s_tcp(char * ptr)
3623 int fd[2];
3625 memset(ptr, 'X', PAGE_SIZE);
3627 if (get_tcp_pair(AF_INET, SOCK_STREAM, 0, fd) != 0) e(0);
3629 if (send(fd[0], "A", 1, 0) != 1) e(0);
3631 if (send(fd[0], ptr, PAGE_SIZE * 2, MSG_DONTWAIT) != -1) e(0);
3632 if (errno != EFAULT) e(0);
3634 if (send(fd[0], "B", 1, 0) != 1) e(0);
3636 if (shutdown(fd[0], SHUT_WR) != 0) e(0);
3638 if (recv(fd[1], &ptr[PAGE_SIZE - 1], PAGE_SIZE, MSG_WAITALL) != -1)
3639 e(0);
3640 if (errno != EFAULT) e(0);
3642 if (recv(fd[1], ptr, 3, MSG_DONTWAIT) != 2) e(0);
3643 if (ptr[0] != 'A') e(0);
3644 if (ptr[1] != 'B') e(0);
3646 if (close(fd[0]) != 0) e(0);
3647 if (close(fd[1]) != 0) e(0);
3651 * Test sending and receiving with bad pointers on a UDP socket.
3653 static void
3654 sub91s_udp(char * ptr)
3656 struct sockaddr_in6 sin6;
3657 int i, fd;
3659 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
3661 memset(&sin6, 0, sizeof(sin6));
3662 sin6.sin6_family = AF_INET6;
3663 sin6.sin6_port = htons(TEST_PORT_A);
3664 memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
3666 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
3668 memset(ptr, 'A', PAGE_SIZE);
3670 if (sendto(fd, &ptr[PAGE_SIZE / 2], PAGE_SIZE, 0,
3671 (struct sockaddr *)&sin6, sizeof(sin6)) != -1) e(0);
3672 if (errno != EFAULT) e(0);
3674 memset(ptr, 'B', PAGE_SIZE);
3676 if (sendto(fd, ptr, PAGE_SIZE, 0, (struct sockaddr *)&sin6,
3677 sizeof(sin6)) != PAGE_SIZE) e(0);
3679 memset(ptr, 0, PAGE_SIZE);
3681 if (recvfrom(fd, &ptr[PAGE_SIZE / 2], PAGE_SIZE, 0, NULL, 0) != -1)
3682 e(0);
3683 if (errno != EFAULT) e(0);
3685 if (recvfrom(fd, ptr, PAGE_SIZE * 2, 0, NULL, 0) != PAGE_SIZE) e(0);
3686 for (i = 0; i < PAGE_SIZE; i++)
3687 if (ptr[i] != 'B') e(0);
3689 if (close(fd) != 0) e(0);
3693 * Test sending and receiving with bad pointers.
3695 static void
3696 test91s(void)
3698 char *ptr;
3700 subtest = 19;
3702 if ((ptr = mmap(NULL, PAGE_SIZE * 2, PROT_READ | PROT_WRITE,
3703 MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED) e(0);
3705 if (munmap(&ptr[PAGE_SIZE], PAGE_SIZE) != 0) e(0);
3707 sub91s_tcp(ptr);
3708 sub91s_udp(ptr);
3710 if (munmap(ptr, PAGE_SIZE) != 0) e(0);
3714 * Test closing TCP sockets and SO_LINGER.
3716 static void
3717 test91t(void)
3719 char buf[CHUNK];
3720 size_t total, left;
3721 ssize_t res;
3722 int i, fd[2];
3724 subtest = 20;
3726 total = get_buf_sizes(SOCK_STREAM, NULL, NULL);
3728 memset(buf, 0, sizeof(buf));
3731 * Test two cases of handling connection closure:
3733 * 1) the FIN+ACK case, where the closing side finishes the close
3734 * operation once its FIN has been acknowledged;
3735 * 2) the FIN+FIN case, where the closing side finishes the close
3736 * operation once it has sent its own FIN (possibly without getting
3737 * an ACK yet) and also receives a FIN from the other side.
3739 * Since lwIP prevents us from detecting #1 without polling, which
3740 * happens twice a second, we can test #2 by shutting down the peer
3741 * connection immediately after (i=0/2) or even before (i=4/5) closing
3742 * this side.
3744 for (i = 0; i <= 5; i++) {
3745 if (get_tcp_pair(AF_INET, SOCK_STREAM, 0, fd) != 0) e(0);
3747 fill_tcp_bufs(fd[0], fd[1], 1 /*fill_send*/, 0 /*delta*/);
3749 if (close(fd[0]) != 0) e(0);
3751 if (i >= 4 && shutdown(fd[1], SHUT_WR) != 0) e(0);
3753 for (left = total; left > 0; left -= res) {
3754 res = recv(fd[1], buf, sizeof(buf), 0);
3755 if (res <= 0) e(0);
3756 if (res > left) e(0);
3759 if (recv(fd[1], buf, sizeof(buf), 0) != 0) e(0);
3761 sleep(i & 1);
3764 * We can still send to the receiving end, but this will cause
3765 * a reset. We do this only if we have not just shut down the
3766 * writing end of this socket. Also test regular closing.
3768 if (i / 2 == 1) {
3769 if (send(fd[1], "B", 1, 0) != 1) e(0);
3771 if (recv(fd[1], buf, sizeof(buf), 0) != -1) e(0);
3772 if (errno != ECONNRESET) e(0);
3775 if (close(fd[1]) != 0) e(0);
3779 * Test that closing a socket with data still in its receive queue
3780 * causes a RST to be issued.
3782 if (get_tcp_pair(AF_INET6, SOCK_STREAM, 0, fd) != 0) e(0);
3784 if (send(fd[0], "C", 1, 0) != 1) e(0);
3786 if (recv(fd[1], buf, sizeof(buf), MSG_PEEK) != 1) e(0);
3788 if (close(fd[1]) != 0) e(0);
3790 if (recv(fd[0], buf, sizeof(buf), 0) != -1) e(0);
3791 if (errno != ECONNRESET) e(0);
3793 if (close(fd[0]) != 0) e(0);
3797 * Test closing a socket with a particular SO_LINGER setting.
3799 static void
3800 sub91u(int nb, int mode, int intr, int onoff, int linger)
3802 char buf[CHUNK];
3803 struct timeval tv1, tv2;
3804 struct linger l;
3805 pid_t pid;
3806 int fd[2], pfd[2], fl, val, res, status;
3808 get_tcp_pair((mode & 1) ? AF_INET6 : AF_INET, SOCK_STREAM, 0, fd);
3811 * Set up the socket pair.
3813 fill_tcp_bufs(fd[0], fd[1], 0 /*fill_send*/, 1 /*delta*/);
3815 if (mode == 3 && shutdown(fd[1], SHUT_WR) != 0) e(0);
3817 l.l_onoff = onoff;
3818 l.l_linger = (linger) ? (2 + intr) : 0;
3819 if (setsockopt(fd[0], SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) e(0);
3821 if (nb) {
3822 if ((fl = fcntl(fd[0], F_GETFL)) == -1) e(0);
3823 if (fcntl(fd[0], F_SETFL, fl | O_NONBLOCK) != 0) e(0);
3826 /* We need two-way parent-child communication for this test. */
3827 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pfd) != 0) e(0);
3829 pid = fork();
3830 switch (pid) {
3831 case 0:
3832 errct = 0;
3834 if (close(pfd[1]) != 0) e(0);
3836 if (close(fd[1]) != 0) e(0);
3838 signal(SIGUSR1, test91_got_signal);
3841 * Do not start closing the file descriptor until after the
3842 * parent has closed its copy.
3844 if (read(pfd[0], &val, sizeof(val)) != sizeof(val)) e(0);
3845 if (val != 0) e(0);
3847 if (gettimeofday(&tv1, NULL) != 0) e(0);
3849 /* Perform the possibly blocking close(2) call. */
3850 if (intr) {
3851 if (close(fd[0]) != -1) e(0);
3852 if (errno != EINPROGRESS) e(0);
3853 } else
3854 if (close(fd[0]) != 0) e(0);
3856 if (gettimeofday(&tv2, NULL) != 0) e(0);
3858 timersub(&tv2, &tv1, &tv1);
3860 /* Polling may take 500ms. */
3861 val = tv1.tv_sec + ((tv1.tv_usec > 750000) ? 1 : 0);
3863 if (val < 0 || val > 2) e(0);
3865 /* Tell the parent how long the close(2) took, in seconds. */
3866 if (write(pfd[0], &val, sizeof(val)) != sizeof(val)) e(0);
3868 exit(errct);
3869 case -1:
3870 e(0);
3873 /* Close file descriptors here and then let the child run. */
3874 if (close(pfd[0]) != 0) e(0);
3876 if (close(fd[0]) != 0) e(0);
3878 val = 0;
3879 if (write(pfd[1], &val, sizeof(val)) != sizeof(val)) e(0);
3882 * Wait one second until we try to close the connection ourselves, if
3883 * applicable. If we are killing the child, we add yet another second
3884 * to tell the difference between a clean close and a timeout/reset.
3886 sleep(1);
3888 if (intr) {
3889 if (kill(pid, SIGUSR1) != 0) e(0);
3891 sleep(1);
3895 * Trigger various ways in which the connection is closed, or not, in
3896 * which case the linger timeout should cause a reset.
3898 switch (mode) {
3899 case 0: /* do nothing; expect reset */
3900 break;
3902 case 1: /* FIN + rFIN */
3903 if (shutdown(fd[1], SHUT_WR) != 0) e(0);
3906 * The FIN cannot yet be sent due to the zero-sized receive
3907 * window. Make some room so that it can be sent.
3909 /* FALLTHROUGH */
3910 case 2: /* FIN + ACK */
3911 case 3: /* rFIN + FIN */
3912 if (recv(fd[1], buf, sizeof(buf), 0) <= 0) e(0);
3913 break;
3915 case 4: /* RST */
3916 l.l_onoff = 1;
3917 l.l_linger = 0;
3918 if (setsockopt(fd[1], SOL_SOCKET, SO_LINGER, &l,
3919 sizeof(l)) != 0) e(0);
3921 if (close(fd[1]) != 0) e(0);
3922 fd[1] = -1;
3923 break;
3925 default:
3926 e(0);
3930 * Make absolutely sure that the linger timer has triggered and we do
3931 * not end up exploiting race conditions in the tests below. As a
3932 * result this subtest takes over a minute but at least it has already
3933 * triggered a whole bunch of bugs (and produced lwIP patch #9125).
3935 sleep(2);
3937 /* Get the number of seconds spent in the close(2) call. */
3938 if (read(pfd[1], &val, sizeof(val)) != sizeof(val)) e(0);
3941 * See if the close(2) call took as long as expected and check that the
3942 * other side of the connection sees either EOF or a reset as expected.
3944 if (mode == 0) {
3945 if (nb) {
3946 if (val != 0) e(0);
3948 sleep(2);
3949 } else if (!intr) {
3950 if (val != linger * 2) e(0);
3951 } else
3952 if (val != 1) e(0);
3954 /* See if the connection was indeed reset. */
3955 while ((res = recv(fd[1], buf, sizeof(buf), 0)) > 0)
3957 if (res != -1) e(0);
3958 if (errno != ECONNRESET) e(0);
3959 } else {
3960 if (val != ((onoff && !nb) || intr)) e(0);
3962 /* Check for EOF unless we already closed the socket. */
3963 if (fd[1] != -1) {
3964 while ((res = recv(fd[1], buf, sizeof(buf), 0)) > 0)
3966 if (res != 0) e(0);
3970 /* Clean up. */
3971 if (fd[1] != -1 && close(fd[1]) != 0) e(0);
3973 if (close(pfd[1]) != 0) e(0);
3975 if (wait(&status) != pid) e(0);
3976 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
3980 * Test SO_LINGER support in various configurations. It is worth noting that I
3981 * implemented a somewhat broken version of SO_LINGER because lwIP does not
3982 * allow for proper detection of our FIN being acknowledged in all cases (this
3983 * is documented in the service). As a result, a close(2) call may return
3984 * earlier than it is supposed to, namely as soon as 1) we sent a FIN, and
3985 * 2) we received a FIN from the other side. We also test the somewhat broken
3986 * behavior here, as above all else the aim is to make sure that the service
3987 * code works as expected.
3989 static void
3990 test91u(void)
3992 int nb, mode;
3994 subtest = 21;
3998 * In all of the following scenarios, close(2) should only ever return
3999 * success, so that the caller knows that the file descriptor has been
4000 * closed.
4002 for (nb = 0; nb <= 1; nb++) {
4004 * SO_LINGER off: the close(2) call should return immediately,
4005 * and the connection should be closed in the background.
4007 for (mode = 1; mode <= 4; mode++)
4008 sub91u(nb, mode, 0, 0, 0);
4011 * SO_LINGER on with a zero timeout: the close(2) call should
4012 * return immediately, and the connection should be reset.
4014 sub91u(nb, 0, 0, 1, 0);
4017 * SO_LINGER on with a non-zero timeout: the close(2) call
4018 * should return immediately for non-blocking sockets only, and
4019 * otherwise as soon as either the connection is closed or the
4020 * timeout triggers, in which case the connection is reset.
4022 for (mode = 0; mode <= 4; mode++)
4023 sub91u(nb, mode, 0, 1, 1);
4027 * Test signal-interrupting blocked close(2) calls with SO_LINGER. In
4028 * such cases, the close(2) should return EINPROGRESS to indicate that
4029 * the file descriptor has been closed, and the original close action
4030 * (with the original timeout) should proceed in the background.
4032 for (mode = 0; mode <= 4; mode++)
4033 sub91u(0, mode, 1, 1, 1);
4037 * Test shutdown on listening TCP sockets.
4039 static void
4040 sub91v(int how)
4042 struct sockaddr_in sin;
4043 socklen_t len;
4044 char c;
4045 int fd, fd2, fd3, fl;
4047 memset(&sin, 0, sizeof(sin));
4048 sin.sin_family = AF_INET;
4049 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4051 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
4053 if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
4055 len = sizeof(sin);
4056 if (getsockname(fd, (struct sockaddr *)&sin, &len) != 0) e(0);
4057 if (len != sizeof(sin)) e(0);
4059 if (listen(fd, 1) != 0) e(0);
4061 if ((fd2 = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
4063 if (connect(fd2, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
4065 if (shutdown(fd, how) != 0) e(0);
4067 len = sizeof(sin);
4068 if ((fd3 = accept(fd, (struct sockaddr *)&sin, &len)) < 0) e(0);
4069 if (len != sizeof(sin)) e(0);
4071 if (write(fd2, "A", 1) != 1) e(0);
4072 if (read(fd3, &c, 1) != 1) e(0);
4073 if (c != 'A') e(0);
4075 if (write(fd3, "B", 1) != 1) e(0);
4076 if (read(fd2, &c, 1) != 1) e(0);
4077 if (c != 'B') e(0);
4079 len = sizeof(sin);
4080 if (accept(fd, (struct sockaddr *)&sin, &len) != -1) e(0);
4081 if (errno != ECONNABORTED) e(0);
4083 if ((fl = fcntl(fd, F_GETFL)) == -1) e(0);
4084 if (fcntl(fd, F_SETFL, fl | O_NONBLOCK) != 0) e(0);
4086 len = sizeof(sin);
4087 if (accept(fd, (struct sockaddr *)&sin, &len) != -1) e(0);
4088 if (errno != ECONNABORTED) e(0);
4090 if (close(fd3) != 0) e(0);
4091 if (close(fd2) != 0) e(0);
4092 if (close(fd) != 0) e(0);
4096 * Test shutdown on listening TCP sockets. This test is derived from test90x.
4098 static void
4099 test91v(void)
4101 const int hows[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
4102 int i;
4104 subtest = 22;
4106 for (i = 0; i < __arraycount(hows); i++)
4107 sub91v(hows[i]);
4111 * Test basic sysctl(2) socket enumeration support.
4113 static void
4114 test91w(void)
4116 struct kinfo_pcb ki;
4117 struct sockaddr_in lsin, rsin;
4118 struct sockaddr_in6 lsin6, rsin6;
4119 char buf[CHUNK];
4120 uint16_t local_port, remote_port;
4121 socklen_t len;
4122 int fd[2], val, sndbuf, rcvbuf;
4124 subtest = 23;
4127 * First test TCP.
4129 get_tcp_pair(AF_INET, SOCK_STREAM, 0, fd);
4131 val = 0;
4132 if (setsockopt(fd[1], IPPROTO_TCP, TCP_NODELAY, &val,
4133 sizeof(val)) != 0) e(0);
4135 len = sizeof(lsin);
4136 if (getsockname(fd[0], (struct sockaddr *)&lsin, &len) != 0) e(0);
4137 if (len != sizeof(lsin)) e(0);
4138 local_port = ntohs(lsin.sin_port);
4140 if (getpeername(fd[0], (struct sockaddr *)&rsin, &len) != 0) e(0);
4141 if (len != sizeof(rsin)) e(0);
4142 remote_port = ntohs(rsin.sin_port);
4144 if (send(fd[0], "ABCDE", 5, 0) != 5) e(0);
4146 /* Allow the data to reach the other side and be acknowledged. */
4147 sleep(1);
4149 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, local_port,
4150 remote_port, &ki) != 1) e(0);
4151 if (ki.ki_type != SOCK_STREAM) e(0);
4152 if (ki.ki_tstate != TCPS_ESTABLISHED) e(0);
4153 if (!(ki.ki_tflags & TF_NODELAY)) e(0);
4154 if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
4155 if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
4156 if (ki.ki_sndq != 0) e(0);
4157 if (ki.ki_rcvq != 0) e(0);
4159 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, local_port,
4160 remote_port, &ki) != 0) e(0);
4162 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, remote_port,
4163 local_port, &ki) != 1) e(0);
4164 if (ki.ki_type != SOCK_STREAM) e(0);
4165 if (ki.ki_tstate != TCPS_ESTABLISHED) e(0);
4166 if (ki.ki_tflags & TF_NODELAY) e(0);
4167 if (memcmp(&ki.ki_src, &rsin, sizeof(rsin)) != 0) e(0);
4168 if (memcmp(&ki.ki_dst, &lsin, sizeof(lsin)) != 0) e(0);
4169 if (ki.ki_sndq != 0) e(0);
4170 if (ki.ki_rcvq != 5) e(0);
4172 if (recv(fd[1], buf, sizeof(buf), 0) != 5) e(0);
4174 if (close(fd[0]) != 0) e(0);
4175 if (close(fd[1]) != 0) e(0);
4177 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, local_port,
4178 remote_port, &ki) != 1) e(0);
4179 if (ki.ki_type != SOCK_STREAM) e(0);
4180 if (ki.ki_tstate != TCPS_TIME_WAIT) e(0);
4181 if (ki.ki_sndq != 0) e(0);
4182 if (ki.ki_rcvq != 0) e(0);
4184 /* Test IPv6 sockets as well. */
4185 get_tcp_pair(AF_INET6, SOCK_STREAM, 0, fd);
4187 len = sizeof(lsin6);
4188 if (getsockname(fd[0], (struct sockaddr *)&lsin6, &len) != 0) e(0);
4189 if (len != sizeof(lsin6)) e(0);
4190 local_port = ntohs(lsin6.sin6_port);
4192 if (getpeername(fd[0], (struct sockaddr *)&rsin6, &len) != 0) e(0);
4193 if (len != sizeof(rsin6)) e(0);
4194 remote_port = ntohs(rsin6.sin6_port);
4196 memset(buf, 0, sizeof(buf));
4198 /* We fill up the queues so we do not need to sleep in this case. */
4199 (void)get_buf_sizes(SOCK_STREAM, &sndbuf, &rcvbuf);
4201 fill_tcp_bufs(fd[0], fd[1], 1 /*fill_send*/, 0 /*delta*/);
4203 if (send(fd[0], buf, 1, MSG_DONTWAIT) != -1) e(0);
4204 if (errno != EWOULDBLOCK) e(0);
4206 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, local_port,
4207 remote_port, &ki) != 1) e(0);
4208 if (ki.ki_type != SOCK_STREAM) e(0);
4209 if (ki.ki_tstate != TCPS_ESTABLISHED) e(0);
4210 if (!(ki.ki_tflags & TF_NODELAY)) e(0);
4211 if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
4212 if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
4213 if (ki.ki_sndq != (size_t)sndbuf) e(0);
4214 if (ki.ki_rcvq != 0) e(0);
4216 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, local_port,
4217 remote_port, &ki) != 0) e(0);
4219 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP,
4220 remote_port, local_port, &ki) != 1) e(0);
4221 if (ki.ki_type != SOCK_STREAM) e(0);
4222 if (ki.ki_tstate != TCPS_ESTABLISHED) e(0);
4223 if (!(ki.ki_tflags & TF_NODELAY)) e(0);
4224 if (memcmp(&ki.ki_src, &rsin6, sizeof(rsin6)) != 0) e(0);
4225 if (memcmp(&ki.ki_dst, &lsin6, sizeof(lsin6)) != 0) e(0);
4226 if (ki.ki_sndq != 0) e(0);
4227 if (ki.ki_rcvq != (size_t)rcvbuf) e(0);
4229 if (close(fd[0]) != 0) e(0);
4230 if (close(fd[1]) != 0) e(0);
4232 /* Bound and listening sockets should show up as well. */
4233 if ((fd[0] = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
4235 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, 0, 0,
4236 &ki) != 0) e(0);
4238 memset(&lsin, 0, sizeof(lsin));
4239 lsin.sin_len = sizeof(lsin);
4240 lsin.sin_family = AF_INET;
4241 lsin.sin_port = htons(TEST_PORT_A);
4242 lsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4243 if (bind(fd[0], (struct sockaddr *)&lsin, sizeof(lsin)) != 0) e(0);
4245 memset(&rsin, 0, sizeof(rsin));
4246 rsin.sin_len = sizeof(rsin);
4247 rsin.sin_family = AF_INET;
4249 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, TEST_PORT_A,
4250 0, &ki) != 1) e(0);
4251 if (ki.ki_type != SOCK_STREAM) e(0);
4252 if (ki.ki_tstate != TCPS_CLOSED) e(0);
4253 if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
4254 if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
4255 if (ki.ki_sndq != 0) e(0);
4256 if (ki.ki_rcvq != 0) e(0);
4258 if (listen(fd[0], 1)) e(0);
4260 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, TEST_PORT_A,
4261 0, &ki) != 1) e(0);
4262 if (ki.ki_type != SOCK_STREAM) e(0);
4263 if (ki.ki_tstate != TCPS_LISTEN) e(0);
4264 if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
4265 if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
4266 if (ki.ki_sndq != 0) e(0);
4267 if (ki.ki_rcvq != 0) e(0);
4269 if (close(fd[0]) != 0) e(0);
4271 /* Test IPv6 sockets as well. */
4272 if ((fd[0] = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
4274 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, 0, 0,
4275 &ki) != 0) e(0);
4277 val = 1;
4278 if (setsockopt(fd[0], IPPROTO_IPV6, IPV6_V6ONLY, &val,
4279 sizeof(val)) != 0) e(0);
4281 memset(&lsin6, 0, sizeof(lsin6));
4282 lsin6.sin6_len = sizeof(lsin6);
4283 lsin6.sin6_family = AF_INET6;
4284 lsin6.sin6_port = htons(TEST_PORT_A);
4285 memcpy(&lsin6.sin6_addr, &in6addr_loopback, sizeof(lsin6.sin6_addr));
4286 if (bind(fd[0], (struct sockaddr *)&lsin6, sizeof(lsin6)) != 0) e(0);
4288 memset(&rsin6, 0, sizeof(rsin6));
4289 rsin6.sin6_len = sizeof(rsin6);
4290 rsin6.sin6_family = AF_INET6;
4292 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP,
4293 TEST_PORT_A, 0, &ki) != 1) e(0);
4294 if (ki.ki_type != SOCK_STREAM) e(0);
4295 if (ki.ki_tstate != TCPS_CLOSED) e(0);
4296 if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
4297 if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
4298 if (!(ki.ki_pflags & IN6P_IPV6_V6ONLY)) e(0);
4300 if (listen(fd[0], 1)) e(0);
4302 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP,
4303 TEST_PORT_A, 0, &ki) != 1) e(0);
4304 if (ki.ki_type != SOCK_STREAM) e(0);
4305 if (ki.ki_tstate != TCPS_LISTEN) e(0);
4306 if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
4307 if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
4308 if (!(ki.ki_pflags & IN6P_IPV6_V6ONLY)) e(0);
4310 if (close(fd[0]) != 0) e(0);
4313 * I do not dare binding to ANY so we cannot test IPV6_V6ONLY properly
4314 * here. Instead we repeat the test and ensure the IN6P_IPV6_V6ONLY
4315 * flag accurately represents the current state.
4317 if ((fd[0] = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
4319 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, 0, 0,
4320 &ki) != 0) e(0);
4322 val = 0;
4323 if (setsockopt(fd[0], IPPROTO_IPV6, IPV6_V6ONLY, &val,
4324 sizeof(val)) != 0) e(0);
4326 if (bind(fd[0], (struct sockaddr *)&lsin6, sizeof(lsin6)) != 0) e(0);
4328 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP,
4329 TEST_PORT_A, 0, &ki) != 1) e(0);
4330 if (ki.ki_type != SOCK_STREAM) e(0);
4331 if (ki.ki_tstate != TCPS_CLOSED) e(0);
4332 if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
4333 if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
4334 if (!(ki.ki_pflags & IN6P_IPV6_V6ONLY)) e(0);
4336 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, TEST_PORT_A,
4337 0, &ki) != 0) e(0);
4339 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_TCP, TEST_PORT_A,
4340 0, &ki) != 0) e(0);
4342 if (close(fd[0]) != 0) e(0);
4345 * Then test UDP.
4347 if ((fd[0] = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
4349 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP, 0, 0,
4350 &ki) != 0) e(0);
4352 memset(&lsin, 0, sizeof(lsin));
4353 lsin.sin_len = sizeof(lsin);
4354 lsin.sin_family = AF_INET;
4355 lsin.sin_port = htons(TEST_PORT_A);
4356 lsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4358 memset(&rsin, 0, sizeof(rsin));
4359 rsin.sin_len = sizeof(rsin);
4360 rsin.sin_family = AF_INET;
4362 if (bind(fd[0], (struct sockaddr *)&lsin, sizeof(lsin)) != 0) e(0);
4364 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP, TEST_PORT_A,
4365 0, &ki) != 1) e(0);
4366 if (ki.ki_type != SOCK_DGRAM) e(0);
4367 if (ki.ki_tstate != 0) e(0);
4368 if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
4369 if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
4370 if (ki.ki_sndq != 0) e(0);
4371 if (ki.ki_rcvq != 0) e(0);
4373 rsin.sin_port = htons(TEST_PORT_B);
4374 rsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4375 if (connect(fd[0], (struct sockaddr *)&rsin, sizeof(rsin)) != 0) e(0);
4377 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP, TEST_PORT_A,
4378 TEST_PORT_B, &ki) != 1) e(0);
4379 if (ki.ki_type != SOCK_DGRAM) e(0);
4380 if (ki.ki_tstate != 0) e(0);
4381 if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
4382 if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
4383 if (ki.ki_sndq != 0) e(0);
4384 if (ki.ki_rcvq != 0) e(0);
4386 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP, TEST_PORT_B,
4387 TEST_PORT_A, &ki) != 0) e(0);
4389 if ((fd[1] = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
4391 if (bind(fd[1], (struct sockaddr *)&rsin, sizeof(rsin)) != 0) e(0);
4393 if (sendto(fd[1], "ABC", 3, 0, (struct sockaddr *)&lsin,
4394 sizeof(lsin)) != 3) e(0);
4396 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP, TEST_PORT_A,
4397 TEST_PORT_B, &ki) != 1) e(0);
4398 if (ki.ki_type != SOCK_DGRAM) e(0);
4399 if (ki.ki_tstate != 0) e(0);
4400 if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
4401 if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
4402 if (ki.ki_sndq != 0) e(0);
4403 if (ki.ki_rcvq < 3) e(0); /* size is rounded up */
4405 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP,
4406 TEST_PORT_A, TEST_PORT_B, &ki) != 0) e(0);
4408 if (close(fd[0]) != 0) e(0);
4409 if (close(fd[1]) != 0) e(0);
4411 /* Test IPv6 sockets as well. */
4412 if ((fd[0] = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
4414 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP, 0, 0,
4415 &ki) != 0) e(0);
4417 memset(&lsin6, 0, sizeof(lsin6));
4418 lsin6.sin6_len = sizeof(lsin6);
4419 lsin6.sin6_family = AF_INET6;
4420 lsin6.sin6_port = htons(TEST_PORT_A);
4421 memcpy(&lsin6.sin6_addr, &in6addr_loopback, sizeof(lsin6.sin6_addr));
4422 if (bind(fd[0], (struct sockaddr *)&lsin6, sizeof(lsin6)) != 0) e(0);
4424 memset(&rsin6, 0, sizeof(rsin6));
4425 rsin6.sin6_len = sizeof(rsin6);
4426 rsin6.sin6_family = AF_INET6;
4428 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP,
4429 TEST_PORT_A, 0, &ki) != 1) e(0);
4430 if (ki.ki_type != SOCK_DGRAM) e(0);
4431 if (ki.ki_tstate != 0) e(0);
4432 if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
4433 if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
4434 if (ki.ki_sndq != 0) e(0);
4435 if (ki.ki_rcvq != 0) e(0);
4436 if (!(ki.ki_pflags & IN6P_IPV6_V6ONLY)) e(0);
4438 rsin6.sin6_port = htons(TEST_PORT_B);
4439 memcpy(&rsin6.sin6_addr, &in6addr_loopback, sizeof(rsin6.sin6_addr));
4440 if (connect(fd[0], (struct sockaddr *)&rsin6, sizeof(rsin6)) != 0)
4441 e(0);
4443 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP,
4444 TEST_PORT_A, TEST_PORT_B, &ki) != 1) e(0);
4445 if (ki.ki_type != SOCK_DGRAM) e(0);
4446 if (ki.ki_tstate != 0) e(0);
4447 if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
4448 if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
4449 if (ki.ki_sndq != 0) e(0);
4450 if (ki.ki_rcvq != 0) e(0);
4451 if (!(ki.ki_pflags & IN6P_IPV6_V6ONLY)) e(0);
4453 if (close(fd[0]) != 0) e(0);
4455 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP,
4456 TEST_PORT_A, TEST_PORT_B, &ki) != 0) e(0);
4460 * Test socket enumeration of sockets using IPv4-mapped IPv6 addresses.
4462 static void
4463 test91x(void)
4465 struct sockaddr_in6 sin6;
4466 struct sockaddr_in sin;
4467 socklen_t len;
4468 struct kinfo_pcb ki;
4469 unsigned short local_port, remote_port;
4470 int fd, fd2, fd3, val;
4472 subtest = 24;
4475 * Test that information from an IPv6 socket bound to an IPv4-mapped
4476 * IPv6 address is as expected. For socket enumeration, due to lwIP
4477 * limitations we return an IPv4 address instead of an IPv4-mapped IPv6
4478 * address, and that is what this test checks for various sockets.
4480 if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
4482 val = 0;
4483 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
4484 e(0);
4486 memset(&sin6, 0, sizeof(sin6));
4487 sin6.sin6_family = AF_INET6;
4488 if (inet_pton(AF_INET6, "::ffff:"LOOPBACK_IPV4, &sin6.sin6_addr) != 1)
4489 e(0);
4491 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
4493 len = sizeof(sin6);
4494 if (getsockname(fd, (struct sockaddr *)&sin6, &len) != 0) e(0);
4495 if (len != sizeof(sin6)) e(0);
4496 if (sin6.sin6_len != sizeof(sin6)) e(0);
4497 if (sin6.sin6_family != AF_INET6) e(0);
4498 local_port = ntohs(sin6.sin6_port);
4500 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, local_port,
4501 0, &ki) != 0) e(0);
4503 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, local_port,
4504 0, &ki) != 1) e(0);
4506 if (ki.ki_type != SOCK_STREAM) e(0);
4507 if (ki.ki_tstate != TCPS_CLOSED) e(0);
4509 memcpy(&sin, &ki.ki_src, sizeof(sin));
4510 if (sin.sin_len != sizeof(sin)) e(0);
4511 if (sin.sin_family != AF_INET) e(0);
4512 if (sin.sin_port != htons(local_port)) e(0);
4513 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4515 memcpy(&sin, &ki.ki_dst, sizeof(sin));
4516 if (sin.sin_len != sizeof(sin)) e(0);
4517 if (sin.sin_family != AF_INET) e(0);
4518 if (sin.sin_port != htons(0)) e(0);
4519 if (sin.sin_addr.s_addr != htonl(INADDR_ANY)) e(0);
4521 if (listen(fd, 1) != 0) e(0);
4524 * Test that information from an accepted (IPv6) socket is correct
4525 * for a connection from an IPv4 address.
4527 if ((fd2 = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
4529 memset(&sin, 0, sizeof(sin));
4530 sin.sin_family = AF_INET;
4531 sin.sin_port = htons(local_port);
4532 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4534 if (connect(fd2, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
4536 len = sizeof(sin);
4537 if (getsockname(fd2, (struct sockaddr *)&sin, &len) != 0) e(0);
4538 if (len != sizeof(sin)) e(0);
4539 if (sin.sin_len != sizeof(sin)) e(0);
4540 if (sin.sin_family != AF_INET) e(0);
4541 remote_port = ntohs(sin.sin_port);
4543 len = sizeof(sin6);
4544 if ((fd3 = accept(fd, (struct sockaddr *)&sin6, &len)) < 0) e(0);
4545 if (len != sizeof(sin6)) e(0);
4546 if (sin6.sin6_len != sizeof(sin6)) e(0);
4547 if (sin6.sin6_family != AF_INET6) e(0);
4548 if (sin6.sin6_port != htons(remote_port)) e(0);
4549 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4550 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4551 e(0);
4553 len = sizeof(sin6);
4554 if (getsockname(fd3, (struct sockaddr *)&sin6, &len) != 0) e(0);
4555 if (len != sizeof(sin6)) e(0);
4556 if (sin6.sin6_len != sizeof(sin6)) e(0);
4557 if (sin6.sin6_family != AF_INET6) e(0);
4558 if (sin6.sin6_port != htons(local_port)) e(0);
4559 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4560 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4561 e(0);
4563 len = sizeof(sin6);
4564 if (getpeername(fd3, (struct sockaddr *)&sin6, &len) != 0) e(0);
4565 if (len != sizeof(sin6)) e(0);
4566 if (sin6.sin6_len != sizeof(sin6)) e(0);
4567 if (sin6.sin6_family != AF_INET6) e(0);
4568 if (sin6.sin6_port != htons(remote_port)) e(0);
4569 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4570 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4571 e(0);
4573 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, local_port,
4574 remote_port, &ki) != 0) e(0);
4576 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, local_port,
4577 remote_port, &ki) != 1) e(0);
4579 if (ki.ki_type != SOCK_STREAM) e(0);
4580 if (ki.ki_tstate != TCPS_ESTABLISHED) e(0);
4582 memcpy(&sin, &ki.ki_src, sizeof(sin));
4583 if (sin.sin_len != sizeof(sin)) e(0);
4584 if (sin.sin_family != AF_INET) e(0);
4585 if (sin.sin_port != htons(local_port)) e(0);
4586 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4588 memcpy(&sin, &ki.ki_dst, sizeof(sin));
4589 if (sin.sin_len != sizeof(sin)) e(0);
4590 if (sin.sin_family != AF_INET) e(0);
4591 if (sin.sin_port != htons(remote_port)) e(0);
4592 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4594 if (close(fd3) != 0) e(0);
4595 if (close(fd2) != 0) e(0);
4597 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, local_port,
4598 remote_port, &ki) != 0) e(0);
4600 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, local_port,
4601 remote_port, &ki) != 1) e(0);
4603 if (ki.ki_type != SOCK_STREAM) e(0);
4604 if (ki.ki_tstate != TCPS_TIME_WAIT) e(0);
4606 memcpy(&sin, &ki.ki_src, sizeof(sin));
4607 if (sin.sin_len != sizeof(sin)) e(0);
4608 if (sin.sin_family != AF_INET) e(0);
4609 if (sin.sin_port != htons(local_port)) e(0);
4610 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4612 memcpy(&sin, &ki.ki_dst, sizeof(sin));
4613 if (sin.sin_len != sizeof(sin)) e(0);
4614 if (sin.sin_family != AF_INET) e(0);
4615 if (sin.sin_port != htons(remote_port)) e(0);
4616 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4619 * Test that information from a connected (IPv6) socket is correct
4620 * after connecting it to an IPv4 address.
4622 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
4624 val = 0;
4625 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
4626 e(0);
4628 memset(&sin6, 0, sizeof(sin6));
4629 sin6.sin6_family = AF_INET6;
4630 sin6.sin6_port = htons(local_port);
4631 if (inet_pton(AF_INET6, "::ffff:"LOOPBACK_IPV4, &sin6.sin6_addr) != 1)
4632 e(0);
4634 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
4636 len = sizeof(sin6);
4637 if (getsockname(fd2, (struct sockaddr *)&sin6, &len) != 0) e(0);
4638 if (len != sizeof(sin6)) e(0);
4639 if (sin6.sin6_len != sizeof(sin6)) e(0);
4640 if (sin6.sin6_family != AF_INET6) e(0);
4641 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4642 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4643 e(0);
4644 remote_port = ntohs(sin6.sin6_port);
4646 len = sizeof(sin6);
4647 if (getpeername(fd2, (struct sockaddr *)&sin6, &len) != 0) e(0);
4648 if (len != sizeof(sin6)) e(0);
4649 if (sin6.sin6_len != sizeof(sin6)) e(0);
4650 if (sin6.sin6_family != AF_INET6) e(0);
4651 if (sin6.sin6_port != htons(local_port)) e(0);
4652 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4653 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4654 e(0);
4656 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP,
4657 remote_port, local_port, &ki) != 0) e(0);
4659 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, remote_port,
4660 local_port, &ki) != 1) e(0);
4662 if (ki.ki_type != SOCK_STREAM) e(0);
4663 if (ki.ki_tstate != TCPS_ESTABLISHED) e(0);
4665 memcpy(&sin, &ki.ki_src, sizeof(sin));
4666 if (sin.sin_len != sizeof(sin)) e(0);
4667 if (sin.sin_family != AF_INET) e(0);
4668 if (sin.sin_port != htons(remote_port)) e(0);
4669 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4671 memcpy(&sin, &ki.ki_dst, sizeof(sin));
4672 if (sin.sin_len != sizeof(sin)) e(0);
4673 if (sin.sin_family != AF_INET) e(0);
4674 if (sin.sin_port != htons(local_port)) e(0);
4675 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4677 len = sizeof(sin6);
4678 if ((fd3 = accept(fd, (struct sockaddr *)&sin6, &len)) < 0) e(0);
4679 if (len != sizeof(sin6)) e(0);
4680 if (sin6.sin6_len != sizeof(sin6)) e(0);
4681 if (sin6.sin6_family != AF_INET6) e(0);
4682 if (sin6.sin6_port != htons(remote_port)) e(0);
4683 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4684 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4685 e(0);
4687 if (close(fd2) != 0) e(0);
4688 if (close(fd3) != 0) e(0);
4689 if (close(fd) != 0) e(0);
4692 * Do one more test on an accepted socket, now without binding the
4693 * listening socket to an IPv4-mapped IPv6 address.
4695 if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
4697 val = 0;
4698 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
4699 e(0);
4701 memset(&sin6, 0, sizeof(sin6));
4702 sin6.sin6_family = AF_INET6;
4703 memcpy(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr));
4705 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
4707 len = sizeof(sin6);
4708 if (getsockname(fd, (struct sockaddr *)&sin6, &len) != 0) e(0);
4709 if (len != sizeof(sin6)) e(0);
4710 if (sin6.sin6_len != sizeof(sin6)) e(0);
4711 if (sin6.sin6_family != AF_INET6) e(0);
4712 local_port = ntohs(sin6.sin6_port);
4714 if (listen(fd, 1) != 0) e(0);
4716 if ((fd2 = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
4718 memset(&sin, 0, sizeof(sin));
4719 sin.sin_family = AF_INET;
4720 sin.sin_port = htons(local_port);
4721 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4722 if (connect(fd2, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
4724 len = sizeof(sin);
4725 if (getsockname(fd2, (struct sockaddr *)&sin, &len) != 0) e(0);
4726 if (len != sizeof(sin)) e(0);
4727 if (sin.sin_len != sizeof(sin)) e(0);
4728 if (sin.sin_family != AF_INET) e(0);
4729 remote_port = ntohs(sin.sin_port);
4731 len = sizeof(sin6);
4732 if ((fd3 = accept(fd, (struct sockaddr *)&sin6, &len)) < 0) e(0);
4733 if (len != sizeof(sin6)) e(0);
4734 if (sin6.sin6_len != sizeof(sin6)) e(0);
4735 if (sin6.sin6_family != AF_INET6) e(0);
4736 if (sin6.sin6_port != htons(remote_port)) e(0);
4737 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4738 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4739 e(0);
4741 len = sizeof(sin6);
4742 if (getsockname(fd3, (struct sockaddr *)&sin6, &len) != 0) e(0);
4743 if (len != sizeof(sin6)) e(0);
4744 if (sin6.sin6_len != sizeof(sin6)) e(0);
4745 if (sin6.sin6_family != AF_INET6) e(0);
4746 if (sin6.sin6_port != htons(local_port)) e(0);
4747 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4748 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4749 e(0);
4751 len = sizeof(sin6);
4752 if (getpeername(fd3, (struct sockaddr *)&sin6, &len) != 0) e(0);
4753 if (len != sizeof(sin6)) e(0);
4754 if (sin6.sin6_len != sizeof(sin6)) e(0);
4755 if (sin6.sin6_family != AF_INET6) e(0);
4756 if (sin6.sin6_port != htons(remote_port)) e(0);
4757 if (!IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) e(0);
4758 if (sin6.sin6_addr.__u6_addr.__u6_addr32[3] != htonl(INADDR_LOOPBACK))
4759 e(0);
4761 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP, local_port,
4762 remote_port, &ki) != 0) e(0);
4764 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP, local_port,
4765 remote_port, &ki) != 1) e(0);
4767 if (ki.ki_type != SOCK_STREAM) e(0);
4768 if (ki.ki_tstate != TCPS_ESTABLISHED) e(0);
4770 memcpy(&sin, &ki.ki_src, sizeof(sin));
4771 if (sin.sin_len != sizeof(sin)) e(0);
4772 if (sin.sin_family != AF_INET) e(0);
4773 if (sin.sin_port != htons(local_port)) e(0);
4774 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4776 memcpy(&sin, &ki.ki_dst, sizeof(sin));
4777 if (sin.sin_len != sizeof(sin)) e(0);
4778 if (sin.sin_family != AF_INET) e(0);
4779 if (sin.sin_port != htons(remote_port)) e(0);
4780 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4782 if (close(fd3) != 0) e(0);
4783 if (close(fd2) != 0) e(0);
4784 if (close(fd) != 0) e(0);
4787 * Do some very simple UDP socket enumeration tests. The rest is
4788 * already tested elsewhere.
4790 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
4792 val = 0;
4793 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
4794 e(0);
4796 memset(&sin6, 0, sizeof(sin6));
4797 sin6.sin6_family = AF_INET6;
4798 if (inet_pton(AF_INET6, "::ffff:"LOOPBACK_IPV4, &sin6.sin6_addr) != 1)
4799 e(0);
4801 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
4803 len = sizeof(sin6);
4804 if (getsockname(fd, (struct sockaddr *)&sin6, &len) != 0) e(0);
4805 if (len != sizeof(sin6)) e(0);
4806 if (sin6.sin6_len != sizeof(sin6)) e(0);
4807 if (sin6.sin6_family != AF_INET6) e(0);
4808 local_port = ntohs(sin6.sin6_port);
4810 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP, local_port,
4811 0, &ki) != 0) e(0);
4813 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP, local_port,
4814 0, &ki) != 1) e(0);
4816 if (ki.ki_type != SOCK_DGRAM) e(0);
4817 if (ki.ki_tstate != 0) e(0);
4819 memcpy(&sin, &ki.ki_src, sizeof(sin));
4820 if (sin.sin_len != sizeof(sin)) e(0);
4821 if (sin.sin_family != AF_INET) e(0);
4822 if (sin.sin_port != htons(local_port)) e(0);
4823 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4825 memcpy(&sin, &ki.ki_dst, sizeof(sin));
4826 if (sin.sin_len != sizeof(sin)) e(0);
4827 if (sin.sin_family != AF_INET) e(0);
4828 if (sin.sin_port != htons(0)) e(0);
4829 if (sin.sin_addr.s_addr != htonl(INADDR_ANY)) e(0);
4831 if (close(fd) != 0) e(0);
4833 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
4835 val = 0;
4836 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
4837 e(0);
4839 memset(&sin6, 0, sizeof(sin6));
4840 sin6.sin6_family = AF_INET6;
4841 sin6.sin6_port = htons(TEST_PORT_A);
4842 if (inet_pton(AF_INET6, "::ffff:"LOOPBACK_IPV4, &sin6.sin6_addr) != 1)
4843 e(0);
4845 if (connect(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
4847 len = sizeof(sin6);
4848 if (getsockname(fd, (struct sockaddr *)&sin6, &len) != 0) e(0);
4849 if (len != sizeof(sin6)) e(0);
4850 if (sin6.sin6_len != sizeof(sin6)) e(0);
4851 if (sin6.sin6_family != AF_INET6) e(0);
4852 local_port = ntohs(sin6.sin6_port);
4854 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP, local_port,
4855 TEST_PORT_A, &ki) != 0) e(0);
4857 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP, local_port,
4858 TEST_PORT_A, &ki) != 1) e(0);
4860 if (ki.ki_type != SOCK_DGRAM) e(0);
4861 if (ki.ki_tstate != 0) e(0);
4863 memcpy(&sin, &ki.ki_src, sizeof(sin));
4864 if (sin.sin_len != sizeof(sin)) e(0);
4865 if (sin.sin_family != AF_INET) e(0);
4866 if (sin.sin_port != htons(local_port)) e(0);
4867 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4869 memcpy(&sin, &ki.ki_dst, sizeof(sin));
4870 if (sin.sin_len != sizeof(sin)) e(0);
4871 if (sin.sin_family != AF_INET) e(0);
4872 if (sin.sin_port != htons(TEST_PORT_A)) e(0);
4873 if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
4875 if (close(fd) != 0) e(0);
4879 * Test local and remote IPv6 address handling. In particular, test scope IDs
4880 * and IPv4-mapped IPv6 addresses.
4882 static void
4883 test91y(void)
4886 subtest = 25;
4888 socklib_test_addrs(SOCK_STREAM, 0);
4890 socklib_test_addrs(SOCK_DGRAM, 0);
4894 * Test low-memory conditions for TCP.
4896 static void
4897 test91z(void)
4899 struct sockaddr_in6 sin6;
4900 socklen_t len;
4901 unsigned char buf[CHUNK];
4902 struct timeval tv;
4903 unsigned int i, j, k;
4904 ssize_t res, left;
4905 pid_t pid, pid2;
4906 static int fds[OPEN_MAX];
4907 static size_t pos[OPEN_MAX];
4908 int lfd, pfd[2], val, sndlen, rcvlen, status;
4910 subtest = 26;
4913 * We use custom send and receive buffer sizes, such that we can
4914 * trigger the case that we run out of send buffers without causing
4915 * buffers used on the receiving side to empty the buffer pool first.
4916 * While the latter case is not unrealistic for practical scenarios, it
4917 * is not what we want to test here. It would also cause practical
4918 * problems for this test, as the result may be that the loopback
4919 * interface (that we use here) starts dropping packets due to being
4920 * unable to make copies.
4922 * The aim with these two is that the ratio is such that we run into
4923 * the 75% usage limit for the send side without using the other 25%
4924 * for receiving purposes. Since our TCP buffer merging guarantees at
4925 * most a 50% overhead on the receiving side, the minimum ratio of 5:1
4926 * translates to a worst-case ratio is 10:3 which is just above 75%.
4927 * Thus, we should be able to use 80K:16K. Instead, we use 128K:16K,
4928 * because otherwise we will run out of sockets before we run out of
4929 * buffers. After all, we are not generating any traffic on the socket
4930 * pairs in the other direction--something for which we do provision.
4932 sndlen = 131072;
4933 rcvlen = 16384;
4936 * Unfortunately, filling up receive queues is not easy, and for any
4937 * size other than the window size (which is by nature also the minimum
4938 * receive queue length that may be set) we would need to work around
4939 * the same issue described in fill_tcp_bufs(), which would massively
4940 * complicate the implementation of this subtest. For now, make sure
4941 * that inconsistent internal changes will trigger this assert.
4943 assert(rcvlen == WINDOW_SIZE);
4945 if ((lfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
4947 memset(&sin6, 0, sizeof(sin6));
4948 sin6.sin6_family = AF_INET6;
4949 memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
4951 if (bind(lfd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
4953 len = sizeof(sin6);
4954 if (getsockname(lfd, (struct sockaddr *)&sin6, &len) != 0) e(0);
4956 if (listen(lfd, 1) != 0) e(0);
4959 * Start a child process for the receiving ends. We have to use
4960 * another process because we aim to open a total concurrent number of
4961 * TCP sockets that exceeds OPEN_MAX.
4963 if (pipe(pfd) != 0) e(0);
4965 pid = fork();
4966 switch (pid) {
4967 case 0:
4968 errct = 0;
4970 if (close(lfd) != 0) e(0);
4971 if (close(pfd[1]) != 0) e(0);
4973 /* Create socket pairs. */
4974 for (i = 0; ; i++) {
4975 if (i == __arraycount(fds)) e(0);
4977 if ((fds[i] = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
4978 e(0);
4980 if (connect(fds[i], (struct sockaddr *)&sin6,
4981 sizeof(sin6)) != 0) e(0);
4983 val = 1;
4984 if (setsockopt(fds[i], IPPROTO_TCP, TCP_NODELAY, &val,
4985 sizeof(val)) != 0) e(0);
4987 if (setsockopt(fds[i], SOL_SOCKET, SO_RCVBUF, &rcvlen,
4988 sizeof(rcvlen)) != 0) e(0);
4990 /* Synchronization point A. */
4991 if (read(pfd[0], &k, sizeof(k)) != sizeof(k)) e(0);
4992 if (k == 0)
4993 break;
4996 /* Synchronization point B. */
4997 if (read(pfd[0], &k, sizeof(k)) != sizeof(k)) e(0);
4998 if (k != 2) e(0);
5000 /* Receive some data from one socket. */
5001 pos[0] = 0;
5002 for (left = sizeof(buf) * 2; left > 0; left -= res) {
5003 res = recv(fds[0], buf, MIN(left, sizeof(buf)), 0);
5004 if (res <= 0) e(0);
5005 if (res > left) e(0);
5007 for (j = 0; j < res; j++)
5008 if (buf[j] != (unsigned char)(pos[0]++)) e(0);
5011 /* Synchronization point C. */
5012 if (read(pfd[0], &k, sizeof(k)) != sizeof(k)) e(0);
5013 if (k != 3) e(0);
5016 * Receive all remaining data from all sockets. Do this in two
5017 * steps. First enlarge the receive buffer and empty it, so
5018 * that upon resumption, all remaining data is transferred from
5019 * the sender to the receiver in one go. Then actually wait
5020 * for any remaining data, and the EOF. If we do both in one
5021 * step, this part of the test will take several minutes to
5022 * complete. Note that the last socket needs special treatment
5023 * because its send queue may not have been filled entirely.
5025 for (k = 0; k <= i; k++) {
5026 if (setsockopt(fds[i], SOL_SOCKET, SO_RCVBUF, &rcvlen,
5027 sizeof(rcvlen)) != 0) e(0);
5029 pos[k] = (k == 0) ? (sizeof(buf) * 2) : 0;
5031 for (left = sndlen + rcvlen - pos[k]; left > 0;
5032 left -= res) {
5033 res = recv(fds[k], buf, MIN(left, sizeof(buf)),
5034 MSG_DONTWAIT);
5035 if (res == -1 && errno == EWOULDBLOCK)
5036 break;
5037 if (res == 0 && k == i) {
5038 pos[i] = sndlen + rcvlen;
5039 break;
5041 if (res <= 0) e(0);
5042 if (res > left) e(0);
5044 for (j = 0; j < res; j++)
5045 if (buf[j] != (unsigned char)(k +
5046 pos[k]++)) e(0);
5050 for (k = 0; k <= i; k++) {
5051 for (left = sndlen + rcvlen - pos[k]; left > 0;
5052 left -= res) {
5053 res = recv(fds[k], buf, MIN(left, sizeof(buf)),
5055 if (res == 0 && k == i)
5056 break;
5057 if (res <= 0) e(0);
5058 if (res > left) e(0);
5060 for (j = 0; j < res; j++)
5061 if (buf[j] != (unsigned char)(k +
5062 pos[k]++)) e(0);
5065 if (recv(fds[k], buf, 1, 0) != 0) e(0);
5068 /* Clean up. */
5069 do {
5070 if (close(fds[i]) != 0) e(0);
5071 } while (i-- > 0);
5073 exit(errct);
5074 case -1:
5075 e(0);
5078 if (close(pfd[0]) != 0) e(0);
5080 for (i = 0; ; i++) {
5081 if (i == __arraycount(fds)) e(0);
5083 len = sizeof(sin6);
5084 if ((fds[i] = accept(lfd, (struct sockaddr *)&sin6, &len)) < 0)
5085 e(0);
5087 val = 1;
5088 if (setsockopt(fds[i], IPPROTO_TCP, TCP_NODELAY, &val,
5089 sizeof(val)) != 0) e(0);
5091 if (setsockopt(fds[i], SOL_SOCKET, SO_SNDBUF, &sndlen,
5092 sizeof(sndlen)) != 0) e(0);
5095 * Try to pump as much data into one end of the socket. This
5096 * may fail at any time due to being out of buffers, so we use
5097 * a send timeout to break the resulting blocking call.
5099 tv.tv_sec = 1;
5100 tv.tv_usec = 0;
5102 if (setsockopt(fds[i], SOL_SOCKET, SO_SNDTIMEO, &tv,
5103 sizeof(tv)) != 0) e(0);
5106 * Since buffer corruption is most likely to be detected when
5107 * lots of buffers are actually in use, also make sure that we
5108 * (eventually) receive what we send.
5110 res = sizeof(buf);
5111 pos[i] = 0;
5112 for (left = sndlen + rcvlen; left > 0; left -= res) {
5113 /* One byte at a time, for simplicity.. */
5114 for (j = sizeof(buf) - res; j < sizeof(buf); j++)
5115 buf[j] = (unsigned char)(i + pos[i]++);
5117 res = send(fds[i], buf, MIN(left, sizeof(buf)), 0);
5118 if (res == -1 && errno == EWOULDBLOCK)
5119 break;
5121 if (res <= 0) e(0);
5122 if (res > left) e(0);
5124 if (res < sizeof(buf))
5125 memmove(buf, &buf[res], sizeof(buf) - res);
5128 /* Synchronization point A. */
5129 k = (left == 0);
5130 if (write(pfd[1], &k, sizeof(k)) != sizeof(k)) e(0);
5132 if (left > 0)
5133 break;
5136 if (close(lfd) != 0) e(0);
5139 * We should always be able to fill at least two socket pairs' buffers
5140 * completely this way; in fact with a 512x512 pool it should be three,
5141 * but some sockets may be in use in the background. With the default
5142 * settings of the memory pool system, we should ideally be able to get
5143 * up to 96 socket pairs.
5145 if (i < 3) e(0);
5148 * Mix things up a bit by fully shutting down one file descriptor and
5149 * closing another, both on the sending side.
5151 if (shutdown(fds[1], SHUT_RDWR) != 0) e(0);
5152 if (close(fds[2]) != 0) e(0);
5155 * Make sure that when there is buffer space available again, pending
5156 * send() calls get woken up. We do this using a child process that
5157 * blocks on a send() call and a parent process that frees up some
5158 * buffer space by receiving from another socket.
5160 pid2 = fork();
5161 switch (pid2) {
5162 case 0:
5163 errct = 0;
5165 /* Disable the timeout again. */
5166 tv.tv_sec = 0;
5167 tv.tv_usec = 0;
5169 if (setsockopt(fds[i], SOL_SOCKET, SO_SNDTIMEO, &tv,
5170 sizeof(tv)) != 0) e(0);
5173 * Try sending. This should block until there are more buffers
5174 * available.
5176 res = send(fds[i], buf, MIN(left, sizeof(buf)), 0);
5177 if (res <= 0) e(0);
5178 if (res > left) e(0);
5180 exit(errct);
5182 case -1:
5183 e(0);
5186 /* Make sure the child's send() call is indeed hanging. */
5187 sleep(2);
5189 if (waitpid(pid2, &status, WNOHANG) != 0) e(0);
5191 /* Then receive some data on another socket. */
5193 /* Synchronization point B. */
5194 k = 2;
5195 if (write(pfd[1], &k, sizeof(k)) != sizeof(k)) e(0);
5197 /* The send() call should now be woken up, eventually. */
5198 if (waitpid(pid2, &status, 0) != pid2) e(0);
5199 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
5202 * Shut down all (remaining) sending file descriptors for sending, so
5203 * that we can receive until we get EOF. For all but the last socket,
5204 * we must get the full size of what we intended to send; for the first
5205 * socket, we have already received two buffers worth of data. Note
5206 * that the receipt may take a while, mainly because it takes some time
5207 * for sockets that were previously blocked to get going again.
5209 for (k = 0; k <= i; k++) {
5210 if (k != 1 && k != 2 && shutdown(fds[k], SHUT_WR) != 0)
5211 e(0);
5214 /* Synchronization point C. */
5215 k = 3;
5216 if (write(pfd[1], &k, sizeof(k)) != sizeof(k)) e(0);
5218 if (close(pfd[1]) != 0) e(0);
5220 /* Wait for the child to receive everything and terminate. */
5221 if (waitpid(pid, &status, 0) != pid) e(0);
5222 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
5224 /* Clean up. */
5225 do {
5226 if (i != 2 && close(fds[i]) != 0) e(0);
5227 } while (i-- > 0);
5231 * Test multicast support.
5233 static void
5234 test91aa(void)
5237 subtest = 27;
5239 socklib_test_multicast(SOCK_DGRAM, 0);
5243 * Test that putting an unbound TCP socket in listening mode will bind the
5244 * socket to a port.
5246 static void
5247 test91ab(void)
5249 struct sockaddr_in sin;
5250 struct sockaddr_in6 sin6;
5251 socklen_t len;
5252 int fd;
5254 subtest = 28;
5256 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) e(0);
5258 if (listen(fd, 1) != 0) e(0);
5260 len = sizeof(sin);
5261 if (getsockname(fd, (struct sockaddr *)&sin, &len) != 0) e(0);
5262 if (len != sizeof(sin)) e(0);
5263 if (sin.sin_len != sizeof(sin)) e(0);
5264 if (sin.sin_family != AF_INET) e(0);
5265 if (sin.sin_port == htons(0)) e(0);
5266 if (sin.sin_addr.s_addr != htonl(INADDR_ANY)) e(0);
5268 if (close(fd) != 0) e(0);
5270 if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
5272 if (listen(fd, 1) != 0) e(0);
5274 len = sizeof(sin6);
5275 if (getsockname(fd, (struct sockaddr *)&sin6, &len) != 0) e(0);
5276 if (len != sizeof(sin6)) e(0);
5277 if (sin6.sin6_len != sizeof(sin6)) e(0);
5278 if (sin6.sin6_family != AF_INET6) e(0);
5279 if (sin6.sin6_port == htons(0)) e(0);
5280 if (memcmp(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr)) != 0)
5281 e(0);
5283 if (close(fd) != 0) e(0);
5287 * Test for connecting to the same remote TCP endpoint with the same local
5288 * endpoint twice in a row. The second connection should fail due to the
5289 * TIME_WAIT state left behind from the first connection, but this previously
5290 * caused an infinite loop instead. lwIP bug #50498.
5292 static void
5293 test91ac(void)
5295 struct sockaddr_in6 lsin6, rsin6;
5296 socklen_t len;
5297 int fd, fd2, fd3;
5299 subtest = 29;
5301 if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
5303 memset(&rsin6, 0, sizeof(rsin6));
5304 rsin6.sin6_family = AF_INET6;
5305 memcpy(&rsin6.sin6_addr, &in6addr_loopback, sizeof(rsin6.sin6_addr));
5307 if (bind(fd, (struct sockaddr *)&rsin6, sizeof(rsin6)) != 0) e(0);
5309 len = sizeof(rsin6);
5310 if (getsockname(fd, (struct sockaddr *)&rsin6, &len) != 0) e(0);
5311 if (len != sizeof(rsin6)) e(0);
5313 if (listen(fd, 1) != 0) e(0);
5315 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
5317 if (connect(fd2, (struct sockaddr *)&rsin6, sizeof(rsin6)) != 0) e(0);
5319 if ((fd3 = accept(fd, (struct sockaddr *)&lsin6, &len)) < 0) e(0);
5320 if (len != sizeof(rsin6)) e(0);
5322 /* The server end must initiate the close for this to work. */
5323 if (close(fd3) != 0) e(0);
5325 if (close(fd2) != 0) e(0);
5327 if ((fd2 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) e(0);
5329 if (bind(fd2, (struct sockaddr *)&lsin6, sizeof(lsin6)) != 0) e(0);
5332 * The timeout should occur almost immediately, due to a shortcut in
5333 * lwIP (which was also the source of the problem here). The actual
5334 * error code is not really important though. In fact, if in the
5335 * future the connection does get established, that is still not an
5336 * issue - in fact, it would be nice to have a working rsh(1), which is
5337 * how this problem showed up in the first place - but at the very
5338 * least the service should keep operating.
5340 if (connect(fd2, (struct sockaddr *)&rsin6, sizeof(rsin6)) != -1) e(0);
5342 if (close(fd2) != 0) e(0);
5343 if (close(fd) != 0) e(0);
5347 * Test program for LWIP TCP/UDP sockets.
5350 main(int argc, char ** argv)
5352 unsigned int m;
5353 int i;
5355 start(91);
5357 if (argc == 2)
5358 m = atoi(argv[1]);
5359 else
5360 m = 0xFFFFFFFF;
5362 for (i = 0; i < ITERATIONS; i++) {
5363 if (m & 0x00000001) test91a();
5364 if (m & 0x00000002) test91b();
5365 if (m & 0x00000004) test91c();
5366 if (m & 0x00000008) test91d();
5367 if (m & 0x00000010) test91e();
5368 if (m & 0x00000020) test91f();
5369 if (m & 0x00000040) test91g();
5370 if (m & 0x00000080) test91h();
5371 if (m & 0x00000100) test91i();
5372 if (m & 0x00000200) test91j();
5373 if (m & 0x00000400) test91k();
5374 if (m & 0x00000800) test91l();
5375 if (m & 0x00001000) test91m();
5376 if (m & 0x00002000) test91n();
5377 if (m & 0x00004000) test91o();
5378 if (m & 0x00008000) test91p();
5379 if (m & 0x00010000) test91q();
5380 if (m & 0x00020000) test91r();
5381 if (m & 0x00040000) test91s();
5382 if (m & 0x00080000) test91t();
5383 if (m & 0x00100000) test91u();
5384 if (m & 0x00200000) test91v();
5385 if (m & 0x00400000) test91w();
5386 if (m & 0x00800000) test91x();
5387 if (m & 0x01000000) test91y();
5388 if (m & 0x02000000) test91z();
5389 if (m & 0x04000000) test91aa();
5390 if (m & 0x08000000) test91ab();
5391 if (m & 0x10000000) test91ac();
5394 quit();
5395 /* NOTREACHED */