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.
10 #include <sys/param.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #include <sys/sysctl.h>
16 #include <netinet/in.h>
17 #include <netinet/ip.h>
18 #include <netinet6/in6_var.h>
19 #include <arpa/inet.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
] = {
100 static const char *callname
[C_MAX
] = {
128 static int socklib_sigpipe
;
131 * Signal handler for SIGPIPE signals.
134 socklib_signal(int sig
)
137 if (sig
!= SIGPIPE
) e(0);
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
)
165 r
= accept(fd
, remote_addr
, &addr_len
);
173 r
= bind(fd
, local_addr
, addr_len
);
178 r
= connect(fd
, remote_addr
, addr_len
);
183 r
= getpeername(fd
, remote_addr
, &addr_len
);
188 r
= getsockname(fd
, remote_addr
, &addr_len
);
192 case C_GETSOCKOPT_ERR
:
195 r
= getsockopt(fd
, SOL_SOCKET
, SO_ERROR
, &i
, &len
);
198 * We assume this call always succeeds, and test against the
209 case C_GETSOCKOPT_KA
:
212 r
= getsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &i
, &len
);
216 case C_GETSOCKOPT_RB
:
219 r
= getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &i
, &len
);
224 r
= ioctl(fd
, FIONREAD
, &i
);
226 /* On success, we test against the returned value here. */
238 r
= recv(fd
, data
, sizeof(data
), 0);
243 r
= recvfrom(fd
, data
, sizeof(data
), 0, remote_addr
,
251 r
= send(fd
, data
, sizeof(data
), 0);
258 r
= sendto(fd
, data
, sizeof(data
), 0, remote_addr
, addr_len
);
262 case C_SETSOCKOPT_BC
:
265 r
= setsockopt(fd
, SOL_SOCKET
, SO_BROADCAST
, &i
, sizeof(i
));
269 case C_SETSOCKOPT_KA
:
272 r
= setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &i
, sizeof(i
));
280 r
= setsockopt(fd
, SOL_SOCKET
, SO_LINGER
, &l
, sizeof(l
));
284 case C_SETSOCKOPT_RA
:
287 r
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &i
, sizeof(i
));
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
);
307 r
= shutdown(fd
, SHUT_RD
);
312 r
= shutdown(fd
, SHUT_WR
);
317 r
= shutdown(fd
, SHUT_RDWR
);
332 if (fd2
>= 0 && close(fd2
) != 0) e(0);
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.
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
;
369 #if SOCKLIB_SWEEP_GENERATE
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);
384 for (state
= 0; state
< nstates
; state
++) {
385 for (call
= 0; call
< C_MAX
; call
++) {
388 res
= proc(domain
, type
, protocol
, states
[state
],
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
;
405 exp
= results
[call
* nstates
+ state
];
408 printf("FAIL state %d call %d res %d exp %d\n",
409 state
, call
, res
, exp
);
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
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
++) {
438 res
= nresults
[call
* nstates
+ state
];
439 name
= (res
< 0) ? get_error_name(-res
) : NULL
;
441 printf("-%s,", name
);
442 if ((state
+ 1) % 4 != 0 &&
445 (strlen(name
) <= 13) ? "\t" : "",
446 (strlen(name
) <= 5) ? "\t" : "");
449 if ((state
+ 1) % 4 != 0 &&
457 #elif SOCKLIB_SWEEP_GENERATE == 2
458 /* Generate table in CSV form. */
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
;
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.
486 socklib_multicast_tx_options(int type
)
488 struct in_addr in_addr
;
490 unsigned int ifindex
;
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>.
504 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, &byte
, &len
) != 0)
506 if (len
!= sizeof(byte
)) e(0);
507 if (type
!= SOCK_STREAM
&& byte
!= 1) e(0);
511 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_LOOP
, &byte
, &len
) != 0)
513 if (len
!= sizeof(byte
)) e(0);
516 len
= sizeof(in_addr
);
517 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_IF
, &in_addr
, &len
) != 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. */
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);
535 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
,
537 if (errno
!= ENOPROTOOPT
) e(0);
538 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
,
540 if (errno
!= ENOPROTOOPT
) e(0);
541 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
, &len
) != -1)
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.
555 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
, &len
) != 0)
557 if (len
!= sizeof(val
)) e(0);
558 if (type
!= SOCK_STREAM
&& val
!= 1) e(0);
562 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
, &len
) != 0)
564 if (len
!= sizeof(val
)) e(0);
568 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
, &len
) != 0)
570 if (len
!= sizeof(val
)) e(0);
573 /* It must not be possible to get/set IPv4 options on IPv6 sockets. */
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);
586 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, &val
, &len
) != -1)
588 if (errno
!= ENOPROTOOPT
) e(0);
589 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_LOOP
, &val
, &len
) != -1)
591 if (errno
!= ENOPROTOOPT
) e(0);
592 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_IF
, &val
, &len
) != -1)
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);
602 if (setsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, &byte
,
603 sizeof(byte
)) != 0) e(0);
607 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, &byte
, &len
) != 0)
609 if (len
!= sizeof(byte
)) e(0);
610 if (byte
!= 129) e(0);
613 if (setsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_LOOP
, &byte
,
619 if (getsockopt(fd
, IPPROTO_IP
, IP_MULTICAST_LOOP
, &byte
, &len
) != 0)
621 if (len
!= sizeof(byte
)) 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)
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)
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);
641 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
,
642 sizeof(val
)) != 0) e(0);
646 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
, &len
) != 0)
648 if (len
!= sizeof(val
)) e(0);
649 if (val
!= 137) e(0);
652 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
,
653 sizeof(val
)) != -1) e(0);
654 if (errno
!= EINVAL
) e(0);
657 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
,
658 sizeof(val
)) != -1) e(0);
659 if (errno
!= EINVAL
) e(0);
663 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
, &len
) != 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);
674 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
, &len
) != 0)
676 if (len
!= sizeof(val
)) e(0);
680 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
,
681 sizeof(val
)) != 0) e(0);
685 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
, &len
) != 0)
687 if (len
!= sizeof(val
)) e(0);
691 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
,
692 sizeof(val
)) != 0) e(0);
695 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
,
696 sizeof(val
)) != -1) e(0);
697 if (errno
!= EINVAL
) e(0);
700 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
,
701 sizeof(val
)) != -1) e(0);
702 if (errno
!= EINVAL
) e(0);
706 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &val
, &len
) != 0)
708 if (len
!= sizeof(val
)) e(0);
712 ifindex
= if_nametoindex(LOOPBACK_IFNAME
);
715 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
,
716 sizeof(val
)) != 0) e(0);
720 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
, &len
) != 0)
722 if (len
!= sizeof(val
)) e(0);
723 if (val
!= ifindex
) e(0);
726 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
,
727 sizeof(val
)) != -1) e(0);
730 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
,
731 sizeof(val
)) != -1) e(0);
735 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
, &len
) != 0)
737 if (len
!= sizeof(val
)) e(0);
738 if (val
!= ifindex
) e(0);
741 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
,
742 sizeof(val
)) != 0) e(0);
746 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &val
, &len
) != 0)
748 if (len
!= sizeof(val
)) e(0);
751 if (close(fd
) != 0) e(0);
755 * Test for large sends and receives on stream sockets with MSG_WAITALL.
758 socklib_large_transfers(int fd
[2])
764 #define LARGE_BUF (4096*1024)
766 if ((buf
= malloc(LARGE_BUF
)) == NULL
) e(0);
767 memset(buf
, 0, LARGE_BUF
);
774 if (close(fd
[0]) != 0) e(0);
777 if (recv(fd
[1], buf
, LARGE_BUF
, MSG_WAITALL
) != LARGE_BUF
)
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);
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);
793 memset(buf
, 'y', LARGE_BUF
);
795 if (recv(fd
[1], buf
, LARGE_BUF
, MSG_WAITALL
) != LARGE_BUF
- 1)
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);
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);
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.
851 socklib_producer_consumer(int fd
[2])
855 socklen_t len
, size
, off
;
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);
866 if ((buf
= malloc(size
)) == NULL
) e(0);
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)
890 if (close(fd
[0]) != 0) e(0);
894 for (off
= 0; off
< TRANSFER_SIZE
; ) {
895 if (off
< TRANSFER_SIZE
/ 2)
897 ((off
/ (TRANSFER_SIZE
/ 8) % 2) ? 64 :
900 len
= lrand48() % size
;
902 num
= lrand48() % 16;
904 if (num
& 1) flags
|= MSG_PEEK
;
905 if (num
& 2) flags
|= MSG_WAITALL
;
906 if (num
& 4) flags
|= MSG_DONTWAIT
;
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);
919 if ((r
= recv(fd
[1], buf
, len
, flags
)) == -1) {
920 if (errno
!= EWOULDBLOCK
) 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
)) {
940 if ((flags
& (MSG_DONTWAIT
| MSG_WAITALL
)) ==
941 MSG_WAITALL
&& r
!= len
&&
942 off
< TRANSFER_SIZE
) e(0);
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]);
955 if (close(fd
[1]) != 0) e(0);
961 if (close(fd
[1]) != 0) e(0);
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;
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;
982 r
= send(fd
[0], buf
, len
, flags
);
985 if (r
> (ssize_t
)len
) e(0);
986 if (!(flags
& MSG_DONTWAIT
)) e(0);
988 if (errno
!= EWOULDBLOCK
) e(0);
996 if (off
/ (TRANSFER_SIZE
/ 4) !=
997 (off
+ r
) / (TRANSFER_SIZE
/ 4))
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]);
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.
1025 socklib_got_signal(int sig __unused
)
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 */
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
;
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.
1064 if (send(fd
[1], data
, idata
, 0) != idata
) e(0);
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.
1085 FD_SET(fd
[0], &fds
);
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. */
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
||
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.
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);
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);
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.
1170 if (pipe2(pfd
, O_NONBLOCK
) != 0) e(0);
1177 if (close(fd
[1]) != 0) e(0);
1178 if (close(pfd
[0]) != 0) e(0);
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
);
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);
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);
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)
1225 if (read(pfd
[0], &res
, sizeof(res
)) != sizeof(res
))
1227 if (read(pfd
[0], &err
, sizeof(err
)) != sizeof(err
))
1230 if (res
!= MIN(idata
+ edata
, len
)) e(0);
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);
1245 * Now test various ways to terminate the receive call.
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;
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);
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
) {
1272 } else if (idata
+ edata
> 0) {
1273 if (res
!= MIN(idata
+ edata
, len
)) e(0);
1274 } else if (tstate
== 3) {
1276 if (res
!= -1) e(0);
1277 if (err
!= ECONNRESET
) e(0);
1279 if (res
!= len
) e(0);
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.
1289 if (res
!= MIN(idata
, len
)) e(0);
1291 if (res
!= -1) e(0);
1292 if (err
!= EINTR
) e(0);
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.
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
;
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
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);
1353 mib
[miblen
++] = sizeof(*array
);
1356 if (sysctl(mib
, miblen
, NULL
, &oldlen
, NULL
, 0) != 0) e(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);
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
);
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
);
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);
1408 memcpy(ki
, &array
[found
], sizeof(*ki
));
1412 return (found
!= -1);
1416 const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
1417 const struct in6_addr in6addr_loopback
= IN6ADDR_LOOPBACK_INIT
;
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.
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
,
1446 const struct sockaddr_in6
*sin6p
;
1448 const struct sockaddr_in6
*addr
;
1451 const struct sockaddr_in6
*name
;
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
},
1471 const struct sockaddr_in6
*addr
;
1474 const struct sockaddr_in6
*name
;
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
},
1492 struct ifaddrs
*ifa
, *ifp
, *ifp2
;
1493 struct in6_ifreq ifr
;
1494 char name
[IF_NAMESIZE
], buf
[1];
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)
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)
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.
1571 for (i
= 1; i
< BAD_IFINDEX
; i
++) {
1572 if (if_indextoname(i
, name
) == NULL
) {
1573 if (errno
!= ENXIO
) e(0);
1577 if (!strcmp(name
, LOOPBACK_IFNAME
))
1581 memcpy(&sin6_ll_mix
, &sin6_ll_all
, sizeof(sin6_ll_mix
));
1582 sin6_ll_mix
.sin6_scope_id
= i
;
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);
1604 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
,
1605 sizeof(val
)) != 0) e(0);
1607 r
= bind(fd
, (struct sockaddr
*)bp
->addr
,
1610 /* Did the bind(2) call produce the expected result? */
1612 if (bp
->res
!= 0) e(0);
1614 if (r
!= -1 || bp
->res
!= errno
) e(0);
1616 /* The rest is for successful bind(2) calls. */
1618 if (close(fd
) != 0) e(0);
1623 /* Get the bound address. */
1625 if (getsockname(fd
, (struct sockaddr
*)&sin6
,
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);
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
))
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
)) ?
1656 if ((fd
= socket(AF_INET6
, type
| sfl
, protocol
)) < 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);
1668 if (getsockname(fd
, (struct sockaddr
*)&sin6
,
1671 port
= sin6
.sin6_port
;
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
)
1681 if (cp
->flags
& F_MIX
)
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
))
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);
1703 if (setsockopt(fd2
, IPPROTO_IPV6
, IPV6_V6ONLY
,
1704 &val
, sizeof(val
)) != 0) e(0);
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)
1721 r
= connect(fd
, (struct sockaddr
*)&sin6
,
1727 if (r
!= -1 || exp
!= errno
) e(0);
1730 if (close(fd
) != 0) e(0);
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
1743 if (getsockname(fd
, (struct sockaddr
*)&sin6
,
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);
1751 if (sin6
.sin6_port
!= 0) e(0);
1752 port
= sin6
.sin6_port
;
1754 if (!(bp
->flags
& F_ANY
))
1756 else if (!(cp
->flags
& F_REM
))
1759 sin6p
= NULL
; /* can't test: may vary */
1761 if (sin6p
!= NULL
) {
1764 if (memcmp(&sin6
, sin6p
, sizeof(sin6
)) != 0)
1769 * Test getpeername(2). It should always be the
1770 * "normalized" version of the target address.
1773 if (getpeername(fd
, (struct sockaddr
*)&sin6
,
1775 if (len
!= sizeof(sin6
)) e(0);
1777 if (type
!= SOCK_RAW
) {
1778 if (sin6
.sin6_port
!= htons(TEST_PORT_A
)) e(0);
1780 if (sin6
.sin6_port
!= 0) e(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.
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);
1806 if (close(fd
) != 0) e(0);
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). */
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);
1827 if (memcmp(&sin6
, sin6p
, sizeof(sin6
)) != 0)
1830 /* Test getpeername(2). */
1831 if (getpeername(fd3
, (struct sockaddr
*)&sin6
,
1833 if (len
!= sizeof(sin6
)) e(0);
1835 if (sin6
.sin6_port
!= port
) e(0);
1838 if (memcmp(&sin6
, sin6p
, sizeof(sin6
)) != 0)
1841 /* Test getsockname(2). */
1842 if (getsockname(fd3
, (struct sockaddr
*)&sin6
,
1844 if (len
!= sizeof(sin6
)) e(0);
1846 if (sin6
.sin6_port
!= htons(TEST_PORT_A
)) e(0);
1849 if (memcmp(&sin6
, cp
->name
, sizeof(sin6
)) != 0)
1852 if (close(fd3
) != 0) e(0);
1854 /* Test recvfrom(2). */
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);
1865 if (memcmp(&sin6
, sin6p
, sizeof(sin6
)) != 0)
1868 if (close(fd2
) != 0) e(0);
1871 if (close(fd
) != 0) e(0);
1874 if (type
== SOCK_STREAM
)
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
))
1889 if ((fd
= socket(AF_INET6
, type
, protocol
)) < 0) e(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);
1900 if (getsockname(fd
, (struct sockaddr
*)&sin6
,
1903 port
= sin6
.sin6_port
;
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
))
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
))
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);
1934 if (setsockopt(fd2
, IPPROTO_IPV6
, IPV6_V6ONLY
,
1935 &val
, sizeof(val
)) != 0) e(0);
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);
1950 r
= sendto(fd
, "B", 1, 0, (struct sockaddr
*)&sin6
,
1954 if (r
!= -1 || exp
!= errno
) e(0);
1956 if (close(fd
) != 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.
1969 if (getsockname(fd
, (struct sockaddr
*)&sin6
,
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);
1977 if (sin6
.sin6_port
!= 0) e(0);
1978 port
= sin6
.sin6_port
;
1981 if (memcmp(&sin6
, bp
->name
, sizeof(sin6
)) != 0) e(0);
1984 /* Test recvfrom(2) on the receiving socket. */
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);
1995 if (bp
->flags
& F_ANY
)
2000 if (memcmp(&sin6
, sin6p
, sizeof(sin6
)) != 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);
2018 for (ifp
= ifa
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
2019 if (strcmp(ifp
->ifa_name
, LOOPBACK_IFNAME
) == 0)
2022 if (!(ifp
->ifa_flags
& IFF_UP
) || ifp
->ifa_addr
== NULL
||
2023 ifp
->ifa_addr
->sa_family
!= AF_INET6
)
2026 memcpy(&sin6
, ifp
->ifa_addr
, sizeof(sin6
));
2028 if (!IN6_IS_ADDR_LINKLOCAL(&sin6
.sin6_addr
))
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
));
2054 if (link_state
== LINK_STATE_DOWN
)
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
))
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
)
2090 * If no second interface with a link-local address was found, we
2091 * cannot perform the rest of this subtest.
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);
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
);
2121 sin6
.sin6_scope_id
= ifindex
;
2123 if (connect(fd2
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1)
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)
2138 if (close(fd2
) != 0) e(0);
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)
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)
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);
2193 if (recvfrom(fd
, buf
, sizeof(buf
), 0, (struct sockaddr
*)&sin6
,
2195 if (buf
[0] != 'D') e(0);
2197 if (recvfrom(fd
, buf
, sizeof(buf
), 0, (struct sockaddr
*)&sin6
,
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
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];
2215 struct ipv6_mreq ipv6mr
;
2216 struct in6_pktinfo ipi6
;
2219 struct cmsghdr
*cmsg
;
2220 socklen_t len
, hdrlen
;
2221 unsigned int count
, ifindex
, ifindex2
;
2223 struct cmsghdr cmsg
;
2226 char buf
[sizeof(struct ip
) + 1], *buf2
, name
[IF_NAMESIZE
];
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
,
2315 if (r
!= -1 || errno
!= ENOBUFS
) e(0);
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. */
2471 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 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
,
2495 if (r
!= -1 || errno
!= ENOBUFS
) e(0);
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);
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. */
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. */
2591 if (getsockname(fd2
, (struct sockaddr
*)&sinA
, &len
) != 0) e(0);
2594 if (getsockopt(fd2
, IPPROTO_IP
, IP_TTL
, &ttl
, &len
) != 0) e(0);
2597 if (setsockopt(fd
, IPPROTO_IP
, IP_RECVTTL
, &val
, sizeof(val
)) != 0)
2600 hdrlen
= (type
== SOCK_RAW
) ? sizeof(struct ip
) : 0;
2602 memset(&iov
, 0, sizeof(iov
));
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
);
2612 msg
.msg_control
= control
.buf
;
2613 msg
.msg_controllen
= sizeof(control
);
2615 r
= recvmsg(fd
, &msg
, 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
)))
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
));
2644 if (msg
.msg_flags
& MSG_MCAST
) e(0);
2645 if (byte
!= ttl
) e(0);
2648 if (!(msg
.msg_flags
& MSG_MCAST
)) e(0);
2649 if (byte
!= 1) e(0);
2652 if (!(msg
.msg_flags
& MSG_MCAST
)) e(0);
2653 if (byte
!= 123) e(0);
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)
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. */
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. */
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. */
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. */
2778 if (getsockopt(fd2
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
,
2783 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVHOPLIMIT
, &val
,
2784 sizeof(val
)) != 0) e(0);
2786 memset(&iov
, 0, sizeof(iov
));
2790 for (i
= 0; i
< 6; ) {
2791 memset(&msg
, 0, sizeof(msg
));
2792 msg
.msg_name
= &sin6B
;
2793 msg
.msg_namelen
= sizeof(sin6B
);
2796 msg
.msg_control
= control
.buf
;
2797 msg
.msg_controllen
= sizeof(control
);
2799 r
= recvmsg(fd
, &msg
, 0);
2802 if (msg
.msg_namelen
!= sizeof(sin6B
)) e(0);
2804 if (memcmp(&sin6A
, &sin6B
, sizeof(sin6A
)))
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
));
2820 if (msg
.msg_flags
& MSG_MCAST
) e(0);
2821 if (val
!= (int)ttl
) e(0);
2827 if (!(msg
.msg_flags
& MSG_MCAST
)) e(0);
2831 if (!(msg
.msg_flags
& MSG_MCAST
)) e(0);
2832 if (val
!= 125) e(0);
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);
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
));
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
,
2955 if ((fd2
= socket(AF_INET6
, type
, protocol
)) < 0) e(0);
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
));
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);
2997 if (getsockname(fd2
, (struct sockaddr
*)&sinA
, &len
) != 0) e(0);
2999 if (sendto(fd
, "D", 1, 0, (struct sockaddr
*)&sinA
, sizeof(sinA
)) != 1)
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
,
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);
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);
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)
3144 if (getsockname(fd
, (struct sockaddr
*)&sinA
, &len
) != 0)
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)
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)
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.
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);
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)
3217 len
= sizeof(sin6A
);
3218 if (getsockname(fd
, (struct sockaddr
*)&sin6A
, &len
) != 0)
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)
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);
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);
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);
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)
3297 if (getsockname(fd
, (struct sockaddr
*)&sinA
, &len
) != 0)
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)
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)
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)
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)
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)
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)
3378 len
= sizeof(sin6A
);
3379 if (getsockname(fd
, (struct sockaddr
*)&sin6A
, &len
) != 0)
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)
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);
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);
3466 if (strcmp(name
, LOOPBACK_IFNAME
))
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)
3482 len
= sizeof(sin6A
);
3483 if (getsockname(fd
, (struct sockaddr
*)&sin6A
, &len
) != 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
));
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
);
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
,
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
,
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);