Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / tests / socklib.c
blobaf09280ee94caa17dfa8d5a3e0510259a3f9f7c5
1 /*
2 * Socket test code library. This file contains code that is worth sharing
3 * between TCP/IP and UDS tests, as well as code that is worth sharing between
4 * various TCP/IP tests.
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <signal.h>
10 #include <sys/param.h>
11 #include <sys/wait.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #include <sys/sysctl.h>
15 #include <net/if.h>
16 #include <netinet/in.h>
17 #include <netinet/ip.h>
18 #include <netinet6/in6_var.h>
19 #include <arpa/inet.h>
20 #include <ifaddrs.h>
21 #include <unistd.h>
22 #include <fcntl.h>
24 #include "common.h"
25 #include "socklib.h"
27 #define TEST_PORT_A 12345 /* this port should be free and usable */
28 #define TEST_PORT_B 12346 /* this port should be free and usable */
30 #define LOOPBACK_IFNAME "lo0" /* loopback interface name */
31 #define LOOPBACK_IPV4 "127.0.0.1" /* IPv4 address */
32 #define LOOPBACK_IPV6_LL "fe80::1" /* link-local IPv6 address */
34 /* These address should simply eat all packets. */
35 #define TEST_BLACKHOLE_IPV4 "127.255.0.254"
36 #define TEST_BLACKHOLE_IPV6 "::2"
37 #define TEST_BLACKHOLE_IPV6_LL "fe80::ffff"
39 /* Addresses for multicast-related testing. */
40 #define TEST_MULTICAST_IPV4 "233.252.0.1" /* RFC 5771 Sec. 9.2 */
41 #define TEST_MULTICAST_IPV6 "ff0e::db8:0:1" /* RFC 6676 Sec. 3 */
42 #define TEST_MULTICAST_IPV6_LL "ff02::db8:0:1"
43 #define TEST_MULTICAST_IPV6_BAD "ff00::db8:0:1"
45 #define BAD_IFINDEX 255 /* guaranteed not to belong to an interface */
47 /* 0 = check, 1 = generate source, 2 = generate CSV */
48 #define SOCKLIB_SWEEP_GENERATE 0
50 #if SOCKLIB_SWEEP_GENERATE
51 /* Link against minix/usr.bin/trace/error.o to make this work! */
52 const char *get_error_name(int err);
54 #if SOCKLIB_SWEEP_GENERATE == 2
55 static const char *statename[S_MAX] = {
56 "S_NEW",
57 "S_N_SHUT_R",
58 "S_N_SHUT_W",
59 "S_N_SHUT_RW",
60 "S_BOUND",
61 "S_LISTENING",
62 "S_L_SHUT_R",
63 "S_L_SHUT_W",
64 "S_L_SHUT_RW",
65 "S_CONNECTING",
66 "S_C_SHUT_R",
67 "S_C_SHUT_W",
68 "S_C_SHUT_RW",
69 "S_CONNECTED",
70 "S_ACCEPTED",
71 "S_SHUT_R",
72 "S_SHUT_W",
73 "S_SHUT_RW",
74 "S_RSHUT_R",
75 "S_RSHUT_W",
76 "S_RSHUT_RW",
77 "S_SHUT2_R",
78 "S_SHUT2_W",
79 "S_SHUT2_RW",
80 "S_PRE_EOF",
81 "S_AT_EOF",
82 "S_POST_EOF",
83 "S_PRE_SHUT_R",
84 "S_EOF_SHUT_R",
85 "S_POST_SHUT_R",
86 "S_PRE_SHUT_W",
87 "S_EOF_SHUT_W",
88 "S_POST_SHUT_W",
89 "S_PRE_SHUT_RW",
90 "S_EOF_SHUT_RW",
91 "S_POST_SHUT_RW",
92 "S_PRE_RESET",
93 "S_AT_RESET",
94 "S_POST_RESET",
95 "S_FAILED",
96 "S_POST_FAILED",
98 #endif
100 static const char *callname[C_MAX] = {
101 "C_ACCEPT",
102 "C_BIND",
103 "C_CONNECT",
104 "C_GETPEERNAME",
105 "C_GETSOCKNAME",
106 "C_GETSOCKOPT_ERR",
107 "C_GETSOCKOPT_KA",
108 "C_GETSOCKOPT_RB",
109 "C_IOCTL_NREAD",
110 "C_LISTEN",
111 "C_RECV",
112 "C_RECVFROM",
113 "C_SEND",
114 "C_SENDTO",
115 "C_SELECT_R",
116 "C_SELECT_W",
117 "C_SELECT_X",
118 "C_SETSOCKOPT_BC",
119 "C_SETSOCKOPT_KA",
120 "C_SETSOCKOPT_L",
121 "C_SETSOCKOPT_RA",
122 "C_SHUTDOWN_R",
123 "C_SHUTDOWN_RW",
124 "C_SHUTDOWN_W",
126 #endif
128 static int socklib_sigpipe;
131 * Signal handler for SIGPIPE signals.
133 static void
134 socklib_signal(int sig)
137 if (sig != SIGPIPE) e(0);
139 socklib_sigpipe++;
143 * The given socket file descriptor 'fd' has been set up in the desired state.
144 * Perform the given call 'call' on it, possibly using local socket address
145 * 'local_addr' (for binding) or remote socket address 'remote_addr' (for
146 * connecting or to store resulting addresses), both of size 'addr_len'.
147 * Return the result of the call, using a positive value if the call succeeded,
148 * or a negated errno code if the call failed.
151 socklib_sweep_call(enum call call, int fd, struct sockaddr * local_addr,
152 struct sockaddr * remote_addr, socklen_t addr_len)
154 char data[1];
155 struct linger l;
156 fd_set fd_set;
157 struct timeval tv;
158 socklen_t len;
159 int i, r, fd2;
161 fd2 = -1;
163 switch (call) {
164 case C_ACCEPT:
165 r = accept(fd, remote_addr, &addr_len);
167 if (r >= 0)
168 fd2 = r;
170 break;
172 case C_BIND:
173 r = bind(fd, local_addr, addr_len);
175 break;
177 case C_CONNECT:
178 r = connect(fd, remote_addr, addr_len);
180 break;
182 case C_GETPEERNAME:
183 r = getpeername(fd, remote_addr, &addr_len);
185 break;
187 case C_GETSOCKNAME:
188 r = getsockname(fd, remote_addr, &addr_len);
190 break;
192 case C_GETSOCKOPT_ERR:
193 len = sizeof(i);
195 r = getsockopt(fd, SOL_SOCKET, SO_ERROR, &i, &len);
198 * We assume this call always succeeds, and test against the
199 * pending error.
201 if (r != 0) e(0);
202 if (i != 0) {
203 r = -1;
204 errno = i;
207 break;
209 case C_GETSOCKOPT_KA:
210 len = sizeof(i);
212 r = getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, &len);
214 break;
216 case C_GETSOCKOPT_RB:
217 len = sizeof(i);
219 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &i, &len);
221 break;
223 case C_IOCTL_NREAD:
224 r = ioctl(fd, FIONREAD, &i);
226 /* On success, we test against the returned value here. */
227 if (r == 0)
228 r = i;
230 break;
232 case C_LISTEN:
233 r = listen(fd, 1);
235 break;
237 case C_RECV:
238 r = recv(fd, data, sizeof(data), 0);
240 break;
242 case C_RECVFROM:
243 r = recvfrom(fd, data, sizeof(data), 0, remote_addr,
244 &addr_len);
246 break;
248 case C_SEND:
249 data[0] = 0;
251 r = send(fd, data, sizeof(data), 0);
253 break;
255 case C_SENDTO:
256 data[0] = 0;
258 r = sendto(fd, data, sizeof(data), 0, remote_addr, addr_len);
260 break;
262 case C_SETSOCKOPT_BC:
263 i = 0;
265 r = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i));
267 break;
269 case C_SETSOCKOPT_KA:
270 i = 1;
272 r = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
274 break;
276 case C_SETSOCKOPT_L:
277 l.l_onoff = 1;
278 l.l_linger = 0;
280 r = setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
282 break;
284 case C_SETSOCKOPT_RA:
285 i = 1;
287 r = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
289 break;
291 case C_SELECT_R:
292 case C_SELECT_W:
293 case C_SELECT_X:
294 FD_ZERO(&fd_set);
295 FD_SET(fd, &fd_set);
297 tv.tv_sec = 0;
298 tv.tv_usec = 0;
300 r = select(fd + 1, (call == C_SELECT_R) ? &fd_set : NULL,
301 (call == C_SELECT_W) ? &fd_set : NULL,
302 (call == C_SELECT_X) ? &fd_set : NULL, &tv);
304 break;
306 case C_SHUTDOWN_R:
307 r = shutdown(fd, SHUT_RD);
309 break;
311 case C_SHUTDOWN_W:
312 r = shutdown(fd, SHUT_WR);
314 break;
316 case C_SHUTDOWN_RW:
317 r = shutdown(fd, SHUT_RDWR);
319 break;
321 default:
322 r = -1;
323 errno = EINVAL;
324 e(0);
327 if (r < -1) e(0);
329 if (r == -1)
330 r = -errno;
332 if (fd2 >= 0 && close(fd2) != 0) e(0);
334 return r;
338 * Perform a sweep of socket calls vs socket states, testing the outcomes
339 * against provided tables or (if SOCKLIB_SWEEP_GENERATE is set) reporting on
340 * the outcomes instead. The caller must provide the following:
342 * - the socket domain, type, and protocol to test; these are simply forwarded
343 * to the callback function (see below);
344 * - the set of S_ states to test, as array 'states' with 'nstates' elements;
345 * - unless generating output, a matrix of expected results as 'results', which
346 * is actually a two-dimensional array with dimensions [C_MAX][nstates], with
347 * either positive call output or a negated call errno code in each cell;
348 * - a callback function 'proc' that must set up a socket in the given state
349 * and pass it to socklib_sweep_call().
351 * The 'states' array allows each socket sweep test to support a different set
352 * of states, because not every type of socket can be put in every possible
353 * state. All calls are always tried in each state, though.
355 * The sweep also tests for SIGPIPE generation, which assumes that all calls on
356 * SOCK_STREAM sockets that return EPIPE, also raise a SIGPIPE signal, and that
357 * no other SIGPIPE signal is ever raised otherwise.
359 * Standard e() error throwing is used for set-up and result mismatches.
361 void
362 socklib_sweep(int domain, int type, int protocol, const enum state * states,
363 unsigned int nstates, const int * results, int (* proc)(int domain,
364 int type, int protocol, enum state, enum call))
366 struct sigaction act, oact;
367 enum state state;
368 enum call call;
369 #if SOCKLIB_SWEEP_GENERATE
370 const char *name;
371 int res, *nresults;
372 #else
373 int res, exp;
374 #endif
376 memset(&act, 0, sizeof(act));
377 act.sa_handler = socklib_signal;
378 if (sigaction(SIGPIPE, &act, &oact) != 0) e(0);
380 #if SOCKLIB_SWEEP_GENERATE
381 if ((nresults = malloc(nstates * C_MAX)) == NULL) e(0);
382 #endif
384 for (state = 0; state < nstates; state++) {
385 for (call = 0; call < C_MAX; call++) {
386 socklib_sigpipe = 0;
388 res = proc(domain, type, protocol, states[state],
389 call);
392 * If the result was EPIPE and this is a stream-type
393 * socket, we must have received exactly one SIGPIPE
394 * signal. Otherwise, we must not have received one.
395 * Note that technically, the SIGPIPE could arrive
396 * sometime after this check, but with regular system
397 * service scheduling that will never happen.
399 if (socklib_sigpipe !=
400 (res == -EPIPE && type == SOCK_STREAM)) e(0);
402 #if SOCKLIB_SWEEP_GENERATE
403 nresults[call * nstates + state] = res;
404 #else
405 exp = results[call * nstates + state];
407 if (res != exp) {
408 printf("FAIL state %d call %d res %d exp %d\n",
409 state, call, res, exp);
410 e(0);
412 #endif
416 if (sigaction(SIGPIPE, &oact, NULL) != 0) e(0);
418 #if SOCKLIB_SWEEP_GENERATE
419 #if SOCKLIB_SWEEP_GENERATE == 1
421 * Generate a table in C form, ready to be pasted into test source.
422 * Obviously, generated results should be hand-checked carefully before
423 * being pasted into a test. Arguably these tables should be hand-made
424 * for maximum scrutiny, but I already checked the results from the
425 * CSV form (#define SOCKLIB_SWEEP_GENERATE 2) and have no desire for
426 * RSI -dcvmoole
428 printf("\nstatic const int X_results[][__arraycount(X_states)] = {\n");
429 for (call = 0; call < C_MAX; call++) {
430 if ((name = callname[call]) == NULL) e(0);
431 printf("\t[%s]%s%s%s= {", name,
432 (strlen(name) <= 21) ? "\t" : "",
433 (strlen(name) <= 13) ? "\t" : "",
434 (strlen(name) <= 5) ? "\t" : "");
435 for (state = 0; state < nstates; state++) {
436 if (state % 4 == 0)
437 printf("\n\t\t");
438 res = nresults[call * nstates + state];
439 name = (res < 0) ? get_error_name(-res) : NULL;
440 if (name != NULL) {
441 printf("-%s,", name);
442 if ((state + 1) % 4 != 0 &&
443 state < nstates - 1)
444 printf("%s%s",
445 (strlen(name) <= 13) ? "\t" : "",
446 (strlen(name) <= 5) ? "\t" : "");
447 } else {
448 printf("%d,", res);
449 if ((state + 1) % 4 != 0 &&
450 state < nstates - 1)
451 printf("\t\t");
454 printf("\n\t},\n");
456 printf("};\n");
457 #elif SOCKLIB_SWEEP_GENERATE == 2
458 /* Generate table in CSV form. */
459 printf("\n");
460 for (state = 0; state < nstates; state++)
461 printf(",%s", statename[states[state]] + 2);
462 for (call = 0; call < C_MAX; call++) {
463 printf("\n%s", callname[call] + 2);
464 for (state = 0; state < nstates; state++) {
465 res = nresults[call * nstates + state];
466 name = (res < 0) ? get_error_name(-res) : NULL;
467 if (name != NULL)
468 printf(",%s", name);
469 else
470 printf(",%d", res);
473 printf("\n");
474 #endif
476 free(nresults);
477 #endif
481 * Test for setting and retrieving UDP/RAW multicast transmission options.
482 * This is an interface-level test only: we do not (yet) test whether the
483 * options have any effect. The given 'type' must be SOCK_DGRAM or SOCK_RAW.
485 void
486 socklib_multicast_tx_options(int type)
488 struct in_addr in_addr;
489 socklen_t len;
490 unsigned int ifindex;
491 uint8_t byte;
492 int fd, val;
494 subtest = 10;
496 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
499 * Initially, the multicast TTL is expected be 1, looping should be
500 * enabled, and the multicast source address should be <any>.
502 byte = 0;
503 len = sizeof(byte);
504 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte, &len) != 0)
505 e(0);
506 if (len != sizeof(byte)) e(0);
507 if (type != SOCK_STREAM && byte != 1) e(0);
509 byte = 0;
510 len = sizeof(byte);
511 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte, &len) != 0)
512 e(0);
513 if (len != sizeof(byte)) e(0);
514 if (byte != 1) e(0);
516 len = sizeof(in_addr);
517 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &in_addr, &len) != 0)
518 e(0);
519 if (len != sizeof(in_addr)) e(0);
520 if (in_addr.s_addr != htonl(INADDR_ANY)) e(0);
522 /* It must not be possible to get/set IPv6 options on IPv4 sockets. */
523 val = 0;
524 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
525 sizeof(val)) != -1) e(0);
526 if (errno != ENOPROTOOPT) e(0);
527 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
528 sizeof(val)) != -1) e(0);
529 if (errno != ENOPROTOOPT) e(0);
530 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
531 sizeof(val) /*wrong but it doesn't matter*/) != -1) e(0);
532 if (errno != ENOPROTOOPT) e(0);
534 len = sizeof(val);
535 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
536 &len) != -1) e(0);
537 if (errno != ENOPROTOOPT) e(0);
538 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
539 &len) != -1) e(0);
540 if (errno != ENOPROTOOPT) e(0);
541 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != -1)
542 e(0);
543 if (errno != ENOPROTOOPT) e(0);
545 if (close(fd) != 0) e(0);
547 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
550 * Expect the same defaults as for IPv4. IPV6_MULTICAST_IF uses an
551 * interface index rather than an IP address, though.
553 val = 0;
554 len = sizeof(val);
555 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
556 e(0);
557 if (len != sizeof(val)) e(0);
558 if (type != SOCK_STREAM && val != 1) e(0);
560 val = 0;
561 len = sizeof(val);
562 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, &len) != 0)
563 e(0);
564 if (len != sizeof(val)) e(0);
565 if (val != 1) e(0);
567 len = sizeof(val);
568 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
569 e(0);
570 if (len != sizeof(val)) e(0);
571 if (val != 0) e(0);
573 /* It must not be possible to get/set IPv4 options on IPv6 sockets. */
574 byte = 0;
575 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte,
576 sizeof(byte)) != -1) e(0);
577 if (errno != ENOPROTOOPT) e(0);
578 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte,
579 sizeof(byte)) != -1) e(0);
580 if (errno != ENOPROTOOPT) e(0);
581 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &byte,
582 sizeof(byte) /* wrong but it doesn't matter */) != -1) e(0);
583 if (errno != ENOPROTOOPT) e(0);
585 len = sizeof(byte);
586 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, &len) != -1)
587 e(0);
588 if (errno != ENOPROTOOPT) e(0);
589 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &val, &len) != -1)
590 e(0);
591 if (errno != ENOPROTOOPT) e(0);
592 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &val, &len) != -1)
593 e(0);
594 if (errno != ENOPROTOOPT) e(0);
596 if (close(fd) != 0) e(0);
598 /* Test changing options. */
599 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
601 byte = 129;
602 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte,
603 sizeof(byte)) != 0) e(0);
605 byte = 0;
606 len = sizeof(byte);
607 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte, &len) != 0)
608 e(0);
609 if (len != sizeof(byte)) e(0);
610 if (byte != 129) e(0);
612 byte = 0;
613 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte,
614 sizeof(byte)) != 0)
615 e(0);
617 byte = 1;
618 len = sizeof(byte);
619 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte, &len) != 0)
620 e(0);
621 if (len != sizeof(byte)) e(0);
622 if (byte != 0) e(0);
624 in_addr.s_addr = htonl(INADDR_LOOPBACK);
625 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &in_addr,
626 sizeof(in_addr)) != 0)
627 e(0);
629 in_addr.s_addr = htonl(INADDR_ANY);
630 len = sizeof(in_addr);
631 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &in_addr, &len) != 0)
632 e(0);
633 if (len != sizeof(in_addr)) e(0);
634 if (in_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
636 if (close(fd) != 0) e(0);
638 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
640 val = 137;
641 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
642 sizeof(val)) != 0) e(0);
644 val = 0;
645 len = sizeof(val);
646 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
647 e(0);
648 if (len != sizeof(val)) e(0);
649 if (val != 137) e(0);
651 val = -2;
652 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
653 sizeof(val)) != -1) e(0);
654 if (errno != EINVAL) e(0);
656 val = 256;
657 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
658 sizeof(val)) != -1) e(0);
659 if (errno != EINVAL) e(0);
661 val = 0;
662 len = sizeof(val);
663 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
664 e(0);
665 if (len != sizeof(val)) e(0);
666 if (val != 137) e(0);
668 val = -1; /* use default */
669 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
670 sizeof(val)) != 0) e(0);
672 val = 0;
673 len = sizeof(val);
674 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
675 e(0);
676 if (len != sizeof(val)) e(0);
677 if (val != 1) e(0);
679 val = 0;
680 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
681 sizeof(val)) != 0) e(0);
683 val = 1;
684 len = sizeof(val);
685 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, &len) != 0)
686 e(0);
687 if (len != sizeof(val)) e(0);
688 if (val != 0) e(0);
690 val = 1;
691 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
692 sizeof(val)) != 0) e(0);
694 val = -1;
695 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
696 sizeof(val)) != -1) e(0);
697 if (errno != EINVAL) e(0);
699 val = 2;
700 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
701 sizeof(val)) != -1) e(0);
702 if (errno != EINVAL) e(0);
704 val = 0;
705 len = sizeof(val);
706 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, &len) != 0)
707 e(0);
708 if (len != sizeof(val)) e(0);
709 if (val != 1) e(0);
711 val = -1;
712 ifindex = if_nametoindex(LOOPBACK_IFNAME);
714 val = ifindex;
715 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
716 sizeof(val)) != 0) e(0);
718 val = 0;
719 len = sizeof(val);
720 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
721 e(0);
722 if (len != sizeof(val)) e(0);
723 if (val != ifindex) e(0);
725 val = BAD_IFINDEX;
726 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
727 sizeof(val)) != -1) e(0);
729 val = -1;
730 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
731 sizeof(val)) != -1) e(0);
733 val = 0;
734 len = sizeof(val);
735 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
736 e(0);
737 if (len != sizeof(val)) e(0);
738 if (val != ifindex) e(0);
740 val = 0;
741 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
742 sizeof(val)) != 0) e(0);
744 val = ifindex;
745 len = sizeof(val);
746 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
747 e(0);
748 if (len != sizeof(val)) e(0);
749 if (val != 0) e(0);
751 if (close(fd) != 0) e(0);
755 * Test for large sends and receives on stream sockets with MSG_WAITALL.
757 void
758 socklib_large_transfers(int fd[2])
760 char *buf;
761 pid_t pid;
762 int i, status;
764 #define LARGE_BUF (4096*1024)
766 if ((buf = malloc(LARGE_BUF)) == NULL) e(0);
767 memset(buf, 0, LARGE_BUF);
769 pid = fork();
770 switch (pid) {
771 case 0:
772 errct = 0;
774 if (close(fd[0]) != 0) e(0);
776 /* Part 1. */
777 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF)
778 e(0);
780 for (i = 0; i < LARGE_BUF; i++)
781 if (buf[i] != (char)(i + (i >> 16))) e(0);
783 if (recv(fd[1], buf, LARGE_BUF,
784 MSG_DONTWAIT | MSG_WAITALL) != -1) e(0);
785 if (errno != EWOULDBLOCK) e(0);
787 /* Part 2. */
788 if (send(fd[1], buf, LARGE_BUF / 2, 0) != LARGE_BUF / 2) e(0);
790 if (shutdown(fd[1], SHUT_WR) != 0) e(0);
792 /* Part 3. */
793 memset(buf, 'y', LARGE_BUF);
795 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF - 1)
796 e(0);
798 for (i = 0; i < LARGE_BUF - 1; i++)
799 if (buf[i] != (char)(i + (i >> 16))) e(0);
800 if (buf[LARGE_BUF - 1] != 'y') e(0);
802 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != 0) e(0);
804 exit(errct);
805 case -1:
806 e(0);
809 if (close(fd[1]) != 0) e(0);
811 /* Part 1: check that a large send fully arrives. */
812 for (i = 0; i < LARGE_BUF; i++)
813 buf[i] = (char)(i + (i >> 16));
815 if (send(fd[0], buf, LARGE_BUF, 0) != LARGE_BUF) e(0);
817 /* Part 2: check that remote shutdown terminates a partial receive. */
818 memset(buf, 'x', LARGE_BUF);
820 if (recv(fd[0], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF / 2) e(0);
822 for (i = 0; i < LARGE_BUF / 2; i++)
823 if (buf[i] != (char)(i + (i >> 16))) e(0);
824 for (; i < LARGE_BUF; i++)
825 if (buf[i] != 'x') e(0);
827 if (recv(fd[0], buf, LARGE_BUF, MSG_WAITALL) != 0) e(0);
829 /* Part 3: check that remote close terminates a partial receive. */
830 for (i = 0; i < LARGE_BUF; i++)
831 buf[i] = (char)(i + (i >> 16));
833 if (send(fd[0], buf, LARGE_BUF - 1, 0) != LARGE_BUF - 1) e(0);
835 if (close(fd[0]) != 0) e(0);
837 if (waitpid(pid, &status, 0) != pid) e(0);
838 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
840 free(buf);
843 #define PRINT_STATS 0
846 * A randomized producer-consumer test for stream sockets. As part of this,
847 * we also perform very basic bulk functionality tests of FIONREAD, MSG_PEEK,
848 * MSG_DONTWAIT, and MSG_WAITALL.
850 void
851 socklib_producer_consumer(int fd[2])
853 char *buf;
854 time_t t;
855 socklen_t len, size, off;
856 ssize_t r;
857 pid_t pid;
858 int i, rcvlen, status, exp, flags, num, stat[3] = { 0, 0, 0 };
860 len = sizeof(rcvlen);
861 if (getsockopt(fd[0], SOL_SOCKET, SO_RCVBUF, &rcvlen, &len) != 0) e(0);
862 if (len != sizeof(rcvlen)) e(0);
864 size = rcvlen * 3;
866 if ((buf = malloc(size)) == NULL) e(0);
868 t = time(NULL);
871 * We vary small versus large (random) send and receive sizes,
872 * splitting the entire transfer in four phases along those lines.
874 * In theory, the use of an extra system call, the use of MSG_PEEK, and
875 * the fact that without MSG_WAITALL a receive call may return any
876 * partial result, all contribute to the expectation that the consumer
877 * side will fall behind the producer. In order to test both filling
878 * and draining the receive queue, we use a somewhat larger small
879 * receive size for the consumer size (up to 256 bytes rather than 64)
880 * during each half of the four phases. The effectiveness of these
881 * numbers can be verified with statistics (disabled by default).
883 #define TRANSFER_SIZE (16 * 1024 * 1024)
885 pid = fork();
886 switch (pid) {
887 case 0:
888 errct = 0;
890 if (close(fd[0]) != 0) e(0);
892 srand48(t + 1);
894 for (off = 0; off < TRANSFER_SIZE; ) {
895 if (off < TRANSFER_SIZE / 2)
896 len = lrand48() %
897 ((off / (TRANSFER_SIZE / 8) % 2) ? 64 :
898 256);
899 else
900 len = lrand48() % size;
902 num = lrand48() % 16;
903 flags = 0;
904 if (num & 1) flags |= MSG_PEEK;
905 if (num & 2) flags |= MSG_WAITALL;
906 if (num & 4) flags |= MSG_DONTWAIT;
907 if (num & 8) {
909 * Obviously there are race conditions here but
910 * the returned number should be a lower bound.
912 if (ioctl(fd[1], FIONREAD, &exp) != 0) e(0);
913 if (exp < 0 || exp > rcvlen) e(0);
914 } else
915 exp = -1;
917 stat[0]++;
919 if ((r = recv(fd[1], buf, len, flags)) == -1) {
920 if (errno != EWOULDBLOCK) e(0);
921 if (exp > 0) e(0);
923 stat[2]++;
924 continue;
927 if (r < len) {
928 stat[1]++;
930 if (exp > r) e(0);
933 for (i = 0; i < r; i++)
934 if (buf[i] != (char)((off + i) +
935 ((off + i) >> 16))) e(0);
937 if (!(flags & MSG_PEEK)) {
938 off += r;
940 if ((flags & (MSG_DONTWAIT | MSG_WAITALL)) ==
941 MSG_WAITALL && r != len &&
942 off < TRANSFER_SIZE) e(0);
946 #if PRINT_STATS
948 * The second and third numbers should ideally be a large but
949 * non-dominating fraction of the first one.
951 printf("RECV: total %d short %d again %d\n",
952 stat[0], stat[1], stat[2]);
953 #endif
955 if (close(fd[1]) != 0) e(0);
956 exit(errct);
957 case -1:
958 e(0);
961 if (close(fd[1]) != 0) e(0);
963 srand48(t);
965 for (off = 0; off < TRANSFER_SIZE; ) {
966 if (off < TRANSFER_SIZE / 4 ||
967 (off >= TRANSFER_SIZE / 2 && off < TRANSFER_SIZE * 3 / 4))
968 len = lrand48() % 64;
969 else
970 len = lrand48() % size;
972 if (len > TRANSFER_SIZE - off)
973 len = TRANSFER_SIZE - off;
975 for (i = 0; i < len; i++)
976 buf[i] = (off + i) + ((off + i) >> 16);
978 flags = (lrand48() % 2) ? MSG_DONTWAIT : 0;
980 stat[0]++;
982 r = send(fd[0], buf, len, flags);
984 if (r != len) {
985 if (r > (ssize_t)len) e(0);
986 if (!(flags & MSG_DONTWAIT)) e(0);
987 if (r == -1) {
988 if (errno != EWOULDBLOCK) e(0);
989 r = 0;
991 stat[2]++;
992 } else
993 stat[1]++;
996 if (off / (TRANSFER_SIZE / 4) !=
997 (off + r) / (TRANSFER_SIZE / 4))
998 sleep(1);
1000 off += r;
1003 #if PRINT_STATS
1005 * The second and third numbers should ideally be a large but non-
1006 * dominating fraction of the first one.
1008 printf("SEND: total %d short %d again %d\n",
1009 stat[0], stat[1], stat[2]);
1010 #endif
1012 free(buf);
1014 if (close(fd[0]) != 0) e(0);
1016 if (waitpid(pid, &status, 0) != pid) e(0);
1017 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1021 * Signal handler which just needs to exist, so that invoking it will interrupt
1022 * an ongoing system call.
1024 static void
1025 socklib_got_signal(int sig __unused)
1028 /* Nothing. */
1032 * Test for receiving on stream sockets. The quick summary here is that
1033 * recv(MSG_WAITALL) should keep suspending until as many bytes as requested
1034 * are also received (or the call is interrupted, or no more can possibly be
1035 * received - the meaning of the latter depends on the domain), and,
1036 * SO_RCVLOWAT acts as an admission test for the receive: nothing is received
1037 * until there are at least as many bytes are available in the receive buffer
1038 * as the low receive watermark, or the whole receive request length, whichever
1039 * is smaller. In addition, select(2) should use the same threshold.
1041 #define MAX_BYTES 2 /* set to 3 for slightly better(?) testing */
1042 #define USLEEP_TIME 250000 /* increase on wimpy platforms if needed */
1044 static void
1045 socklib_stream_recv_sub(int (* socket_pair)(int, int, int, int *), int domain,
1046 int type, int idata, int istate, int rlowat, int len, int bits,
1047 int act, int (* break_recv)(int, const char *, size_t))
1049 const char *data = "ABCDE"; /* this limits MAX_BYTES to 3 */
1050 struct sigaction sa;
1051 struct timeval tv;
1052 fd_set fds;
1053 char buf[3];
1054 pid_t pid;
1055 int fd[2], val, flags, min, res, err;
1056 int pfd[2], edata, tstate, fl, status;
1058 if (socket_pair(domain, type, 0, fd) != 0) e(0);
1061 * Set up the initial condition on the sockets.
1063 if (idata > 0)
1064 if (send(fd[1], data, idata, 0) != idata) e(0);
1066 switch (istate) {
1067 case 0: break;
1068 case 1: if (shutdown(fd[0], SHUT_RD) != 0) e(0); break;
1069 case 2: if (shutdown(fd[1], SHUT_WR) != 0) e(0); break;
1070 case 3: if (close(fd[1]) != 0) e(0); break;
1073 /* Set the low receive water mark. */
1074 if (setsockopt(fd[0], SOL_SOCKET, SO_RCVLOWAT, &rlowat,
1075 sizeof(rlowat)) != 0) e(0);
1077 /* SO_RCVLOWAT is always bounded by the actual receive length. */
1078 min = MIN(len, rlowat);
1081 * Do a quick select test to see if its result indeed matches whether
1082 * the available data in the receive buffer meets the threshold.
1084 FD_ZERO(&fds);
1085 FD_SET(fd[0], &fds);
1086 tv.tv_sec = 0;
1087 tv.tv_usec = 0;
1088 res = select(fd[0] + 1, &fds, NULL, NULL, &tv);
1089 if (res < 0 || res > 1) e(0);
1090 if (res != (idata >= rlowat || istate > 0)) e(0);
1091 if (res == 1 && !FD_ISSET(fd[0], &fds)) e(0);
1093 /* Also do a quick test for ioctl(FIONREAD). */
1094 if (ioctl(fd[0], FIONREAD, &val) != 0) e(0);
1095 if (val != ((istate != 1) ? idata : 0)) e(0);
1097 /* Translate the given bits to receive call flags. */
1098 flags = 0;
1099 if (bits & 1) flags |= MSG_PEEK;
1100 if (bits & 2) flags |= MSG_DONTWAIT;
1101 if (bits & 4) flags |= MSG_WAITALL;
1104 * Cut short a whole lot of cases, to avoid the overhead of forking,
1105 * namely when we know the call should return immediately. This is
1106 * the case when MSG_DONTWAIT is set, or if a termination condition has
1107 * been raised, or if enough initial data are available to meet the
1108 * conditions for the receive call.
1110 if ((flags & MSG_DONTWAIT) || istate > 0 || (idata >= min &&
1111 ((flags & (MSG_PEEK | MSG_WAITALL)) != MSG_WAITALL ||
1112 idata >= len))) {
1113 res = recv(fd[0], buf, len, flags);
1115 if (res == -1 && errno != EWOULDBLOCK) e(0);
1118 * If the socket has been shutdown locally, we will never get
1119 * anything but zero. Otherwise, if we meet the SO_RCVLOWAT
1120 * test, we should have received as much as was available and
1121 * requested. Otherwise, if the remote end has been shut down
1122 * or closed, we expected to get any available data or
1123 * otherwise EOF (implied with idata==0). If none of these
1124 * cases apply, we should have gotten EWOULDBLOCK.
1126 if (istate == 1) {
1127 if (res != 0) e(0);
1128 } else if (idata >= min) {
1129 if (res != MIN(len, idata)) e(0);
1130 if (strncmp(buf, data, res)) e(0);
1131 } else if (istate > 0) {
1132 if (res != idata) e(0);
1133 if (strncmp(buf, data, res)) e(0);
1134 } else
1135 if (res != -1) e(0);
1137 /* Early cleanup and return to avoid even more code clutter. */
1138 if (istate != 3 && close(fd[1]) != 0) e(0);
1139 if (close(fd[0]) != 0) e(0);
1141 return;
1145 * Now starts the interesting stuff: the receive call should now block,
1146 * even though if we add MSG_DONTWAIT it may not return EWOULDBLOCK,
1147 * because MSG_DONTWAIT overrides MSG_WAITALL. As such, we can only
1148 * test our expectations by actually letting the call block, in a child
1149 * process, and waiting. We do test as much of the above assumption as
1150 * we can just for safety right here, but this is not a substitute for
1151 * actually blocking even in these cases!
1153 if (!(flags & MSG_WAITALL)) {
1154 if (recv(fd[0], buf, len, flags | MSG_DONTWAIT) != -1) e(0);
1155 if (errno != EWOULDBLOCK) e(0);
1159 * If (act < 12), we send 0, 1, or 2 extra data bytes before forcing
1160 * the receive call to terminate in one of four ways.
1162 * If (act == 12), we use a signal to interrupt the receive call.
1164 if (act < 12) {
1165 edata = act % 3;
1166 tstate = act / 3;
1167 } else
1168 edata = tstate = 0;
1170 if (pipe2(pfd, O_NONBLOCK) != 0) e(0);
1172 pid = fork();
1173 switch (pid) {
1174 case 0:
1175 errct = 0;
1177 if (close(fd[1]) != 0) e(0);
1178 if (close(pfd[0]) != 0) e(0);
1180 if (act == 12) {
1181 memset(&sa, 0, sizeof(sa));
1182 sa.sa_handler = socklib_got_signal;
1183 if (sigaction(SIGUSR1, &sa, NULL) != 0) e(0);
1186 res = recv(fd[0], buf, len, flags);
1187 err = errno;
1189 if (write(pfd[1], &res, sizeof(res)) != sizeof(res)) e(0);
1190 if (write(pfd[1], &err, sizeof(err)) != sizeof(err)) e(0);
1192 if (res > 0 && strncmp(buf, data, res)) e(0);
1194 exit(errct);
1195 case -1:
1196 e(0);
1199 if (close(pfd[1]) != 0) e(0);
1202 * Allow the child to enter the blocking recv(2), and check the pipe
1203 * to see if it is really blocked.
1205 if (usleep(USLEEP_TIME) != 0) e(0);
1207 if (read(pfd[0], buf, 1) != -1) e(0);
1208 if (errno != EAGAIN) e(0);
1210 if (edata > 0) {
1211 if (send(fd[1], &data[idata], edata, 0) != edata) e(0);
1214 * The threshold for the receive is now met if both the minimum
1215 * is met and MSG_WAITALL was not set (or overridden by
1216 * MSG_PEEK) or the entire request has been satisfied.
1218 if (idata + edata >= min &&
1219 ((flags & (MSG_PEEK | MSG_WAITALL)) != MSG_WAITALL ||
1220 idata + edata >= len)) {
1221 if ((fl = fcntl(pfd[0], F_GETFL, 0)) == -1) e(0);
1222 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0)
1223 e(0);
1225 if (read(pfd[0], &res, sizeof(res)) != sizeof(res))
1226 e(0);
1227 if (read(pfd[0], &err, sizeof(err)) != sizeof(err))
1228 e(0);
1230 if (res != MIN(idata + edata, len)) e(0);
1232 /* Bail out. */
1233 goto cleanup;
1236 /* Sleep and test once more. */
1237 if (usleep(USLEEP_TIME) != 0) e(0);
1239 if (read(pfd[0], buf, 1) != -1) e(0);
1240 if (errno != EAGAIN) e(0);
1243 if (act < 12) {
1245 * Now test various ways to terminate the receive call.
1247 switch (tstate) {
1248 case 0: if (shutdown(fd[0], SHUT_RD) != 0) e(0); break;
1249 case 1: if (shutdown(fd[1], SHUT_WR) != 0) e(0); break;
1250 case 2: if (close(fd[1]) != 0) e(0); fd[1] = -1; break;
1251 case 3: fd[1] = break_recv(fd[1], data, strlen(data)); break;
1253 } else
1254 if (kill(pid, SIGUSR1) != 0) e(0);
1256 if ((fl = fcntl(pfd[0], F_GETFL, 0)) == -1) e(0);
1257 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0) e(0);
1259 if (read(pfd[0], &res, sizeof(res)) != sizeof(res)) e(0);
1260 if (read(pfd[0], &err, sizeof(err)) != sizeof(err)) e(0);
1262 if (act < 12) {
1264 * If there were any data we should have received them now;
1265 * after all the receive minimum stops being relevant when
1266 * another condition has been raised. There is one exception:
1267 * if the receive threshold was never met and we now shut down
1268 * the socket for reading, EOF is acceptable as return value.
1270 if (tstate == 0 && idata + edata < min) {
1271 if (res != 0) e(0);
1272 } else if (idata + edata > 0) {
1273 if (res != MIN(idata + edata, len)) e(0);
1274 } else if (tstate == 3) {
1275 if (fd[1] == -1) {
1276 if (res != -1) e(0);
1277 if (err != ECONNRESET) e(0);
1278 } else
1279 if (res != len) e(0);
1280 } else
1281 if (res != 0) e(0);
1282 } else {
1284 * If the receive met the threshold before being interrupted,
1285 * we should have received at least something. Otherwise, the
1286 * receive was never admitted and should just return EINTR.
1288 if (idata >= min) {
1289 if (res != MIN(idata, len)) e(0);
1290 } else {
1291 if (res != -1) e(0);
1292 if (err != EINTR) e(0);
1296 cleanup:
1297 if (close(pfd[0]) != 0) e(0);
1299 if (wait(&status) != pid) e(0);
1300 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1302 if (fd[1] != -1 && close(fd[1]) != 0) e(0);
1303 if (close(fd[0]) != 0) e(0);
1307 * Test for receiving on stream sockets. In particular, test SO_RCVLOWAT,
1308 * MSG_PEEK, MSG_DONTWAIT, and MSG_WAITALL.
1310 void
1311 socklib_stream_recv(int (* socket_pair)(int, int, int, int *), int domain,
1312 int type, int (* break_recv)(int, const char *, size_t))
1314 int idata, istate, rlowat, len, bits, act;
1316 /* Insanity. */
1317 for (idata = 0; idata <= MAX_BYTES; idata++)
1318 for (istate = 0; istate <= 3; istate++)
1319 for (rlowat = 1; rlowat <= MAX_BYTES; rlowat++)
1320 for (len = 1; len <= MAX_BYTES; len++)
1321 for (bits = 0; bits < 8; bits++)
1322 for (act = 0; act <= 12; act++)
1323 socklib_stream_recv_sub
1324 (socket_pair,
1325 domain, type,
1326 idata, istate,
1327 rlowat, len, bits,
1328 act, break_recv);
1332 * Obtain information for a matching protocol control block, using sysctl(7).
1333 * The PCB is to be obtained through the given sysctl path string, and must
1334 * match the other given parameters. Return 1 if found with 'ki' filled with
1335 * the PCB information, or 0 if not.
1338 socklib_find_pcb(const char * path, int protocol, uint16_t local_port,
1339 uint16_t remote_port, struct kinfo_pcb * ki)
1341 struct sockaddr_in sin;
1342 struct sockaddr_in6 sin6;
1343 struct kinfo_pcb *array;
1344 size_t i, miblen, oldlen;
1345 uint16_t lport, rport;
1346 int mib[CTL_MAXNAME], found;
1348 miblen = __arraycount(mib);
1349 if (sysctlnametomib(path, mib, &miblen) != 0) e(0);
1350 if (miblen > __arraycount(mib) - 4) e(0);
1351 mib[miblen++] = 0;
1352 mib[miblen++] = 0;
1353 mib[miblen++] = sizeof(*array);
1354 mib[miblen++] = 0;
1356 if (sysctl(mib, miblen, NULL, &oldlen, NULL, 0) != 0) e(0);
1357 if (oldlen == 0)
1358 return 0; /* should not happen due to added slop space */
1359 if (oldlen % sizeof(*array)) e(0);
1361 if ((array = (struct kinfo_pcb *)malloc(oldlen)) == NULL) e(0);
1363 if (sysctl(mib, miblen, array, &oldlen, NULL, 0) != 0) e(0);
1364 if (oldlen % sizeof(*array)) e(0);
1366 found = -1;
1367 for (i = 0; i < oldlen / sizeof(*array); i++) {
1368 /* Perform some basic checks. */
1369 if (array[i].ki_pcbaddr == 0) e(0);
1370 if (array[i].ki_ppcbaddr == 0) e(0);
1371 if (array[i].ki_family != mib[1]) e(0);
1373 if (mib[1] == AF_INET6) {
1374 memcpy(&sin6, &array[i].ki_src, sizeof(sin6));
1375 if (sin6.sin6_family != AF_INET6) e(0);
1376 if (sin6.sin6_len != sizeof(sin6)) e(0);
1377 lport = ntohs(sin6.sin6_port);
1379 memcpy(&sin6, &array[i].ki_dst, sizeof(sin6));
1380 if (sin6.sin6_family != AF_INET6) e(0);
1381 if (sin6.sin6_len != sizeof(sin6)) e(0);
1382 rport = ntohs(sin6.sin6_port);
1383 } else {
1384 memcpy(&sin, &array[i].ki_src, sizeof(sin));
1385 if (sin.sin_family != AF_INET) e(0);
1386 if (sin.sin_len != sizeof(sin)) e(0);
1387 lport = ntohs(sin.sin_port);
1389 memcpy(&sin, &array[i].ki_dst, sizeof(sin));
1390 if (sin.sin_family != AF_UNSPEC) {
1391 if (sin.sin_family != AF_INET) e(0);
1392 if (sin.sin_len != sizeof(sin)) e(0);
1393 rport = ntohs(sin.sin_port);
1394 } else
1395 rport = 0;
1398 /* Try to match every PCB. We must find at most one match. */
1399 if (array[i].ki_protocol == protocol && lport == local_port &&
1400 rport == remote_port) {
1401 if (found != -1) e(0);
1403 found = (int)i;
1407 if (found >= 0)
1408 memcpy(ki, &array[found], sizeof(*ki));
1410 free(array);
1412 return (found != -1);
1415 #ifdef NO_INET6
1416 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
1417 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
1419 void
1420 inet6_getscopeid(struct sockaddr_in6 * sin6 __unused, int flags __unused)
1424 * Nothing. The tests linked to socklib make heavy use of IPv6, and
1425 * are expected to fail if IPv6 support is disabled at compile time.
1426 * Therefore, what this replacement function does is not relevant.
1429 #endif /* NO_INET6 */
1431 #define F_ANY 0x01 /* not bound, or bound to an 'any' address */
1432 #define F_V4 0x02 /* address is IPv4-mapped IPv6 address */
1433 #define F_REM 0x04 /* address is remote (not assigned to an interface) */
1434 #define F_MIX 0x08 /* address has non-loopback scope */
1437 * Test local and remote IPv6 address handling on TCP or UDP sockets.
1439 void
1440 socklib_test_addrs(int type, int protocol)
1442 struct sockaddr_in6 sin6, sin6_any, sin6_any_scope, sin6_lo,
1443 sin6_lo_scope, sin6_ll_all, sin6_ll_lo, sin6_ll_rem, sin6_ll_kame,
1444 sin6_ll_bad, sin6_ll_mix, sin6_rem, sin6_v4_any, sin6_v4_lo,
1445 sin6_v4_rem, rsin6;
1446 const struct sockaddr_in6 *sin6p;
1447 const struct {
1448 const struct sockaddr_in6 *addr;
1449 int res;
1450 int flags;
1451 const struct sockaddr_in6 *name;
1452 } bind_array[] = {
1453 { NULL, 0, F_ANY, &sin6_any },
1454 { &sin6_any, 0, F_ANY, &sin6_any },
1455 { &sin6_any_scope, 0, F_ANY, &sin6_any },
1456 { &sin6_lo, 0, 0, &sin6_lo },
1457 { &sin6_lo_scope, 0, 0, &sin6_lo },
1458 { &sin6_ll_lo, 0, 0, &sin6_ll_lo },
1459 { &sin6_v4_lo, 0, F_V4, &sin6_v4_lo },
1460 { &sin6_rem, EADDRNOTAVAIL },
1461 { &sin6_ll_all, EADDRNOTAVAIL },
1462 { &sin6_ll_rem, EADDRNOTAVAIL },
1463 { &sin6_ll_kame, EINVAL },
1464 { &sin6_ll_bad, ENXIO },
1465 { &sin6_v4_any, EADDRNOTAVAIL },
1466 { &sin6_v4_rem, EADDRNOTAVAIL },
1467 /* The following entry MUST be last. */
1468 { &sin6_ll_mix, EADDRNOTAVAIL },
1469 }, *bp;
1470 const struct {
1471 const struct sockaddr_in6 *addr;
1472 int res;
1473 int flags;
1474 const struct sockaddr_in6 *name;
1475 } conn_array[] = {
1476 { &sin6_any, EHOSTUNREACH, 0 },
1477 { &sin6_any_scope, EHOSTUNREACH, 0 },
1478 { &sin6_ll_kame, EINVAL, 0 },
1479 { &sin6_ll_bad, ENXIO, 0 },
1480 { &sin6_v4_any, EHOSTUNREACH, F_V4 },
1481 { &sin6_lo, 0, 0, &sin6_lo },
1482 { &sin6_lo_scope, 0, 0, &sin6_lo },
1483 { &sin6_ll_all, 0, 0, &sin6_ll_lo },
1484 { &sin6_ll_lo, 0, 0, &sin6_ll_lo },
1485 { &sin6_v4_lo, 0, F_V4, &sin6_v4_lo },
1486 { &sin6_rem, 0, F_REM, &sin6_rem },
1487 { &sin6_ll_rem, 0, F_REM, &sin6_ll_rem },
1488 { &sin6_v4_rem, 0, F_V4|F_REM, &sin6_v4_rem },
1489 /* The following entry MUST be last. */
1490 { &sin6_ll_mix, 0, F_REM|F_MIX, &sin6_ll_mix },
1491 }, *cp;
1492 struct ifaddrs *ifa, *ifp, *ifp2;
1493 struct in6_ifreq ifr;
1494 char name[IF_NAMESIZE], buf[1];
1495 socklen_t len;
1496 uint32_t port;
1497 unsigned int i, j, ifindex, ifindex2, have_mix, found;
1498 int r, fd, fd2, fd3, val, sfl, exp, link_state;
1500 ifindex = if_nametoindex(LOOPBACK_IFNAME);
1501 if (ifindex == 0) e(0);
1503 /* An IPv6 'any' address - ::0. */
1504 memset(&sin6_any, 0, sizeof(sin6_any));
1505 sin6_any.sin6_len = sizeof(sin6_any);
1506 sin6_any.sin6_family = AF_INET6;
1507 memcpy(&sin6_any.sin6_addr, &in6addr_any, sizeof(sin6_any.sin6_addr));
1509 /* An IPv6 'any' address, but with a bad scope ID set. */
1510 memcpy(&sin6_any_scope, &sin6_any, sizeof(sin6_any_scope));
1511 sin6_any_scope.sin6_scope_id = BAD_IFINDEX;
1513 /* An IPv6 loopback address - ::1. */
1514 memcpy(&sin6_lo, &sin6_any, sizeof(sin6_lo));
1515 memcpy(&sin6_lo.sin6_addr, &in6addr_loopback,
1516 sizeof(sin6_lo.sin6_addr));
1518 /* An IPv6 loopback address, but with a bad scope ID set. */
1519 memcpy(&sin6_lo_scope, &sin6_lo, sizeof(sin6_lo_scope));
1520 sin6_lo_scope.sin6_scope_id = BAD_IFINDEX;
1522 /* An IPv6 link-local address without scope - fe80::1. */
1523 memcpy(&sin6_ll_all, &sin6_any, sizeof(sin6_ll_all));
1524 if (inet_pton(AF_INET6, LOOPBACK_IPV6_LL, &sin6_ll_all.sin6_addr) != 1)
1525 e(0);
1527 /* An IPv6 link-local address with the loopback scope - fe80::1%lo0. */
1528 memcpy(&sin6_ll_lo, &sin6_ll_all, sizeof(sin6_ll_lo));
1529 sin6_ll_lo.sin6_scope_id = ifindex;
1531 /* An unassigned IPv6 link-local address - fe80::ffff%lo0. */
1532 memcpy(&sin6_ll_rem, &sin6_ll_lo, sizeof(sin6_ll_rem));
1533 if (inet_pton(AF_INET6, TEST_BLACKHOLE_IPV6_LL,
1534 &sin6_ll_rem.sin6_addr) != 1) e(0);
1536 /* A KAME-style IPv6 link-local loopback address - fe80:ifindex::1. */
1537 memcpy(&sin6_ll_kame, &sin6_ll_all, sizeof(sin6_ll_kame));
1538 sin6_ll_kame.sin6_addr.s6_addr[2] = ifindex >> 8;
1539 sin6_ll_kame.sin6_addr.s6_addr[3] = ifindex % 0xff;
1541 /* An IPv6 link-local address with a bad scope - fe80::1%<bad>. */
1542 memcpy(&sin6_ll_bad, &sin6_ll_all, sizeof(sin6_ll_bad));
1543 sin6_ll_bad.sin6_scope_id = BAD_IFINDEX;
1545 /* A global IPv6 address not assigned to any interface - ::2. */
1546 memcpy(&sin6_rem, &sin6_any, sizeof(sin6_rem));
1547 if (inet_pton(AF_INET6, TEST_BLACKHOLE_IPV6,
1548 &sin6_rem.sin6_addr) != 1) e(0);
1550 /* An IPv4-mapped IPv6 address for 'any' - ::ffff:0.0.0.0. */
1551 memcpy(&sin6_v4_any, &sin6_any, sizeof(sin6_v4_any));
1552 if (inet_pton(AF_INET6, "::ffff:0:0", &sin6_v4_any.sin6_addr) != 1)
1553 e(0);
1555 /* An IPv4-mapped IPv6 loopback address - ::ffff:127.0.0.1. */
1556 memcpy(&sin6_v4_lo, &sin6_any, sizeof(sin6_v4_lo));
1557 if (inet_pton(AF_INET6, "::ffff:"LOOPBACK_IPV4,
1558 &sin6_v4_lo.sin6_addr) != 1) e(0);
1560 /* An unassigned IPv4-mapped IPv6 address - ::ffff:127.255.0.254. */
1561 memcpy(&sin6_v4_rem, &sin6_any, sizeof(sin6_v4_rem));
1562 if (inet_pton(AF_INET6, "::ffff:"TEST_BLACKHOLE_IPV4,
1563 &sin6_v4_rem.sin6_addr) != 1) e(0);
1566 * An IPv6 link-local address with a scope for another interface, for
1567 * example fe80::1%em0. Since no other interfaces may be present, we
1568 * may not be able to generate such an address.
1570 have_mix = 0;
1571 for (i = 1; i < BAD_IFINDEX; i++) {
1572 if (if_indextoname(i, name) == NULL) {
1573 if (errno != ENXIO) e(0);
1574 continue;
1577 if (!strcmp(name, LOOPBACK_IFNAME))
1578 continue;
1580 /* Found one! */
1581 memcpy(&sin6_ll_mix, &sin6_ll_all, sizeof(sin6_ll_mix));
1582 sin6_ll_mix.sin6_scope_id = i;
1583 have_mix = 1;
1584 break;
1588 * Test a whole range of combinations of local and remote addresses,
1589 * both for TCP and UDP, and for UDP both for connect+send and sendto.
1590 * Not all addresses and not all combinations are compatible, and that
1591 * is exactly what we want to test. We first test binding to local
1592 * addresses. Then we test connect (and for UDP, on success, send)
1593 * with remote addresses on those local addresses that could be bound
1594 * to. Finally, for UDP sockets, we separately test sendto.
1596 for (i = 0; i < __arraycount(bind_array) - !have_mix; i++) {
1597 bp = &bind_array[i];
1599 /* Test bind(2) and getsockname(2). */
1600 if (bind_array[i].addr != NULL) {
1601 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
1603 val = 0;
1604 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1605 sizeof(val)) != 0) e(0);
1607 r = bind(fd, (struct sockaddr *)bp->addr,
1608 sizeof(*bp->addr));
1610 /* Did the bind(2) call produce the expected result? */
1611 if (r == 0) {
1612 if (bp->res != 0) e(0);
1613 } else
1614 if (r != -1 || bp->res != errno) e(0);
1616 /* The rest is for successful bind(2) calls. */
1617 if (r != 0) {
1618 if (close(fd) != 0) e(0);
1620 continue;
1623 /* Get the bound address. */
1624 len = sizeof(sin6);
1625 if (getsockname(fd, (struct sockaddr *)&sin6,
1626 &len) != 0) e(0);
1627 if (len != sizeof(sin6)) e(0);
1629 /* A port must be set. Clear it for the comparison. */
1630 if ((sin6.sin6_port == 0) == (type != SOCK_RAW)) e(0);
1632 sin6.sin6_port = 0;
1633 if (memcmp(&sin6, bp->name, sizeof(sin6)) != 0) e(0);
1635 if (close(fd) != 0) e(0);
1638 /* Test connect(2), send(2), and getpeername(2). */
1639 for (j = 0; j < __arraycount(conn_array) - !have_mix; j++) {
1640 cp = &conn_array[j];
1643 * We cannot test remote addresses without having bound
1644 * to a local address, because we may end up generating
1645 * external traffic as a result.
1647 if ((bp->flags & F_ANY) && (cp->flags & F_REM))
1648 continue;
1651 * Use non-blocking sockets only if connecting is going
1652 * to take a while before ultimately failing; TCP only.
1654 sfl = ((cp->flags & F_REM) && (type == SOCK_STREAM)) ?
1655 SOCK_NONBLOCK : 0;
1656 if ((fd = socket(AF_INET6, type | sfl, protocol)) < 0)
1657 e(0);
1659 val = 0;
1660 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1661 sizeof(val)) != 0) e(0);
1663 if (bp->addr != NULL) {
1664 if (bind(fd, (struct sockaddr *)bp->addr,
1665 sizeof(*bp->addr)) != 0) e(0);
1667 len = sizeof(sin6);
1668 if (getsockname(fd, (struct sockaddr *)&sin6,
1669 &len) != 0) e(0);
1671 port = sin6.sin6_port;
1672 } else
1673 port = 0;
1675 memcpy(&sin6, cp->addr, sizeof(sin6));
1676 sin6.sin6_port = htons(TEST_PORT_A);
1678 if ((exp = cp->res) == 0 && type == SOCK_STREAM) {
1679 if (cp->flags & F_REM)
1680 exp = EINPROGRESS;
1681 if (cp->flags & F_MIX)
1682 exp = EHOSTUNREACH;
1686 * The IPv4/IPv6 mismatch check precedes most other
1687 * checks, but (currently) not the bad-scope-ID check.
1689 if (exp != ENXIO && !(bp->flags & F_ANY) &&
1690 ((bp->flags ^ cp->flags) & F_V4))
1691 exp = EINVAL;
1694 * Create a listening or receiving socket if we expect
1695 * the test to succeed and operate on a loopback target
1696 * so that we can test addresses on that end as well.
1698 if (exp == 0 && !(cp->flags & F_REM)) {
1699 if ((fd2 = socket(AF_INET6, type,
1700 protocol)) < 0) e(0);
1702 val = 0;
1703 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY,
1704 &val, sizeof(val)) != 0) e(0);
1706 val = 1;
1707 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR,
1708 &val, sizeof(val)) != 0) e(0);
1710 memcpy(&rsin6, cp->name, sizeof(rsin6));
1711 rsin6.sin6_port = htons(TEST_PORT_A);
1713 if (bind(fd2, (struct sockaddr *)&rsin6,
1714 sizeof(rsin6)) != 0) e(0);
1716 if (type == SOCK_STREAM && listen(fd2, 1) != 0)
1717 e(0);
1718 } else
1719 fd2 = -1;
1721 r = connect(fd, (struct sockaddr *)&sin6,
1722 sizeof(sin6));
1724 if (r == 0) {
1725 if (exp != 0) e(0);
1726 } else
1727 if (r != -1 || exp != errno) e(0);
1729 if (r != 0) {
1730 if (close(fd) != 0) e(0);
1732 continue;
1736 * Connecting should always assign a local address if
1737 * no address was assigned, even if a port was assigned
1738 * already. In the latter case, the port number must
1739 * obviously not change. Test getsockname(2) again, if
1740 * we can.
1742 len = sizeof(sin6);
1743 if (getsockname(fd, (struct sockaddr *)&sin6,
1744 &len) != 0) e(0);
1745 if (len != sizeof(sin6)) e(0);
1747 if (type != SOCK_RAW) {
1748 if (sin6.sin6_port == 0) e(0);
1749 if (port != 0 && port != sin6.sin6_port) e(0);
1750 } else
1751 if (sin6.sin6_port != 0) e(0);
1752 port = sin6.sin6_port;
1754 if (!(bp->flags & F_ANY))
1755 sin6p = bp->name;
1756 else if (!(cp->flags & F_REM))
1757 sin6p = cp->name;
1758 else
1759 sin6p = NULL; /* can't test: may vary */
1761 if (sin6p != NULL) {
1762 sin6.sin6_port = 0;
1764 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1765 e(0);
1769 * Test getpeername(2). It should always be the
1770 * "normalized" version of the target address.
1772 len = sizeof(sin6);
1773 if (getpeername(fd, (struct sockaddr *)&sin6,
1774 &len) != 0) e(0);
1775 if (len != sizeof(sin6)) e(0);
1777 if (type != SOCK_RAW) {
1778 if (sin6.sin6_port != htons(TEST_PORT_A)) e(0);
1779 } else {
1780 if (sin6.sin6_port != 0) e(0);
1783 sin6.sin6_port = 0;
1784 if (memcmp(&sin6, cp->name, sizeof(sin6)) != 0) e(0);
1786 /* Test send(2) on UDP sockets. */
1787 if (type != SOCK_STREAM) {
1788 r = send(fd, "A", 1, 0);
1791 * For remote (rejected) addresses and scope
1792 * mixing, actual send calls may fail after the
1793 * connect succeeded.
1795 if (r == -1 &&
1796 !(cp->flags & (F_REM | F_MIX))) e(0);
1797 else if (r != -1 && r != 1) e(0);
1799 if (r != 1 && fd2 != -1) {
1800 if (close(fd2) != 0) e(0);
1801 fd2 = -1;
1805 if (fd2 == -1) {
1806 if (close(fd) != 0) e(0);
1808 continue;
1812 * The connect or send call succeeded, so we should now
1813 * be able to check the other end.
1815 if (type == SOCK_STREAM) {
1816 /* Test accept(2). */
1817 len = sizeof(sin6);
1818 if ((fd3 = accept(fd2,
1819 (struct sockaddr *)&sin6, &len)) < 0) e(0);
1820 if (len != sizeof(sin6)) e(0);
1822 if (close(fd2) != 0) e(0);
1824 if (sin6.sin6_port != port) e(0);
1825 sin6.sin6_port = 0;
1827 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1828 e(0);
1830 /* Test getpeername(2). */
1831 if (getpeername(fd3, (struct sockaddr *)&sin6,
1832 &len) != 0) e(0);
1833 if (len != sizeof(sin6)) e(0);
1835 if (sin6.sin6_port != port) e(0);
1836 sin6.sin6_port = 0;
1838 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1839 e(0);
1841 /* Test getsockname(2). */
1842 if (getsockname(fd3, (struct sockaddr *)&sin6,
1843 &len) != 0) e(0);
1844 if (len != sizeof(sin6)) e(0);
1846 if (sin6.sin6_port != htons(TEST_PORT_A)) e(0);
1847 sin6.sin6_port = 0;
1849 if (memcmp(&sin6, cp->name, sizeof(sin6)) != 0)
1850 e(0);
1852 if (close(fd3) != 0) e(0);
1853 } else {
1854 /* Test recvfrom(2). */
1855 len = sizeof(sin6);
1856 if (recvfrom(fd2, buf, sizeof(buf), 0,
1857 (struct sockaddr *)&sin6, &len) != 1) e(0);
1859 if (buf[0] != 'A') e(0);
1860 if (len != sizeof(sin6)) e(0);
1862 if (sin6.sin6_port != port) e(0);
1863 sin6.sin6_port = 0;
1865 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1866 e(0);
1868 if (close(fd2) != 0) e(0);
1871 if (close(fd) != 0) e(0);
1874 if (type == SOCK_STREAM)
1875 continue;
1877 /* Test sendto(2). */
1878 for (j = 0; j < __arraycount(conn_array) - !have_mix; j++) {
1879 cp = &conn_array[j];
1882 * We cannot test remote addresses without having bound
1883 * to a local address, because we may end up generating
1884 * external traffic as a result.
1886 if ((bp->flags & F_ANY) && (cp->flags & F_REM))
1887 continue;
1889 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
1891 val = 0;
1892 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1893 sizeof(val)) != 0) e(0);
1895 if (bp->addr != NULL) {
1896 if (bind(fd, (struct sockaddr *)bp->addr,
1897 sizeof(*bp->addr)) != 0) e(0);
1899 len = sizeof(sin6);
1900 if (getsockname(fd, (struct sockaddr *)&sin6,
1901 &len) != 0) e(0);
1903 port = sin6.sin6_port;
1904 } else
1905 port = 0;
1907 memcpy(&sin6, cp->addr, sizeof(sin6));
1908 if (type != SOCK_RAW)
1909 sin6.sin6_port = htons(TEST_PORT_B);
1911 if ((exp = cp->res) == 0) {
1912 if (cp->flags & (F_REM | F_MIX))
1913 exp = EHOSTUNREACH;
1917 * The IPv4/IPv6 mismatch check precedes most other
1918 * checks, but (currently) not the bad-scope-ID check.
1920 if (exp != ENXIO && !(bp->flags & F_ANY) &&
1921 ((bp->flags ^ cp->flags) & F_V4))
1922 exp = EINVAL;
1925 * If we expect the sendto(2) call to succeed and to be
1926 * able to receive the packet, create a receiving
1927 * socket to test recvfrom(2) addresses.
1929 if (exp == 0 && !(cp->flags & F_REM)) {
1930 if ((fd2 = socket(AF_INET6, type,
1931 protocol)) < 0) e(0);
1933 val = 0;
1934 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY,
1935 &val, sizeof(val)) != 0) e(0);
1937 val = 1;
1938 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR,
1939 &val, sizeof(val)) != 0) e(0);
1941 memcpy(&rsin6, cp->name, sizeof(rsin6));
1942 if (type != SOCK_RAW)
1943 rsin6.sin6_port = htons(TEST_PORT_B);
1945 if (bind(fd2, (struct sockaddr *)&rsin6,
1946 sizeof(rsin6)) != 0) e(0);
1947 } else
1948 fd2 = -1;
1950 r = sendto(fd, "B", 1, 0, (struct sockaddr *)&sin6,
1951 sizeof(sin6));
1953 if (r != 1) {
1954 if (r != -1 || exp != errno) e(0);
1956 if (close(fd) != 0) e(0);
1958 continue;
1961 if (exp != 0) e(0);
1964 * The sendto(2) call should assign a local port to the
1965 * socket if none was assigned before, but it must not
1966 * assign a local address.
1968 len = sizeof(sin6);
1969 if (getsockname(fd, (struct sockaddr *)&sin6,
1970 &len) != 0) e(0);
1971 if (len != sizeof(sin6)) e(0);
1973 if (type != SOCK_RAW) {
1974 if (sin6.sin6_port == 0) e(0);
1975 if (port != 0 && port != sin6.sin6_port) e(0);
1976 } else
1977 if (sin6.sin6_port != 0) e(0);
1978 port = sin6.sin6_port;
1980 sin6.sin6_port = 0;
1981 if (memcmp(&sin6, bp->name, sizeof(sin6)) != 0) e(0);
1983 if (fd2 != -1) {
1984 /* Test recvfrom(2) on the receiving socket. */
1985 len = sizeof(sin6);
1986 if (recvfrom(fd2, buf, sizeof(buf), 0,
1987 (struct sockaddr *)&sin6, &len) != 1) e(0);
1989 if (buf[0] != 'B') e(0);
1990 if (len != sizeof(sin6)) e(0);
1992 if (sin6.sin6_port != port) e(0);
1993 sin6.sin6_port = 0;
1995 if (bp->flags & F_ANY)
1996 sin6p = cp->name;
1997 else
1998 sin6p = bp->name;
2000 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
2001 e(0);
2003 if (close(fd2) != 0) e(0);
2006 if (close(fd) != 0) e(0);
2011 * Test that scoped addresses actually work as expected. For this we
2012 * need two interfaces with assigned link-local addresses, one of which
2013 * being the loopback interface. Start by finding another one.
2015 if (getifaddrs(&ifa) != 0) e(0);
2017 found = 0;
2018 for (ifp = ifa; ifp != NULL; ifp = ifp->ifa_next) {
2019 if (strcmp(ifp->ifa_name, LOOPBACK_IFNAME) == 0)
2020 continue;
2022 if (!(ifp->ifa_flags & IFF_UP) || ifp->ifa_addr == NULL ||
2023 ifp->ifa_addr->sa_family != AF_INET6)
2024 continue;
2026 memcpy(&sin6, ifp->ifa_addr, sizeof(sin6));
2028 if (!IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
2029 continue;
2032 * Not only the interface, but also the link has to be up for
2033 * this to work. lwIP will drop all packets, including those
2034 * sent to locally assigned addresses, if the link is down.
2035 * Of course, figuring out whether the interface link is down
2036 * is by no means convenient, especially if we want to do it
2037 * right (i.e., not rely on getifaddrs' address sorting).
2039 link_state = LINK_STATE_DOWN;
2041 for (ifp2 = ifa; ifp2 != NULL; ifp2 = ifp2->ifa_next) {
2042 if (!strcmp(ifp2->ifa_name, ifp->ifa_name) &&
2043 ifp2->ifa_addr != NULL &&
2044 ifp2->ifa_addr->sa_family == AF_LINK &&
2045 ifp2->ifa_data != NULL) {
2046 memcpy(&link_state, &((struct if_data *)
2047 ifp2->ifa_data)->ifi_link_state,
2048 sizeof(link_state));
2050 break;
2054 if (link_state == LINK_STATE_DOWN)
2055 continue;
2058 * In addition, the address has to be in a state where it can
2059 * be used as source address. In practice, that means it must
2060 * not be in ND6 duplicated or tentative state.
2062 memset(&ifr, 0, sizeof(ifr));
2063 strlcpy(ifr.ifr_name, ifp->ifa_name, sizeof(ifr.ifr_name));
2064 memcpy(&ifr.ifr_addr, &sin6, sizeof(sin6));
2066 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
2068 if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr) != 0) e(0);
2070 if (close(fd) != 0) e(0);
2072 if (ifr.ifr_ifru.ifru_flags6 &
2073 (IN6_IFF_DUPLICATED | IN6_IFF_TENTATIVE))
2074 continue;
2076 /* Compensate for poor decisions made by the KAME project. */
2077 inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL);
2079 if (sin6.sin6_scope_id == 0 || sin6.sin6_scope_id == ifindex)
2080 e(0);
2082 found = 1;
2084 break;
2087 freeifaddrs(ifa);
2090 * If no second interface with a link-local address was found, we
2091 * cannot perform the rest of this subtest.
2093 if (!found)
2094 return;
2097 * Create one socket that binds to the link-local address of the
2098 * non-loopback interface. The main goal of this subtest is to ensure
2099 * that traffic directed to that same link-local address but with the
2100 * loopback scope ID does not arrive on this socket.
2102 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2104 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
2106 len = sizeof(sin6);
2107 if (getsockname(fd, (struct sockaddr *)&sin6, &len) != 0) e(0);
2108 if (len != sizeof(sin6)) e(0);
2110 ifindex2 = sin6.sin6_scope_id;
2112 if (type == SOCK_STREAM) {
2113 if (listen(fd, 2) != 0) e(0);
2115 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2117 /* Connecting to the loopback-scope address should time out. */
2118 signal(SIGALRM, socklib_got_signal);
2119 alarm(1);
2121 sin6.sin6_scope_id = ifindex;
2123 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != -1)
2124 e(0);
2126 if (errno != EINTR) e(0);
2128 if (close(fd2) != 0) e(0);
2130 /* Connecting to the real interface's address should work. */
2131 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2133 sin6.sin6_scope_id = ifindex2;
2135 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0)
2136 e(0);
2138 if (close(fd2) != 0) e(0);
2139 } else {
2141 * First connect+send. Sending to the loopback-scope address
2142 * should result in a rejected packet.
2144 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2146 sin6.sin6_scope_id = ifindex;
2148 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0)
2149 e(0);
2151 if (send(fd2, "C", 1, 0) != -1) e(0);
2152 if (errno != EHOSTUNREACH) e(0);
2154 if (close(fd2) != 0) e(0);
2156 /* Sending to the real-interface address should work. */
2157 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2159 sin6.sin6_scope_id = ifindex2;
2161 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0)
2162 e(0);
2164 if (send(fd2, "D", 1, 0) != 1) e(0);
2166 if (close(fd2) != 0) e(0);
2169 * Then sendto. Sending to the loopback-scope address should
2170 * result in a rejected packet.
2172 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2174 sin6.sin6_scope_id = ifindex;
2176 if (sendto(fd2, "E", 1, 0, (struct sockaddr *)&sin6,
2177 sizeof(sin6)) != -1) e(0);
2178 if (errno != EHOSTUNREACH) e(0);
2180 if (close(fd2) != 0) e(0);
2182 /* Sending to the real-interface address should work. */
2183 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2185 sin6.sin6_scope_id = ifindex2;
2187 if (sendto(fd2, "F", 1, 0, (struct sockaddr *)&sin6,
2188 sizeof(sin6)) != 1) e(0);
2190 if (close(fd2) != 0) e(0);
2192 len = sizeof(sin6);
2193 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6,
2194 &len) != 1) e(0);
2195 if (buf[0] != 'D') e(0);
2197 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6,
2198 &len) != 1) e(0);
2199 if (buf[0] != 'F') e(0);
2202 if (close(fd) != 0) e(0);
2206 * Test multicast support for the given socket type, which may be SOCK_DGRAM or
2207 * SOCK_RAW.
2209 void
2210 socklib_test_multicast(int type, int protocol)
2212 struct sockaddr_in sinA, sinB, sin_array[3];
2213 struct sockaddr_in6 sin6A, sin6B, sin6_array[3];
2214 struct ip_mreq imr;
2215 struct ipv6_mreq ipv6mr;
2216 struct in6_pktinfo ipi6;
2217 struct iovec iov;
2218 struct msghdr msg;
2219 struct cmsghdr *cmsg;
2220 socklen_t len, hdrlen;
2221 unsigned int count, ifindex, ifindex2;
2222 union {
2223 struct cmsghdr cmsg;
2224 char buf[256];
2225 } control;
2226 char buf[sizeof(struct ip) + 1], *buf2, name[IF_NAMESIZE];
2227 uint8_t byte, ttl;
2228 int i, j, r, fd, fd2, val;
2231 * Start with testing join/leave mechanics, for both IPv4 and IPv6.
2232 * Note that we cannot test specifying no interface along with a
2233 * multicast address (except for scoped IPv6 addresses), because the
2234 * auto-selected interface is likely a public one, and joining the
2235 * group will thus create external traffic, which is generally
2236 * something we want to avoid in the tests.
2238 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2240 memset(&imr, 0, sizeof(imr));
2242 /* Basic join-leave combo. */
2243 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2244 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
2246 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2247 sizeof(imr)) != 0) e(0);
2249 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2250 sizeof(imr)) != 0) e(0);
2252 /* Joining the same multicast group twice is an error. */
2253 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2254 sizeof(imr)) != 0) e(0);
2256 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2257 sizeof(imr)) != -1) e(0);
2258 if (errno != EEXIST) e(0);
2260 /* If an interface address is specified, it must match an interface. */
2261 imr.imr_interface.s_addr = htonl(TEST_BLACKHOLE_IPV4);
2263 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2264 sizeof(imr)) != -1) e(0);
2265 if (errno != EADDRNOTAVAIL) e(0);
2267 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2268 sizeof(imr)) != -1) e(0);
2269 if (errno != EADDRNOTAVAIL) e(0);
2271 /* The given multicast address must be an actual multicast address. */
2272 imr.imr_multiaddr.s_addr = htonl(INADDR_ANY);
2273 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
2275 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2276 sizeof(imr)) != -1) e(0);
2277 if (errno != EADDRNOTAVAIL) e(0);
2279 imr.imr_multiaddr.s_addr = htonl(INADDR_LOOPBACK);
2281 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2282 sizeof(imr)) != -1) e(0);
2283 if (errno != EADDRNOTAVAIL) e(0);
2285 /* Leaving a multicast group not joined is an error. */
2286 imr.imr_multiaddr.s_addr =
2287 htonl(ntohl(inet_addr(TEST_MULTICAST_IPV4)) + 1);
2289 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2290 sizeof(imr)) != -1) e(0);
2291 if (errno != ESRCH) e(0);
2294 * When leaving a group, an interface address need not be specified,
2295 * even if one was specified when joining. As mentioned, we cannot
2296 * test joining the same address on multiple interfaces, though.
2298 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2299 imr.imr_interface.s_addr = htonl(INADDR_ANY);
2301 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2302 sizeof(imr)) != 0) e(0);
2304 /* There must be a reasonable per-socket group membership limit. */
2305 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
2307 for (count = 0; count < IP_MAX_MEMBERSHIPS + 1; count++) {
2308 imr.imr_multiaddr.s_addr =
2309 htonl(ntohl(inet_addr(TEST_MULTICAST_IPV4)) + count);
2311 r = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2312 sizeof(imr));
2314 if (r != 0) {
2315 if (r != -1 || errno != ENOBUFS) e(0);
2316 break;
2319 if (count < 8 || count > IP_MAX_MEMBERSHIPS) e(0);
2321 /* Test leaving a group at the start of the per-socket list. */
2322 imr.imr_multiaddr.s_addr =
2323 htonl(ntohl(inet_addr(TEST_MULTICAST_IPV4)) + count - 1);
2325 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2326 sizeof(imr)) != 0) e(0);
2328 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2329 sizeof(imr)) != -1) e(0);
2330 if (errno != ESRCH) e(0);
2332 /* Test leaving a group in the middle of the per-socket list. */
2333 imr.imr_multiaddr.s_addr =
2334 htonl(ntohl(inet_addr(TEST_MULTICAST_IPV4)) + count / 2);
2336 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2337 sizeof(imr)) != 0) e(0);
2339 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2340 sizeof(imr)) != -1) e(0);
2341 if (errno != ESRCH) e(0);
2343 /* Test leaving a group at the end of the per-socket list. */
2344 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2346 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2347 sizeof(imr)) != 0) e(0);
2349 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2350 sizeof(imr)) != -1) e(0);
2351 if (errno != ESRCH) e(0);
2353 if (close(fd) != 0) e(0);
2355 /* Still basic join/leave mechanics.. on to IPv6.. */
2356 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2358 memset(&ipv6mr, 0, sizeof(ipv6mr));
2360 /* Basic join-leave combo. */
2361 ifindex = if_nametoindex(LOOPBACK_IFNAME);
2363 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2364 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2365 ipv6mr.ipv6mr_interface = ifindex;
2367 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2368 sizeof(ipv6mr)) != 0) e(0);
2370 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2371 sizeof(ipv6mr)) != 0) e(0);
2373 /* Joining the same multicast group twice is an error. */
2374 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2375 sizeof(ipv6mr)) != 0) e(0);
2377 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2378 sizeof(ipv6mr)) != -1) e(0);
2379 if (errno != EEXIST) e(0);
2381 /* If an interface index is specified, it must be valid. */
2382 ipv6mr.ipv6mr_interface = BAD_IFINDEX;
2384 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2385 sizeof(ipv6mr)) != -1) e(0);
2386 if (errno != ENXIO) e(0);
2388 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2389 sizeof(ipv6mr)) != -1) e(0);
2390 if (errno != ENXIO) e(0);
2392 ipv6mr.ipv6mr_interface = 0x80000000UL | ifindex;
2394 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2395 sizeof(ipv6mr)) != -1) e(0);
2396 if (errno != ENXIO) e(0);
2398 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2399 sizeof(ipv6mr)) != -1) e(0);
2400 if (errno != ENXIO) e(0);
2402 /* The given multicast address must be an actual multicast address. */
2403 ipv6mr.ipv6mr_interface = ifindex;
2404 memcpy(&ipv6mr.ipv6mr_multiaddr, &in6addr_any, sizeof(in6addr_any));
2406 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2407 sizeof(ipv6mr)) != -1) e(0);
2408 if (errno != EADDRNOTAVAIL) e(0);
2410 memcpy(&ipv6mr.ipv6mr_multiaddr, &in6addr_loopback,
2411 sizeof(in6addr_loopback));
2413 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2414 sizeof(ipv6mr)) != -1) e(0);
2415 if (errno != EADDRNOTAVAIL) e(0);
2417 /* Leaving a multicast group not joined is an error. */
2418 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2419 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2420 ipv6mr.ipv6mr_multiaddr.s6_addr[15]++;
2422 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2423 sizeof(ipv6mr)) != -1) e(0);
2424 if (errno != ESRCH) e(0);
2427 * When leaving a group, an interface index need not be specified,
2428 * even if one was specified when joining. If one is specified, it
2429 * must match, though. As mentioned, we cannot test joining the same
2430 * address on multiple interfaces, though.
2432 ipv6mr.ipv6mr_multiaddr.s6_addr[15]--;
2433 ipv6mr.ipv6mr_interface = ifindex + 1; /* lazy: may or may not exist */
2435 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2436 sizeof(ipv6mr)) != -1) e(0);
2437 if (errno != ENXIO && errno != ESRCH) e(0);
2439 ipv6mr.ipv6mr_interface = 0;
2441 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2442 sizeof(ipv6mr)) != 0) e(0);
2444 /* For link-local addresses, an interface must always be specified. */
2445 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
2446 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2447 ipv6mr.ipv6mr_interface = 0;
2449 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2450 sizeof(ipv6mr)) != -1) e(0);
2451 if (errno != EADDRNOTAVAIL) e(0);
2453 ipv6mr.ipv6mr_interface = ifindex;
2455 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2456 sizeof(ipv6mr)) != 0) e(0);
2458 ipv6mr.ipv6mr_interface = 0;
2460 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2461 sizeof(ipv6mr)) != -1) e(0);
2462 if (errno != EADDRNOTAVAIL) e(0);
2464 ipv6mr.ipv6mr_interface = ifindex;
2466 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2467 sizeof(ipv6mr)) != 0) e(0);
2469 /* IPv4-mapped IPv6 multicast addresses are currently not supported. */
2470 val = 0;
2471 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
2472 e(0);
2474 if (inet_pton(AF_INET6, "::ffff:"TEST_MULTICAST_IPV4,
2475 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2476 ipv6mr.ipv6mr_interface = ifindex;
2478 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2479 sizeof(ipv6mr)) != -1) e(0);
2480 if (errno != EADDRNOTAVAIL) e(0);
2483 * There must be a reasonable per-socket group membership limit.
2484 * Apparently there is no IPv6 equivalent of IP_MAX_MEMBERSHIPS..
2486 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2487 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2488 ipv6mr.ipv6mr_interface = ifindex;
2490 for (count = 0; count < IP_MAX_MEMBERSHIPS + 1; count++) {
2491 r = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2492 sizeof(ipv6mr));
2494 if (r != 0) {
2495 if (r != -1 || errno != ENOBUFS) e(0);
2496 break;
2499 ipv6mr.ipv6mr_multiaddr.s6_addr[15]++;
2501 if (count < 8 || count > IP_MAX_MEMBERSHIPS) e(0);
2503 /* Test leaving a group at the start of the per-socket list. */
2504 ipv6mr.ipv6mr_multiaddr.s6_addr[15]--;
2506 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2507 sizeof(ipv6mr)) != 0) e(0);
2509 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2510 sizeof(ipv6mr)) != -1) e(0);
2511 if (errno != ESRCH) e(0);
2513 /* Test leaving a group in the middle of the per-socket list. */
2514 ipv6mr.ipv6mr_multiaddr.s6_addr[15] -= count / 2;
2516 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2517 sizeof(ipv6mr)) != 0) e(0);
2519 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2520 sizeof(ipv6mr)) != -1) e(0);
2521 if (errno != ESRCH) e(0);
2523 /* Test leaving a group at the end of the per-socket list. */
2524 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2525 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2527 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2528 sizeof(ipv6mr)) != 0) e(0);
2530 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2531 sizeof(ipv6mr)) != -1) e(0);
2532 if (errno != ESRCH) e(0);
2534 if (close(fd) != 0) e(0);
2537 * Test sending multicast packets, multicast transmission options, and
2538 * basic receipt. Note that we cannot test IP(V6)_MULTICAST_LOOP
2539 * because no extra duplicates are generated on loopback interfaces.
2541 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2543 /* For UDP, get an assigned port number. */
2544 memset(&sinA, 0, sizeof(sinA));
2545 sinA.sin_family = AF_INET;
2547 if (type == SOCK_DGRAM) {
2548 sinA.sin_addr.s_addr = htonl(INADDR_ANY);
2550 if (bind(fd, (struct sockaddr *)&sinA,
2551 sizeof(sinA)) != 0) e(0);
2553 len = sizeof(sinA);
2554 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0) e(0);
2557 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2558 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
2560 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2561 sizeof(imr)) != 0) e(0);
2563 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
2565 /* Regular packet, default unicast TTL, sendto. */
2566 sinA.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2568 if (sendto(fd2, "A", 1, 0, (struct sockaddr *)&sinA,
2569 sizeof(sinA)) != 1) e(0);
2571 /* Multicast packet, default multicast TTL, sendto. */
2572 if (setsockopt(fd2, IPPROTO_IP, IP_MULTICAST_IF, &sinA.sin_addr,
2573 sizeof(sinA.sin_addr)) != 0) e(0);
2575 sinA.sin_addr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2577 if (sendto(fd2, "B", 1, 0, (struct sockaddr *)&sinA,
2578 sizeof(sinA)) != 1) e(0);
2580 /* Multicast packet, custom multicast TTL, connect+send. */
2581 byte = 123;
2582 if (setsockopt(fd2, IPPROTO_IP, IP_MULTICAST_TTL, &byte,
2583 sizeof(byte)) != 0) e(0);
2585 if (connect(fd2, (struct sockaddr *)&sinA, sizeof(sinA)) != 0) e(0);
2587 if (send(fd2, "C", 1, 0) != 1) e(0);
2589 /* Receive and validate what we sent. */
2590 len = sizeof(sinA);
2591 if (getsockname(fd2, (struct sockaddr *)&sinA, &len) != 0) e(0);
2593 len = sizeof(ttl);
2594 if (getsockopt(fd2, IPPROTO_IP, IP_TTL, &ttl, &len) != 0) e(0);
2596 val = 1;
2597 if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &val, sizeof(val)) != 0)
2598 e(0);
2600 hdrlen = (type == SOCK_RAW) ? sizeof(struct ip) : 0;
2602 memset(&iov, 0, sizeof(iov));
2603 iov.iov_base = buf;
2604 iov.iov_len = hdrlen + 1;
2606 for (i = 0; i < 3; ) {
2607 memset(&msg, 0, sizeof(msg));
2608 msg.msg_name = &sinB;
2609 msg.msg_namelen = sizeof(sinB);
2610 msg.msg_iov = &iov;
2611 msg.msg_iovlen = 1;
2612 msg.msg_control = control.buf;
2613 msg.msg_controllen = sizeof(control);
2615 r = recvmsg(fd, &msg, 0);
2616 if (r < 0) e(0);
2618 if (msg.msg_namelen != sizeof(sinB)) e(0);
2621 * There is a tiny possibility that we receive other packets
2622 * on the receiving socket, as it is not bound to a particular
2623 * address, and there is currently no way to bind a socket to
2624 * a particular interface. We therefore skip packets not from
2625 * the sending socket, conveniently testing the accuracy of the
2626 * reported source address as a side effect.
2628 if (memcmp(&sinA, &sinB, sizeof(sinA)))
2629 continue;
2631 if (r != hdrlen + 1) e(0);
2632 if (buf[hdrlen] != 'A' + i) e(0);
2634 if (msg.msg_flags & MSG_BCAST) e(0);
2636 if ((cmsg = CMSG_FIRSTHDR(&msg)) == NULL) e(0);
2637 if (cmsg->cmsg_level != IPPROTO_IP) e(0);
2638 if (cmsg->cmsg_type != IP_TTL) e(0);
2639 if (cmsg->cmsg_len != CMSG_LEN(sizeof(byte))) e(0);
2640 memcpy(&byte, CMSG_DATA(cmsg), sizeof(byte));
2642 switch (i) {
2643 case 0:
2644 if (msg.msg_flags & MSG_MCAST) e(0);
2645 if (byte != ttl) e(0);
2646 break;
2647 case 1:
2648 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2649 if (byte != 1) e(0);
2650 break;
2651 case 2:
2652 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2653 if (byte != 123) e(0);
2654 break;
2657 i++;
2660 if (close(fd2) != 0) e(0);
2661 if (close(fd) != 0) e(0);
2663 /* Still the send tests, but now IPv6.. */
2664 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2666 /* For UDP, get an assigned port number. */
2667 memset(&sin6A, 0, sizeof(sin6A));
2668 sin6A.sin6_family = AF_INET6;
2670 if (type == SOCK_DGRAM) {
2671 if (bind(fd, (struct sockaddr *)&sin6A,
2672 sizeof(sin6A)) != 0) e(0);
2674 len = sizeof(sin6A);
2675 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
2676 e(0);
2679 memcpy(&sin6B, &sin6A, sizeof(sin6B));
2681 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2682 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2683 ipv6mr.ipv6mr_interface = ifindex;
2685 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2686 sizeof(ipv6mr)) != 0) e(0);
2688 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2690 /* Regular packet, default unicast TTL, sendto. */
2691 if (inet_pton(AF_INET6, LOOPBACK_IPV6_LL, &sin6A.sin6_addr) != 1) e(0);
2692 sin6A.sin6_scope_id = ifindex;
2694 if (sendto(fd2, "D", 1, 0, (struct sockaddr *)&sin6A,
2695 sizeof(sin6A)) != 1) e(0);
2697 /* Multicast packet, default multicast TTL, sendto. */
2698 val = (int)ifindex;
2699 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
2700 sizeof(val)) != 0) e(0);
2702 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2703 &sin6A.sin6_addr) != 1) e(0);
2704 sin6A.sin6_scope_id = 0;
2706 if (sendto(fd2, "E", 1, 0, (struct sockaddr *)&sin6A,
2707 sizeof(sin6A)) != 1) e(0);
2709 /* Multicast packet, custom multicast TTL, connect+send. */
2710 val = 125;
2711 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
2712 sizeof(val)) != 0) e(0);
2714 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2716 if (send(fd2, "F", 1, 0) != 1) e(0);
2718 len = sizeof(sin6A);
2719 if (getsockname(fd2, (struct sockaddr *)&sin6A, &len) != 0) e(0);
2722 * Repeat the last two tests, but now with a link-local multicast
2723 * address. In particular link-local destination addresses do not need
2724 * a zone ID, and the system should be smart enough to pick the right
2725 * zone ID if an outgoing multicast interface is configured. Zone
2726 * violations should be detected and result in errors.
2728 if (close(fd2) != 0) e(0);
2730 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2732 if (bind(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2734 memcpy(&sin6A, &sin6B, sizeof(sin6A));
2736 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
2737 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2738 ipv6mr.ipv6mr_interface = ifindex;
2740 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2741 sizeof(ipv6mr)) != 0) e(0);
2743 /* Link-local multicast packet, sendto. */
2744 val = (int)ifindex;
2745 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
2746 sizeof(val)) != 0) e(0);
2748 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
2749 &sin6A.sin6_addr) != 1) e(0);
2750 sin6A.sin6_scope_id = 0;
2752 if (sendto(fd2, "G", 1, 0, (struct sockaddr *)&sin6A,
2753 sizeof(sin6A)) != 1) e(0);
2755 sin6A.sin6_scope_id = ifindex + 1; /* lazy: may or may not be valid */
2757 if (sendto(fd2, "X", 1, 0, (struct sockaddr *)&sin6A,
2758 sizeof(sin6A)) != -1) e(0);
2759 if (errno != ENXIO && errno != EHOSTUNREACH) e(0);
2761 sin6A.sin6_scope_id = ifindex;
2763 if (sendto(fd2, "H", 1, 0, (struct sockaddr *)&sin6A,
2764 sizeof(sin6A)) != 1) e(0);
2766 /* Link-local multicast packet, connect+send. */
2767 sin6A.sin6_scope_id = 0;
2769 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2771 if (send(fd2, "I", 1, 0) != 1) e(0);
2773 len = sizeof(sin6A);
2774 if (getsockname(fd2, (struct sockaddr *)&sin6A, &len) != 0) e(0);
2776 /* Receive and validate what we sent. */
2777 len = sizeof(val);
2778 if (getsockopt(fd2, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
2779 &len) != 0) e(0);
2780 ttl = (uint8_t)val;
2782 val = 1;
2783 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val,
2784 sizeof(val)) != 0) e(0);
2786 memset(&iov, 0, sizeof(iov));
2787 iov.iov_base = buf;
2788 iov.iov_len = 1;
2790 for (i = 0; i < 6; ) {
2791 memset(&msg, 0, sizeof(msg));
2792 msg.msg_name = &sin6B;
2793 msg.msg_namelen = sizeof(sin6B);
2794 msg.msg_iov = &iov;
2795 msg.msg_iovlen = 1;
2796 msg.msg_control = control.buf;
2797 msg.msg_controllen = sizeof(control);
2799 r = recvmsg(fd, &msg, 0);
2800 if (r < 0) e(0);
2802 if (msg.msg_namelen != sizeof(sin6B)) e(0);
2804 if (memcmp(&sin6A, &sin6B, sizeof(sin6A)))
2805 continue;
2807 if (r != 1) e(0);
2808 if (buf[0] != 'D' + i) e(0);
2810 if (msg.msg_flags & MSG_BCAST) e(0);
2812 if ((cmsg = CMSG_FIRSTHDR(&msg)) == NULL) e(0);
2813 if (cmsg->cmsg_level != IPPROTO_IPV6) e(0);
2814 if (cmsg->cmsg_type != IPV6_HOPLIMIT) e(0);
2815 if (cmsg->cmsg_len != CMSG_LEN(sizeof(val))) e(0);
2816 memcpy(&val, CMSG_DATA(cmsg), sizeof(val));
2818 switch (i) {
2819 case 0:
2820 if (msg.msg_flags & MSG_MCAST) e(0);
2821 if (val != (int)ttl) e(0);
2822 break;
2823 case 1:
2824 case 3:
2825 case 4:
2826 case 5:
2827 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2828 if (val != 1) e(0);
2829 break;
2830 case 2:
2831 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2832 if (val != 125) e(0);
2833 break;
2836 i++;
2839 if (close(fd2) != 0) e(0);
2840 if (close(fd) != 0) e(0);
2843 * Test receiving multicast packets on a bound socket. We have already
2844 * tested receiving packets on an unbound socket, so we need not
2845 * incorporate that into this test as well.
2847 memset(sin_array, 0, sizeof(sin_array));
2848 sin_array[0].sin_family = AF_INET;
2849 sin_array[0].sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2850 sin_array[1].sin_family = AF_INET;
2851 sin_array[1].sin_addr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2852 sin_array[2].sin_family = AF_INET;
2853 sin_array[2].sin_addr.s_addr =
2854 htonl(ntohl(sin_array[1].sin_addr.s_addr) + 1);
2856 for (i = 0; i < __arraycount(sin_array); i++) {
2857 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2859 if (bind(fd, (struct sockaddr *)&sin_array[i],
2860 sizeof(sin_array[i])) != 0) e(0);
2862 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
2863 memcpy(&imr.imr_multiaddr, &sin_array[1].sin_addr,
2864 sizeof(imr.imr_multiaddr));
2865 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2866 sizeof(imr)) != 0) e(0);
2868 memcpy(&imr.imr_multiaddr, &sin_array[2].sin_addr,
2869 sizeof(imr.imr_multiaddr));
2870 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2871 sizeof(imr)) != 0) e(0);
2873 len = sizeof(sinA);
2874 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0) e(0);
2876 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
2878 if (setsockopt(fd2, IPPROTO_IP, IP_MULTICAST_IF,
2879 &imr.imr_interface, sizeof(imr.imr_interface)) != 0) e(0);
2881 for (j = 0; j < __arraycount(sin_array); j++) {
2882 memcpy(&sinA.sin_addr, &sin_array[j].sin_addr,
2883 sizeof(sinA.sin_addr));
2885 byte = 'A' + j;
2886 if (sendto(fd2, &byte, sizeof(byte), 0,
2887 (struct sockaddr *)&sinA,
2888 sizeof(sinA)) != sizeof(byte)) e(0);
2891 if (recv(fd, buf, sizeof(buf), 0) !=
2892 hdrlen + sizeof(byte)) e(0);
2893 if (buf[hdrlen] != 'A' + i) e(0);
2895 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
2896 if (errno != EWOULDBLOCK) e(0);
2898 if (close(fd2) != 0) e(0);
2899 if (close(fd) != 0) e(0);
2902 /* Still testing receiving on bound sockets, now IPv6.. */
2903 memset(sin6_array, 0, sizeof(sin6_array));
2904 sin6_array[0].sin6_family = AF_INET6;
2905 memcpy(&sin6_array[0].sin6_addr, &in6addr_loopback,
2906 sizeof(sin6_array[0].sin6_addr));
2907 sin6_array[1].sin6_family = AF_INET6;
2908 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2909 &sin6_array[1].sin6_addr) != 1) e(0);
2910 sin6_array[2].sin6_family = AF_INET6;
2911 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
2912 &sin6_array[2].sin6_addr) != 1) e(0);
2915 * As with unicast addresses, binding to link-local multicast addresses
2916 * requires a proper zone ID.
2918 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2920 if (bind(fd, (struct sockaddr *)&sin6_array[2],
2921 sizeof(sin6_array[2])) != -1) e(0);
2922 if (errno != EADDRNOTAVAIL) e(0);
2924 sin6_array[2].sin6_scope_id = BAD_IFINDEX;
2926 if (bind(fd, (struct sockaddr *)&sin6_array[2],
2927 sizeof(sin6_array[2])) != -1) e(0);
2928 if (errno != ENXIO) e(0);
2930 sin6_array[2].sin6_scope_id = ifindex;
2932 if (close(fd) != 0) e(0);
2934 for (i = 0; i < __arraycount(sin6_array); i++) {
2935 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2937 if (bind(fd, (struct sockaddr *)&sin6_array[i],
2938 sizeof(sin6_array[i])) != 0) e(0);
2940 ipv6mr.ipv6mr_interface = ifindex;
2941 memcpy(&ipv6mr.ipv6mr_multiaddr, &sin6_array[1].sin6_addr,
2942 sizeof(ipv6mr.ipv6mr_multiaddr));
2943 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2944 sizeof(ipv6mr)) != 0) e(0);
2946 memcpy(&ipv6mr.ipv6mr_multiaddr, &sin6_array[2].sin6_addr,
2947 sizeof(ipv6mr.ipv6mr_multiaddr));
2948 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2949 sizeof(ipv6mr)) != 0) e(0);
2951 len = sizeof(sin6A);
2952 if (getsockname(fd, (struct sockaddr *)&sin6A,
2953 &len) != 0) e(0);
2955 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2957 val = (int)ifindex;
2958 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
2959 sizeof(val)) != 0) e(0);
2961 for (j = 0; j < __arraycount(sin6_array); j++) {
2962 memcpy(&sin6A.sin6_addr, &sin6_array[j].sin6_addr,
2963 sizeof(sin6A.sin6_addr));
2965 byte = 'A' + j;
2966 if (sendto(fd2, &byte, sizeof(byte), 0,
2967 (struct sockaddr *)&sin6A,
2968 sizeof(sin6A)) != sizeof(byte)) e(0);
2971 if (recv(fd, buf, sizeof(buf), 0) != sizeof(byte)) e(0);
2972 if (buf[0] != 'A' + i) e(0);
2974 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
2975 if (errno != EWOULDBLOCK) e(0);
2977 if (close(fd2) != 0) e(0);
2978 if (close(fd) != 0) e(0);
2982 * Now test *sending* on a socket bound to a multicast address. The
2983 * multicast address must not show up as the packet's source address.
2984 * No actual multicast groups are involved here.
2986 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2988 if (bind(fd, (struct sockaddr *)&sin_array[1],
2989 sizeof(sin_array[1])) != 0) e(0);
2991 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
2993 if (bind(fd2, (struct sockaddr *)&sin_array[0],
2994 sizeof(sin_array[0])) != 0) e(0);
2996 len = sizeof(sinA);
2997 if (getsockname(fd2, (struct sockaddr *)&sinA, &len) != 0) e(0);
2999 if (sendto(fd, "D", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3000 e(0);
3002 len = sizeof(sinB);
3003 if (recvfrom(fd2, buf, sizeof(buf), 0, (struct sockaddr *)&sinB,
3004 &len) != hdrlen + 1) e(0);
3005 if (buf[hdrlen] != 'D') e(0);
3007 if (sinB.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
3009 if (close(fd2) != 0) e(0);
3010 if (close(fd) != 0) e(0);
3012 /* Sending from a bound socket, IPv6 version.. */
3013 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3015 if (bind(fd, (struct sockaddr *)&sin6_array[1],
3016 sizeof(sin6_array[1])) != 0) e(0);
3018 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3020 if (bind(fd2, (struct sockaddr *)&sin6_array[0],
3021 sizeof(sin6_array[0])) != 0) e(0);
3023 len = sizeof(sin6A);
3024 if (getsockname(fd2, (struct sockaddr *)&sin6A, &len) != 0) e(0);
3026 if (sendto(fd, "E", 1, 0, (struct sockaddr *)&sin6A,
3027 sizeof(sin6A)) != 1) e(0);
3029 len = sizeof(sin6B);
3030 if (recvfrom(fd2, buf, sizeof(buf), 0, (struct sockaddr *)&sin6B,
3031 &len) != 1) e(0);
3032 if (buf[0] != 'E') e(0);
3034 if (!IN6_IS_ADDR_LOOPBACK(&sin6B.sin6_addr)) e(0);
3036 if (close(fd2) != 0) e(0);
3037 if (close(fd) != 0) e(0);
3040 * A quick, partial test to see if connecting to a particular address
3041 * does not accidentally block packet receipt. What we do not test is
3042 * whether connecting does filter traffic from other sources.
3044 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
3046 memset(&sinA, 0, sizeof(sinA));
3047 sinA.sin_family = AF_INET;
3048 sinA.sin_addr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
3050 if (bind(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0) e(0);
3052 len = sizeof(sinA);
3053 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0) e(0);
3055 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
3056 imr.imr_multiaddr.s_addr = sinA.sin_addr.s_addr;
3057 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3058 sizeof(imr)) != 0) e(0);
3060 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
3062 memset(&sinB, 0, sizeof(sinB));
3063 sinB.sin_family = AF_INET;
3064 sinB.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3066 if (bind(fd2, (struct sockaddr *)&sinB, sizeof(sinB)) != 0) e(0);
3068 len = sizeof(sinB);
3069 if (getsockname(fd2, (struct sockaddr *)&sinB, &len) != 0) e(0);
3071 if (connect(fd, (struct sockaddr *)&sinB, sizeof(sinB)) != 0) e(0);
3073 /* Note that binding to a particular source address is not enough! */
3074 if (setsockopt(fd2, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface,
3075 sizeof(imr.imr_interface)) != 0) e(0);
3077 if (sendto(fd2, "F", 1, 0, (struct sockaddr *)&sinA,
3078 sizeof(sinA)) != 1) e(0);
3080 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3081 if (buf[hdrlen] != 'F') e(0);
3083 if (close(fd) != 0) e(0);
3084 if (close(fd2) != 0) e(0);
3086 /* Also try connecting with IPv6. */
3087 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3089 memset(&sin6A, 0, sizeof(sin6A));
3090 sin6A.sin6_family = AF_INET6;
3091 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
3092 &sin6A.sin6_addr) != 1) e(0);
3093 sin6A.sin6_scope_id = ifindex;
3095 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
3097 len = sizeof(sin6A);
3098 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0) e(0);
3100 ipv6mr.ipv6mr_interface = ifindex;
3101 memcpy(&ipv6mr.ipv6mr_multiaddr, &sin6A.sin6_addr,
3102 sizeof(ipv6mr.ipv6mr_multiaddr));
3103 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3104 sizeof(ipv6mr)) != 0) e(0);
3106 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3108 memset(&sin6B, 0, sizeof(sin6B));
3109 sin6B.sin6_family = AF_INET6;
3110 memcpy(&sin6B.sin6_addr, &in6addr_loopback, sizeof(sin6B.sin6_addr));
3112 if (bind(fd2, (struct sockaddr *)&sin6B, sizeof(sin6B)) != 0) e(0);
3114 len = sizeof(sin6B);
3115 if (getsockname(fd2, (struct sockaddr *)&sin6B, &len) != 0) e(0);
3117 if (connect(fd, (struct sockaddr *)&sin6B, sizeof(sin6B)) != 0) e(0);
3119 /* Unlike with IPv4, here the interface is implied by the zone. */
3120 if (sendto(fd2, "G", 1, 0, (struct sockaddr *)&sin6A,
3121 sizeof(sin6A)) != 1) e(0);
3123 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3124 if (buf[0] != 'G') e(0);
3126 if (close(fd) != 0) e(0);
3127 if (close(fd2) != 0) e(0);
3130 * Test multiple receivers. For UDP, we need to set the SO_REUSEADDR
3131 * option on all sockets for this to be guaranteed to work.
3133 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
3134 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
3136 memset(&sinA, 0, sizeof(sinA));
3137 sinA.sin_family = AF_INET;
3139 if (type == SOCK_DGRAM) {
3140 if (bind(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3141 e(0);
3143 len = sizeof(sinA);
3144 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0)
3145 e(0);
3147 val = 1;
3148 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3149 sizeof(val)) != 0) e(0);
3151 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3152 sizeof(val)) != 0) e(0);
3154 if (bind(fd2, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3155 e(0);
3158 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
3159 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
3161 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3162 sizeof(imr)) != 0) e(0);
3164 if (setsockopt(fd2, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3165 sizeof(imr)) != 0) e(0);
3167 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface,
3168 sizeof(imr.imr_interface)) != 0) e(0);
3170 sinA.sin_addr.s_addr = imr.imr_multiaddr.s_addr;
3172 if (sendto(fd, "H", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3173 e(0);
3175 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3176 if (buf[hdrlen] != 'H') e(0);
3178 if (recv(fd2, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3179 if (buf[hdrlen] != 'H') e(0);
3182 * Also test with a larger buffer, to ensure that packet duplication
3183 * actually works properly. As of writing, we need to patch lwIP to
3184 * make this work at all.
3186 len = 8000;
3187 if ((buf2 = malloc(hdrlen + len + 1)) == NULL) e(0);
3188 buf2[len - 1] = 'I';
3190 if (sendto(fd, buf2, len, 0, (struct sockaddr *)&sinA,
3191 sizeof(sinA)) != len) e(0);
3193 buf2[hdrlen + len - 1] = '\0';
3194 if (recv(fd, buf2, hdrlen + len + 1, 0) != hdrlen + len) e(0);
3195 if (buf2[hdrlen + len - 1] != 'I') e(0);
3197 buf2[hdrlen + len - 1] = '\0';
3198 if (recv(fd2, buf2, hdrlen + len + 1, 0) != hdrlen + len) e(0);
3199 if (buf2[hdrlen + len - 1] != 'I') e(0);
3201 free(buf2);
3203 if (close(fd2) != 0) e(0);
3204 if (close(fd) != 0) e(0);
3206 /* Multiple-receivers test, IPv6 version. */
3207 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3208 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3210 memset(&sin6A, 0, sizeof(sin6A));
3211 sin6A.sin6_family = AF_INET6;
3213 if (type == SOCK_DGRAM) {
3214 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3215 e(0);
3217 len = sizeof(sin6A);
3218 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
3219 e(0);
3221 val = 1;
3222 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3223 sizeof(val)) != 0) e(0);
3225 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3226 sizeof(val)) != 0) e(0);
3228 if (bind(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3229 e(0);
3232 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
3233 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
3234 ipv6mr.ipv6mr_interface = ifindex;
3236 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3237 sizeof(ipv6mr)) != 0) e(0);
3239 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3240 sizeof(ipv6mr)) != 0) e(0);
3242 val = (int)ifindex;
3243 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3244 sizeof(val)) != 0) e(0);
3246 memcpy(&sin6A.sin6_addr, &ipv6mr.ipv6mr_multiaddr,
3247 sizeof(sin6A.sin6_addr));
3249 if (sendto(fd, "J", 1, 0, (struct sockaddr *)&sin6A,
3250 sizeof(sin6A)) != 1) e(0);
3252 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3253 if (buf[0] != 'J') e(0);
3255 if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
3256 if (buf[0] != 'J') e(0);
3258 len = 8000;
3259 if ((buf2 = malloc(len + 1)) == NULL) e(0);
3260 buf2[len - 1] = 'K';
3262 if (sendto(fd, buf2, len, 0, (struct sockaddr *)&sin6A,
3263 sizeof(sin6A)) != len) e(0);
3265 buf2[len - 1] = '\0';
3266 if (recv(fd, buf2, len + 1, 0) != len) e(0);
3267 if (buf2[len - 1] != 'K') e(0);
3269 buf2[len - 1] = '\0';
3270 if (recv(fd2, buf2, len + 1, 0) != len) e(0);
3271 if (buf2[len - 1] != 'K') e(0);
3273 free(buf2);
3275 if (close(fd2) != 0) e(0);
3276 if (close(fd) != 0) e(0);
3279 * Test proper multicast group departure. This test relies on the fact
3280 * that actual group membership is not checked on arrival of a
3281 * multicast-destined packet, so that membership of one socket can be
3282 * tested by another socket sending packets to itself while having
3283 * joined a different group. We test both explicit group departure
3284 * and implicit departure on close.
3286 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
3287 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
3289 memset(&sinA, 0, sizeof(sinA));
3290 sinA.sin_family = AF_INET;
3292 if (type == SOCK_DGRAM) {
3293 if (bind(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3294 e(0);
3296 len = sizeof(sinA);
3297 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0)
3298 e(0);
3300 val = 1;
3301 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3302 sizeof(val)) != 0) e(0);
3304 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3305 sizeof(val)) != 0) e(0);
3307 if (bind(fd2, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3308 e(0);
3311 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
3312 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
3314 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3315 sizeof(imr)) != 0) e(0);
3317 imr.imr_multiaddr.s_addr = htonl(ntohl(imr.imr_multiaddr.s_addr) + 1);
3319 if (setsockopt(fd2, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3320 sizeof(imr)) != 0) e(0);
3322 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface,
3323 sizeof(imr.imr_interface)) != 0) e(0);
3325 sinA.sin_addr.s_addr = imr.imr_multiaddr.s_addr;
3327 if (sendto(fd, "L", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3328 e(0);
3330 if (recv(fd2, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3331 if (buf[hdrlen] != 'L') e(0);
3333 if (setsockopt(fd2, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
3334 sizeof(imr)) != 0) e(0);
3336 if (sendto(fd, "M", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3337 e(0);
3339 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3340 if (buf[hdrlen] != 'L') e(0);
3342 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3343 if (errno != EWOULDBLOCK) e(0);
3345 if (setsockopt(fd2, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3346 sizeof(imr)) != 0) e(0);
3348 if (sendto(fd, "N", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3349 e(0);
3351 if (recv(fd2, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3352 if (buf[hdrlen] != 'N') e(0);
3354 if (close(fd2) != 0) e(0);
3356 if (sendto(fd, "O", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3357 e(0);
3359 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3360 if (buf[hdrlen] != 'N') e(0);
3362 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3363 if (errno != EWOULDBLOCK) e(0);
3365 if (close(fd) != 0) e(0);
3367 /* Multicast group departure, now IPv6.. this is getting boring. */
3368 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3369 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3371 memset(&sin6A, 0, sizeof(sin6A));
3372 sin6A.sin6_family = AF_INET6;
3374 if (type == SOCK_DGRAM) {
3375 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3376 e(0);
3378 len = sizeof(sin6A);
3379 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
3380 e(0);
3382 val = 1;
3383 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3384 sizeof(val)) != 0) e(0);
3386 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3387 sizeof(val)) != 0) e(0);
3389 if (bind(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3390 e(0);
3393 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
3394 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
3395 ipv6mr.ipv6mr_interface = ifindex;
3397 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3398 sizeof(ipv6mr)) != 0) e(0);
3400 ipv6mr.ipv6mr_multiaddr.s6_addr[15]++;
3402 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3403 sizeof(ipv6mr)) != 0) e(0);
3405 val = (int)ifindex;
3406 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3407 sizeof(val)) != 0) e(0);
3409 memcpy(&sin6A.sin6_addr, &ipv6mr.ipv6mr_multiaddr,
3410 sizeof(sin6A.sin6_addr));
3412 if (sendto(fd, "P", 1, 0, (struct sockaddr *)&sin6A,
3413 sizeof(sin6A)) != 1) e(0);
3415 if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
3416 if (buf[0] != 'P') e(0);
3418 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
3419 sizeof(ipv6mr)) != 0) e(0);
3421 if (sendto(fd, "Q", 1, 0, (struct sockaddr *)&sin6A,
3422 sizeof(sin6A)) != 1) e(0);
3424 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3425 if (buf[0] != 'P') e(0);
3427 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3428 if (errno != EWOULDBLOCK) e(0);
3430 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3431 sizeof(ipv6mr)) != 0) e(0);
3433 if (sendto(fd, "R", 1, 0, (struct sockaddr *)&sin6A,
3434 sizeof(sin6A)) != 1) e(0);
3436 if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
3437 if (buf[0] != 'R') e(0);
3439 if (close(fd2) != 0) e(0);
3441 if (sendto(fd, "S", 1, 0, (struct sockaddr *)&sin6A,
3442 sizeof(sin6A)) != 1) e(0);
3444 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3445 if (buf[0] != 'R') e(0);
3447 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3448 if (errno != EWOULDBLOCK) e(0);
3450 if (close(fd) != 0) e(0);
3453 * Lastly, some IPv6-only tests.
3456 * Test that IPV6_PKTINFO overrides IPV6_MULTICAST_IF. For this we
3457 * need two valid interface indices. If we cannot find a second one,
3458 * simply test that the IPV6_PKTINFO information is used at all.
3460 for (ifindex2 = 1; ifindex2 < BAD_IFINDEX; ifindex2++) {
3461 if (if_indextoname(ifindex2, name) == NULL) {
3462 if (errno != ENXIO) e(0);
3463 continue;
3466 if (strcmp(name, LOOPBACK_IFNAME))
3467 break;
3470 if (ifindex2 == BAD_IFINDEX)
3471 ifindex2 = 0; /* too bad; fallback mode */
3473 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3475 memset(&sin6A, 0, sizeof(sin6A));
3476 sin6A.sin6_family = AF_INET6;
3478 if (type == SOCK_DGRAM) {
3479 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3480 e(0);
3482 len = sizeof(sin6A);
3483 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
3484 e(0);
3487 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
3488 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
3489 ipv6mr.ipv6mr_interface = ifindex;
3491 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3492 sizeof(ipv6mr)) != 0) e(0);
3494 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3496 memcpy(&sin6A.sin6_addr, &ipv6mr.ipv6mr_multiaddr,
3497 sizeof(sin6A.sin6_addr));
3499 val = (int)ifindex2;
3500 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3501 sizeof(val)) != 0) e(0);
3503 memset(&iov, 0, sizeof(iov));
3504 iov.iov_base = "T";
3505 iov.iov_len = 1;
3507 memset(&ipi6, 0, sizeof(ipi6));
3508 memcpy(&ipi6.ipi6_addr, &in6addr_loopback, sizeof(ipi6.ipi6_addr));
3509 ipi6.ipi6_ifindex = ifindex;
3511 control.cmsg.cmsg_len = CMSG_LEN(sizeof(ipi6));
3512 control.cmsg.cmsg_level = IPPROTO_IPV6;
3513 control.cmsg.cmsg_type = IPV6_PKTINFO;
3514 memcpy(CMSG_DATA(&control.cmsg), &ipi6, sizeof(ipi6));
3516 memset(&msg, 0, sizeof(msg));
3517 msg.msg_name = &sin6A;
3518 msg.msg_namelen = sizeof(sin6A);
3519 msg.msg_iov = &iov;
3520 msg.msg_iovlen = 1;
3521 msg.msg_control = control.buf;
3522 msg.msg_controllen = control.cmsg.cmsg_len;
3524 if (sendmsg(fd2, &msg, 0) != 1) e(0);
3526 len = sizeof(sin6B);
3527 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6B,
3528 &len) != 1) e(0);
3529 if (buf[0] != 'T') e(0);
3531 if (len != sizeof(sin6B)) e(0);
3532 if (sin6B.sin6_len != sizeof(sin6B)) e(0);
3533 if (sin6B.sin6_family != AF_INET6) e(0);
3534 if (memcmp(&sin6B.sin6_addr, &in6addr_loopback,
3535 sizeof(sin6B.sin6_addr)) != 0) e(0);
3537 if (close(fd2) != 0) e(0);
3539 /* Repeat the same test, but now with a sticky IPV6_PKTINFO setting. */
3540 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3542 memset(&ipi6, 0, sizeof(ipi6));
3543 memcpy(&ipi6.ipi6_addr, &in6addr_loopback, sizeof(ipi6.ipi6_addr));
3544 ipi6.ipi6_ifindex = ifindex;
3546 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_PKTINFO, &ipi6,
3547 sizeof(ipi6)) != 0) e(0);
3549 val = (int)ifindex2;
3550 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3551 sizeof(val)) != 0) e(0);
3553 if (sendto(fd2, "U", 1, 0, (struct sockaddr *)&sin6A,
3554 sizeof(sin6A)) != 1) e(0);
3556 len = sizeof(sin6B);
3557 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6B,
3558 &len) != 1) e(0);
3559 if (buf[0] != 'U') e(0);
3561 if (len != sizeof(sin6B)) e(0);
3562 if (sin6B.sin6_len != sizeof(sin6B)) e(0);
3563 if (sin6B.sin6_family != AF_INET6) e(0);
3564 if (memcmp(&sin6B.sin6_addr, &in6addr_loopback,
3565 sizeof(sin6B.sin6_addr)) != 0) e(0);
3567 if (close(fd2) != 0) e(0);
3568 if (close(fd) != 0) e(0);
3571 * Test that invalid multicast addresses are not accepted anywhere.
3573 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3575 memset(&sin6A, 0, sizeof(sin6A));
3576 sin6A.sin6_family = AF_INET6;
3577 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_BAD,
3578 &sin6A.sin6_addr) != 1) e(0);
3580 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != -1) e(0);
3581 if (errno != EINVAL) e(0);
3583 sin6A.sin6_port = htons(TEST_PORT_A);
3584 if (connect(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != -1) e(0);
3585 if (errno != EINVAL) e(0);
3587 if (sendto(fd, "X", 1, 0, (struct sockaddr *)&sin6A,
3588 sizeof(sin6A)) != -1) e(0);
3589 if (errno != EINVAL) e(0);
3591 memcpy(&ipv6mr.ipv6mr_multiaddr, &sin6A.sin6_addr,
3592 sizeof(ipv6mr.ipv6mr_multiaddr));
3593 ipv6mr.ipv6mr_interface = ifindex;
3595 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3596 sizeof(ipv6mr)) != -1) e(0);
3597 if (errno != EINVAL) e(0);
3599 if (close(fd) != 0) e(0);