1 /*
2 * Socket test code library. This file contains code that is worth sharing
3 * between TCP/IP and UDS tests, as well as code that is worth sharing between
4 * various TCP/IP tests.
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <signal.h>
10 #include <sys/param.h>
11 #include <sys/wait.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #include <sys/sysctl.h>
15 #include <net/if.h>
16 #include <netinet/in.h>
17 #include <netinet/ip.h>
18 #include <netinet6/in6_var.h>
19 #include <arpa/inet.h>
20 #include <ifaddrs.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23
24 #include "common.h"
25 #include "socklib.h"
26
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 */
29
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 */
33
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"
38
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"
44
45 #define BAD_IFINDEX 255 /* guaranteed not to belong to an interface */
46
47 /* 0 = check, 1 = generate source, 2 = generate CSV */
48 #define SOCKLIB_SWEEP_GENERATE 0
49
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);
53
54 #if SOCKLIB_SWEEP_GENERATE == 2
55 static const char *statename[S_MAX] = {
56 "S_NEW",
57 "S_N_SHUT_R",
58 "S_N_SHUT_W",
59 "S_N_SHUT_RW",
60 "S_BOUND",
61 "S_LISTENING",
62 "S_L_SHUT_R",
63 "S_L_SHUT_W",
64 "S_L_SHUT_RW",
65 "S_CONNECTING",
66 "S_C_SHUT_R",
67 "S_C_SHUT_W",
68 "S_C_SHUT_RW",
69 "S_CONNECTED",
70 "S_ACCEPTED",
71 "S_SHUT_R",
72 "S_SHUT_W",
73 "S_SHUT_RW",
74 "S_RSHUT_R",
75 "S_RSHUT_W",
76 "S_RSHUT_RW",
77 "S_SHUT2_R",
78 "S_SHUT2_W",
79 "S_SHUT2_RW",
80 "S_PRE_EOF",
81 "S_AT_EOF",
82 "S_POST_EOF",
83 "S_PRE_SHUT_R",
84 "S_EOF_SHUT_R",
85 "S_POST_SHUT_R",
86 "S_PRE_SHUT_W",
87 "S_EOF_SHUT_W",
88 "S_POST_SHUT_W",
89 "S_PRE_SHUT_RW",
90 "S_EOF_SHUT_RW",
91 "S_POST_SHUT_RW",
92 "S_PRE_RESET",
93 "S_AT_RESET",
94 "S_POST_RESET",
95 "S_FAILED",
96 "S_POST_FAILED",
97 };
98 #endif
99
100 static const char *callname[C_MAX] = {
101 "C_ACCEPT",
102 "C_BIND",
103 "C_CONNECT",
104 "C_GETPEERNAME",
105 "C_GETSOCKNAME",
106 "C_GETSOCKOPT_ERR",
107 "C_GETSOCKOPT_KA",
108 "C_GETSOCKOPT_RB",
109 "C_IOCTL_NREAD",
110 "C_LISTEN",
111 "C_RECV",
112 "C_RECVFROM",
113 "C_SEND",
114 "C_SENDTO",
115 "C_SELECT_R",
116 "C_SELECT_W",
117 "C_SELECT_X",
118 "C_SETSOCKOPT_BC",
119 "C_SETSOCKOPT_KA",
120 "C_SETSOCKOPT_L",
121 "C_SETSOCKOPT_RA",
122 "C_SHUTDOWN_R",
123 "C_SHUTDOWN_RW",
124 "C_SHUTDOWN_W",
125 };
126 #endif
127
128 static int socklib_sigpipe;
129
130 /*
131 * Signal handler for SIGPIPE signals.
132 */
133 static void
socklib_signal(int sig)134 socklib_signal(int sig)
135 {
136
137 if (sig != SIGPIPE) e(0);
138
139 socklib_sigpipe++;
140 }
141
142 /*
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.
149 */
150 int
socklib_sweep_call(enum call call,int fd,struct sockaddr * local_addr,struct sockaddr * remote_addr,socklen_t addr_len)151 socklib_sweep_call(enum call call, int fd, struct sockaddr * local_addr,
152 struct sockaddr * remote_addr, socklen_t addr_len)
153 {
154 char data[1];
155 struct linger l;
156 fd_set fd_set;
157 struct timeval tv;
158 socklen_t len;
159 int i, r, fd2;
160
161 fd2 = -1;
162
163 switch (call) {
164 case C_ACCEPT:
165 r = accept(fd, remote_addr, &addr_len);
166
167 if (r >= 0)
168 fd2 = r;
169
170 break;
171
172 case C_BIND:
173 r = bind(fd, local_addr, addr_len);
174
175 break;
176
177 case C_CONNECT:
178 r = connect(fd, remote_addr, addr_len);
179
180 break;
181
182 case C_GETPEERNAME:
183 r = getpeername(fd, remote_addr, &addr_len);
184
185 break;
186
187 case C_GETSOCKNAME:
188 r = getsockname(fd, remote_addr, &addr_len);
189
190 break;
191
192 case C_GETSOCKOPT_ERR:
193 len = sizeof(i);
194
195 r = getsockopt(fd, SOL_SOCKET, SO_ERROR, &i, &len);
196
197 /*
198 * We assume this call always succeeds, and test against the
199 * pending error.
200 */
201 if (r != 0) e(0);
202 if (i != 0) {
203 r = -1;
204 errno = i;
205 }
206
207 break;
208
209 case C_GETSOCKOPT_KA:
210 len = sizeof(i);
211
212 r = getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, &len);
213
214 break;
215
216 case C_GETSOCKOPT_RB:
217 len = sizeof(i);
218
219 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &i, &len);
220
221 break;
222
223 case C_IOCTL_NREAD:
224 r = ioctl(fd, FIONREAD, &i);
225
226 /* On success, we test against the returned value here. */
227 if (r == 0)
228 r = i;
229
230 break;
231
232 case C_LISTEN:
233 r = listen(fd, 1);
234
235 break;
236
237 case C_RECV:
238 r = recv(fd, data, sizeof(data), 0);
239
240 break;
241
242 case C_RECVFROM:
243 r = recvfrom(fd, data, sizeof(data), 0, remote_addr,
244 &addr_len);
245
246 break;
247
248 case C_SEND:
249 data[0] = 0;
250
251 r = send(fd, data, sizeof(data), 0);
252
253 break;
254
255 case C_SENDTO:
256 data[0] = 0;
257
258 r = sendto(fd, data, sizeof(data), 0, remote_addr, addr_len);
259
260 break;
261
262 case C_SETSOCKOPT_BC:
263 i = 0;
264
265 r = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i));
266
267 break;
268
269 case C_SETSOCKOPT_KA:
270 i = 1;
271
272 r = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
273
274 break;
275
276 case C_SETSOCKOPT_L:
277 l.l_onoff = 1;
278 l.l_linger = 0;
279
280 r = setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
281
282 break;
283
284 case C_SETSOCKOPT_RA:
285 i = 1;
286
287 r = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
288
289 break;
290
291 case C_SELECT_R:
292 case C_SELECT_W:
293 case C_SELECT_X:
294 FD_ZERO(&fd_set);
295 FD_SET(fd, &fd_set);
296
297 tv.tv_sec = 0;
298 tv.tv_usec = 0;
299
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);
303
304 break;
305
306 case C_SHUTDOWN_R:
307 r = shutdown(fd, SHUT_RD);
308
309 break;
310
311 case C_SHUTDOWN_W:
312 r = shutdown(fd, SHUT_WR);
313
314 break;
315
316 case C_SHUTDOWN_RW:
317 r = shutdown(fd, SHUT_RDWR);
318
319 break;
320
321 default:
322 r = -1;
323 errno = EINVAL;
324 e(0);
325 }
326
327 if (r < -1) e(0);
328
329 if (r == -1)
330 r = -errno;
331
332 if (fd2 >= 0 && close(fd2) != 0) e(0);
333
334 return r;
335 }
336
337 /*
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:
341 *
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().
350 *
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.
354 *
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.
358 *
359 * Standard e() error throwing is used for set-up and result mismatches.
360 */
361 void
socklib_sweep(int domain,int type,int protocol,const enum state * states,unsigned int nstates,const int * results,int (* proc)(int domain,int type,int protocol,enum state,enum call))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))
365 {
366 struct sigaction act, oact;
367 enum state state;
368 enum call call;
369 #if SOCKLIB_SWEEP_GENERATE
370 const char *name;
371 int res, *nresults;
372 #else
373 int res, exp;
374 #endif
375
376 memset(&act, 0, sizeof(act));
377 act.sa_handler = socklib_signal;
378 if (sigaction(SIGPIPE, &act, &oact) != 0) e(0);
379
380 #if SOCKLIB_SWEEP_GENERATE
381 if ((nresults = malloc(nstates * C_MAX)) == NULL) e(0);
382 #endif
383
384 for (state = 0; state < nstates; state++) {
385 for (call = 0; call < C_MAX; call++) {
386 socklib_sigpipe = 0;
387
388 res = proc(domain, type, protocol, states[state],
389 call);
390
391 /*
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.
398 */
399 if (socklib_sigpipe !=
400 (res == -EPIPE && type == SOCK_STREAM)) e(0);
401
402 #if SOCKLIB_SWEEP_GENERATE
403 nresults[call * nstates + state] = res;
404 #else
405 exp = results[call * nstates + state];
406
407 if (res != exp) {
408 printf("FAIL state %d call %d res %d exp %d\n",
409 state, call, res, exp);
410 e(0);
411 }
412 #endif
413 }
414 }
415
416 if (sigaction(SIGPIPE, &oact, NULL) != 0) e(0);
417
418 #if SOCKLIB_SWEEP_GENERATE
419 #if SOCKLIB_SWEEP_GENERATE == 1
420 /*
421 * Generate a table in C form, ready to be pasted into test source.
422 * Obviously, generated results should be hand-checked carefully before
423 * being pasted into a test. Arguably these tables should be hand-made
424 * for maximum scrutiny, but I already checked the results from the
425 * CSV form (#define SOCKLIB_SWEEP_GENERATE 2) and have no desire for
426 * RSI -dcvmoole
427 */
428 printf("\nstatic const int X_results[][__arraycount(X_states)] = {\n");
429 for (call = 0; call < C_MAX; call++) {
430 if ((name = callname[call]) == NULL) e(0);
431 printf("\t[%s]%s%s%s= {", name,
432 (strlen(name) <= 21) ? "\t" : "",
433 (strlen(name) <= 13) ? "\t" : "",
434 (strlen(name) <= 5) ? "\t" : "");
435 for (state = 0; state < nstates; state++) {
436 if (state % 4 == 0)
437 printf("\n\t\t");
438 res = nresults[call * nstates + state];
439 name = (res < 0) ? get_error_name(-res) : NULL;
440 if (name != NULL) {
441 printf("-%s,", name);
442 if ((state + 1) % 4 != 0 &&
443 state < nstates - 1)
444 printf("%s%s",
445 (strlen(name) <= 13) ? "\t" : "",
446 (strlen(name) <= 5) ? "\t" : "");
447 } else {
448 printf("%d,", res);
449 if ((state + 1) % 4 != 0 &&
450 state < nstates - 1)
451 printf("\t\t");
452 }
453 }
454 printf("\n\t},\n");
455 }
456 printf("};\n");
457 #elif SOCKLIB_SWEEP_GENERATE == 2
458 /* Generate table in CSV form. */
459 printf("\n");
460 for (state = 0; state < nstates; state++)
461 printf(",%s", statename[states[state]] + 2);
462 for (call = 0; call < C_MAX; call++) {
463 printf("\n%s", callname[call] + 2);
464 for (state = 0; state < nstates; state++) {
465 res = nresults[call * nstates + state];
466 name = (res < 0) ? get_error_name(-res) : NULL;
467 if (name != NULL)
468 printf(",%s", name);
469 else
470 printf(",%d", res);
471 }
472 }
473 printf("\n");
474 #endif
475
476 free(nresults);
477 #endif
478 }
479
480 /*
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.
484 */
485 void
socklib_multicast_tx_options(int type)486 socklib_multicast_tx_options(int type)
487 {
488 struct in_addr in_addr;
489 socklen_t len;
490 unsigned int ifindex;
491 uint8_t byte;
492 int fd, val;
493
494 subtest = 10;
495
496 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
497
498 /*
499 * Initially, the multicast TTL is expected be 1, looping should be
500 * enabled, and the multicast source address should be <any>.
501 */
502 byte = 0;
503 len = sizeof(byte);
504 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte, &len) != 0)
505 e(0);
506 if (len != sizeof(byte)) e(0);
507 if (type != SOCK_STREAM && byte != 1) e(0);
508
509 byte = 0;
510 len = sizeof(byte);
511 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte, &len) != 0)
512 e(0);
513 if (len != sizeof(byte)) e(0);
514 if (byte != 1) e(0);
515
516 len = sizeof(in_addr);
517 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &in_addr, &len) != 0)
518 e(0);
519 if (len != sizeof(in_addr)) e(0);
520 if (in_addr.s_addr != htonl(INADDR_ANY)) e(0);
521
522 /* It must not be possible to get/set IPv6 options on IPv4 sockets. */
523 val = 0;
524 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
525 sizeof(val)) != -1) e(0);
526 if (errno != ENOPROTOOPT) e(0);
527 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
528 sizeof(val)) != -1) e(0);
529 if (errno != ENOPROTOOPT) e(0);
530 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
531 sizeof(val) /*wrong but it doesn't matter*/) != -1) e(0);
532 if (errno != ENOPROTOOPT) e(0);
533
534 len = sizeof(val);
535 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
536 &len) != -1) e(0);
537 if (errno != ENOPROTOOPT) e(0);
538 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
539 &len) != -1) e(0);
540 if (errno != ENOPROTOOPT) e(0);
541 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != -1)
542 e(0);
543 if (errno != ENOPROTOOPT) e(0);
544
545 if (close(fd) != 0) e(0);
546
547 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
548
549 /*
550 * Expect the same defaults as for IPv4. IPV6_MULTICAST_IF uses an
551 * interface index rather than an IP address, though.
552 */
553 val = 0;
554 len = sizeof(val);
555 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
556 e(0);
557 if (len != sizeof(val)) e(0);
558 if (type != SOCK_STREAM && val != 1) e(0);
559
560 val = 0;
561 len = sizeof(val);
562 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, &len) != 0)
563 e(0);
564 if (len != sizeof(val)) e(0);
565 if (val != 1) e(0);
566
567 len = sizeof(val);
568 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
569 e(0);
570 if (len != sizeof(val)) e(0);
571 if (val != 0) e(0);
572
573 /* It must not be possible to get/set IPv4 options on IPv6 sockets. */
574 byte = 0;
575 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte,
576 sizeof(byte)) != -1) e(0);
577 if (errno != ENOPROTOOPT) e(0);
578 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte,
579 sizeof(byte)) != -1) e(0);
580 if (errno != ENOPROTOOPT) e(0);
581 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &byte,
582 sizeof(byte) /* wrong but it doesn't matter */) != -1) e(0);
583 if (errno != ENOPROTOOPT) e(0);
584
585 len = sizeof(byte);
586 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, &len) != -1)
587 e(0);
588 if (errno != ENOPROTOOPT) e(0);
589 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &val, &len) != -1)
590 e(0);
591 if (errno != ENOPROTOOPT) e(0);
592 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &val, &len) != -1)
593 e(0);
594 if (errno != ENOPROTOOPT) e(0);
595
596 if (close(fd) != 0) e(0);
597
598 /* Test changing options. */
599 if ((fd = socket(AF_INET, type, 0)) < 0) e(0);
600
601 byte = 129;
602 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte,
603 sizeof(byte)) != 0) e(0);
604
605 byte = 0;
606 len = sizeof(byte);
607 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &byte, &len) != 0)
608 e(0);
609 if (len != sizeof(byte)) e(0);
610 if (byte != 129) e(0);
611
612 byte = 0;
613 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte,
614 sizeof(byte)) != 0)
615 e(0);
616
617 byte = 1;
618 len = sizeof(byte);
619 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &byte, &len) != 0)
620 e(0);
621 if (len != sizeof(byte)) e(0);
622 if (byte != 0) e(0);
623
624 in_addr.s_addr = htonl(INADDR_LOOPBACK);
625 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &in_addr,
626 sizeof(in_addr)) != 0)
627 e(0);
628
629 in_addr.s_addr = htonl(INADDR_ANY);
630 len = sizeof(in_addr);
631 if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &in_addr, &len) != 0)
632 e(0);
633 if (len != sizeof(in_addr)) e(0);
634 if (in_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
635
636 if (close(fd) != 0) e(0);
637
638 if ((fd = socket(AF_INET6, type, 0)) < 0) e(0);
639
640 val = 137;
641 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
642 sizeof(val)) != 0) e(0);
643
644 val = 0;
645 len = sizeof(val);
646 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
647 e(0);
648 if (len != sizeof(val)) e(0);
649 if (val != 137) e(0);
650
651 val = -2;
652 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
653 sizeof(val)) != -1) e(0);
654 if (errno != EINVAL) e(0);
655
656 val = 256;
657 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
658 sizeof(val)) != -1) e(0);
659 if (errno != EINVAL) e(0);
660
661 val = 0;
662 len = sizeof(val);
663 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
664 e(0);
665 if (len != sizeof(val)) e(0);
666 if (val != 137) e(0);
667
668 val = -1; /* use default */
669 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
670 sizeof(val)) != 0) e(0);
671
672 val = 0;
673 len = sizeof(val);
674 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, &len) != 0)
675 e(0);
676 if (len != sizeof(val)) e(0);
677 if (val != 1) e(0);
678
679 val = 0;
680 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
681 sizeof(val)) != 0) e(0);
682
683 val = 1;
684 len = sizeof(val);
685 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, &len) != 0)
686 e(0);
687 if (len != sizeof(val)) e(0);
688 if (val != 0) e(0);
689
690 val = 1;
691 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
692 sizeof(val)) != 0) e(0);
693
694 val = -1;
695 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
696 sizeof(val)) != -1) e(0);
697 if (errno != EINVAL) e(0);
698
699 val = 2;
700 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
701 sizeof(val)) != -1) e(0);
702 if (errno != EINVAL) e(0);
703
704 val = 0;
705 len = sizeof(val);
706 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, &len) != 0)
707 e(0);
708 if (len != sizeof(val)) e(0);
709 if (val != 1) e(0);
710
711 val = -1;
712 ifindex = if_nametoindex(LOOPBACK_IFNAME);
713
714 val = ifindex;
715 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
716 sizeof(val)) != 0) e(0);
717
718 val = 0;
719 len = sizeof(val);
720 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
721 e(0);
722 if (len != sizeof(val)) e(0);
723 if (val != ifindex) e(0);
724
725 val = BAD_IFINDEX;
726 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
727 sizeof(val)) != -1) e(0);
728
729 val = -1;
730 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
731 sizeof(val)) != -1) e(0);
732
733 val = 0;
734 len = sizeof(val);
735 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
736 e(0);
737 if (len != sizeof(val)) e(0);
738 if (val != ifindex) e(0);
739
740 val = 0;
741 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
742 sizeof(val)) != 0) e(0);
743
744 val = ifindex;
745 len = sizeof(val);
746 if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val, &len) != 0)
747 e(0);
748 if (len != sizeof(val)) e(0);
749 if (val != 0) e(0);
750
751 if (close(fd) != 0) e(0);
752 }
753
754 /*
755 * Test for large sends and receives on stream sockets with MSG_WAITALL.
756 */
757 void
socklib_large_transfers(int fd[2])758 socklib_large_transfers(int fd[2])
759 {
760 char *buf;
761 pid_t pid;
762 int i, status;
763
764 #define LARGE_BUF (4096*1024)
765
766 if ((buf = malloc(LARGE_BUF)) == NULL) e(0);
767 memset(buf, 0, LARGE_BUF);
768
769 pid = fork();
770 switch (pid) {
771 case 0:
772 errct = 0;
773
774 if (close(fd[0]) != 0) e(0);
775
776 /* Part 1. */
777 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF)
778 e(0);
779
780 for (i = 0; i < LARGE_BUF; i++)
781 if (buf[i] != (char)(i + (i >> 16))) e(0);
782
783 if (recv(fd[1], buf, LARGE_BUF,
784 MSG_DONTWAIT | MSG_WAITALL) != -1) e(0);
785 if (errno != EWOULDBLOCK) e(0);
786
787 /* Part 2. */
788 if (send(fd[1], buf, LARGE_BUF / 2, 0) != LARGE_BUF / 2) e(0);
789
790 if (shutdown(fd[1], SHUT_WR) != 0) e(0);
791
792 /* Part 3. */
793 memset(buf, 'y', LARGE_BUF);
794
795 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF - 1)
796 e(0);
797
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);
801
802 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != 0) e(0);
803
804 exit(errct);
805 case -1:
806 e(0);
807 }
808
809 if (close(fd[1]) != 0) e(0);
810
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));
814
815 if (send(fd[0], buf, LARGE_BUF, 0) != LARGE_BUF) e(0);
816
817 /* Part 2: check that remote shutdown terminates a partial receive. */
818 memset(buf, 'x', LARGE_BUF);
819
820 if (recv(fd[0], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF / 2) e(0);
821
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);
826
827 if (recv(fd[0], buf, LARGE_BUF, MSG_WAITALL) != 0) e(0);
828
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));
832
833 if (send(fd[0], buf, LARGE_BUF - 1, 0) != LARGE_BUF - 1) e(0);
834
835 if (close(fd[0]) != 0) e(0);
836
837 if (waitpid(pid, &status, 0) != pid) e(0);
838 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
839
840 free(buf);
841 }
842
843 #define PRINT_STATS 0
844
845 /*
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.
849 */
850 void
socklib_producer_consumer(int fd[2])851 socklib_producer_consumer(int fd[2])
852 {
853 char *buf;
854 time_t t;
855 socklen_t len, size, off;
856 ssize_t r;
857 pid_t pid;
858 int i, rcvlen, status, exp, flags, num, stat[3] = { 0, 0, 0 };
859
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);
863
864 size = rcvlen * 3;
865
866 if ((buf = malloc(size)) == NULL) e(0);
867
868 t = time(NULL);
869
870 /*
871 * We vary small versus large (random) send and receive sizes,
872 * splitting the entire transfer in four phases along those lines.
873 *
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).
882 */
883 #define TRANSFER_SIZE (16 * 1024 * 1024)
884
885 pid = fork();
886 switch (pid) {
887 case 0:
888 errct = 0;
889
890 if (close(fd[0]) != 0) e(0);
891
892 srand48(t + 1);
893
894 for (off = 0; off < TRANSFER_SIZE; ) {
895 if (off < TRANSFER_SIZE / 2)
896 len = lrand48() %
897 ((off / (TRANSFER_SIZE / 8) % 2) ? 64 :
898 256);
899 else
900 len = lrand48() % size;
901
902 num = lrand48() % 16;
903 flags = 0;
904 if (num & 1) flags |= MSG_PEEK;
905 if (num & 2) flags |= MSG_WAITALL;
906 if (num & 4) flags |= MSG_DONTWAIT;
907 if (num & 8) {
908 /*
909 * Obviously there are race conditions here but
910 * the returned number should be a lower bound.
911 */
912 if (ioctl(fd[1], FIONREAD, &exp) != 0) e(0);
913 if (exp < 0 || exp > rcvlen) e(0);
914 } else
915 exp = -1;
916
917 stat[0]++;
918
919 if ((r = recv(fd[1], buf, len, flags)) == -1) {
920 if (errno != EWOULDBLOCK) e(0);
921 if (exp > 0) e(0);
922
923 stat[2]++;
924 continue;
925 }
926
927 if (r < len) {
928 stat[1]++;
929
930 if (exp > r) e(0);
931 }
932
933 for (i = 0; i < r; i++)
934 if (buf[i] != (char)((off + i) +
935 ((off + i) >> 16))) e(0);
936
937 if (!(flags & MSG_PEEK)) {
938 off += r;
939
940 if ((flags & (MSG_DONTWAIT | MSG_WAITALL)) ==
941 MSG_WAITALL && r != len &&
942 off < TRANSFER_SIZE) e(0);
943 }
944 }
945
946 #if PRINT_STATS
947 /*
948 * The second and third numbers should ideally be a large but
949 * non-dominating fraction of the first one.
950 */
951 printf("RECV: total %d short %d again %d\n",
952 stat[0], stat[1], stat[2]);
953 #endif
954
955 if (close(fd[1]) != 0) e(0);
956 exit(errct);
957 case -1:
958 e(0);
959 }
960
961 if (close(fd[1]) != 0) e(0);
962
963 srand48(t);
964
965 for (off = 0; off < TRANSFER_SIZE; ) {
966 if (off < TRANSFER_SIZE / 4 ||
967 (off >= TRANSFER_SIZE / 2 && off < TRANSFER_SIZE * 3 / 4))
968 len = lrand48() % 64;
969 else
970 len = lrand48() % size;
971
972 if (len > TRANSFER_SIZE - off)
973 len = TRANSFER_SIZE - off;
974
975 for (i = 0; i < len; i++)
976 buf[i] = (off + i) + ((off + i) >> 16);
977
978 flags = (lrand48() % 2) ? MSG_DONTWAIT : 0;
979
980 stat[0]++;
981
982 r = send(fd[0], buf, len, flags);
983
984 if (r != len) {
985 if (r > (ssize_t)len) e(0);
986 if (!(flags & MSG_DONTWAIT)) e(0);
987 if (r == -1) {
988 if (errno != EWOULDBLOCK) e(0);
989 r = 0;
990
991 stat[2]++;
992 } else
993 stat[1]++;
994 }
995
996 if (off / (TRANSFER_SIZE / 4) !=
997 (off + r) / (TRANSFER_SIZE / 4))
998 sleep(1);
999
1000 off += r;
1001 }
1002
1003 #if PRINT_STATS
1004 /*
1005 * The second and third numbers should ideally be a large but non-
1006 * dominating fraction of the first one.
1007 */
1008 printf("SEND: total %d short %d again %d\n",
1009 stat[0], stat[1], stat[2]);
1010 #endif
1011
1012 free(buf);
1013
1014 if (close(fd[0]) != 0) e(0);
1015
1016 if (waitpid(pid, &status, 0) != pid) e(0);
1017 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1018 }
1019
1020 /*
1021 * Signal handler which just needs to exist, so that invoking it will interrupt
1022 * an ongoing system call.
1023 */
1024 static void
socklib_got_signal(int sig __unused)1025 socklib_got_signal(int sig __unused)
1026 {
1027
1028 /* Nothing. */
1029 }
1030
1031 /*
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.
1040 */
1041 #define MAX_BYTES 2 /* set to 3 for slightly better(?) testing */
1042 #define USLEEP_TIME 250000 /* increase on wimpy platforms if needed */
1043
1044 static void
socklib_stream_recv_sub(int (* socket_pair)(int,int,int,int *),int domain,int type,int idata,int istate,int rlowat,int len,int bits,int act,int (* break_recv)(int,const char *,size_t))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))
1048 {
1049 const char *data = "ABCDE"; /* this limits MAX_BYTES to 3 */
1050 struct sigaction sa;
1051 struct timeval tv;
1052 fd_set fds;
1053 char buf[3];
1054 pid_t pid;
1055 int fd[2], val, flags, min, res, err;
1056 int pfd[2], edata, tstate, fl, status;
1057
1058 if (socket_pair(domain, type, 0, fd) != 0) e(0);
1059
1060 /*
1061 * Set up the initial condition on the sockets.
1062 */
1063 if (idata > 0)
1064 if (send(fd[1], data, idata, 0) != idata) e(0);
1065
1066 switch (istate) {
1067 case 0: break;
1068 case 1: if (shutdown(fd[0], SHUT_RD) != 0) e(0); break;
1069 case 2: if (shutdown(fd[1], SHUT_WR) != 0) e(0); break;
1070 case 3: if (close(fd[1]) != 0) e(0); break;
1071 }
1072
1073 /* Set the low receive water mark. */
1074 if (setsockopt(fd[0], SOL_SOCKET, SO_RCVLOWAT, &rlowat,
1075 sizeof(rlowat)) != 0) e(0);
1076
1077 /* SO_RCVLOWAT is always bounded by the actual receive length. */
1078 min = MIN(len, rlowat);
1079
1080 /*
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.
1083 */
1084 FD_ZERO(&fds);
1085 FD_SET(fd[0], &fds);
1086 tv.tv_sec = 0;
1087 tv.tv_usec = 0;
1088 res = select(fd[0] + 1, &fds, NULL, NULL, &tv);
1089 if (res < 0 || res > 1) e(0);
1090 if (res != (idata >= rlowat || istate > 0)) e(0);
1091 if (res == 1 && !FD_ISSET(fd[0], &fds)) e(0);
1092
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);
1096
1097 /* Translate the given bits to receive call flags. */
1098 flags = 0;
1099 if (bits & 1) flags |= MSG_PEEK;
1100 if (bits & 2) flags |= MSG_DONTWAIT;
1101 if (bits & 4) flags |= MSG_WAITALL;
1102
1103 /*
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.
1109 */
1110 if ((flags & MSG_DONTWAIT) || istate > 0 || (idata >= min &&
1111 ((flags & (MSG_PEEK | MSG_WAITALL)) != MSG_WAITALL ||
1112 idata >= len))) {
1113 res = recv(fd[0], buf, len, flags);
1114
1115 if (res == -1 && errno != EWOULDBLOCK) e(0);
1116
1117 /*
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.
1125 */
1126 if (istate == 1) {
1127 if (res != 0) e(0);
1128 } else if (idata >= min) {
1129 if (res != MIN(len, idata)) e(0);
1130 if (strncmp(buf, data, res)) e(0);
1131 } else if (istate > 0) {
1132 if (res != idata) e(0);
1133 if (strncmp(buf, data, res)) e(0);
1134 } else
1135 if (res != -1) e(0);
1136
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);
1140
1141 return;
1142 }
1143
1144 /*
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!
1152 */
1153 if (!(flags & MSG_WAITALL)) {
1154 if (recv(fd[0], buf, len, flags | MSG_DONTWAIT) != -1) e(0);
1155 if (errno != EWOULDBLOCK) e(0);
1156 }
1157
1158 /*
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.
1161 *
1162 * If (act == 12), we use a signal to interrupt the receive call.
1163 */
1164 if (act < 12) {
1165 edata = act % 3;
1166 tstate = act / 3;
1167 } else
1168 edata = tstate = 0;
1169
1170 if (pipe2(pfd, O_NONBLOCK) != 0) e(0);
1171
1172 pid = fork();
1173 switch (pid) {
1174 case 0:
1175 errct = 0;
1176
1177 if (close(fd[1]) != 0) e(0);
1178 if (close(pfd[0]) != 0) e(0);
1179
1180 if (act == 12) {
1181 memset(&sa, 0, sizeof(sa));
1182 sa.sa_handler = socklib_got_signal;
1183 if (sigaction(SIGUSR1, &sa, NULL) != 0) e(0);
1184 }
1185
1186 res = recv(fd[0], buf, len, flags);
1187 err = errno;
1188
1189 if (write(pfd[1], &res, sizeof(res)) != sizeof(res)) e(0);
1190 if (write(pfd[1], &err, sizeof(err)) != sizeof(err)) e(0);
1191
1192 if (res > 0 && strncmp(buf, data, res)) e(0);
1193
1194 exit(errct);
1195 case -1:
1196 e(0);
1197 }
1198
1199 if (close(pfd[1]) != 0) e(0);
1200
1201 /*
1202 * Allow the child to enter the blocking recv(2), and check the pipe
1203 * to see if it is really blocked.
1204 */
1205 if (usleep(USLEEP_TIME) != 0) e(0);
1206
1207 if (read(pfd[0], buf, 1) != -1) e(0);
1208 if (errno != EAGAIN) e(0);
1209
1210 if (edata > 0) {
1211 if (send(fd[1], &data[idata], edata, 0) != edata) e(0);
1212
1213 /*
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.
1217 */
1218 if (idata + edata >= min &&
1219 ((flags & (MSG_PEEK | MSG_WAITALL)) != MSG_WAITALL ||
1220 idata + edata >= len)) {
1221 if ((fl = fcntl(pfd[0], F_GETFL, 0)) == -1) e(0);
1222 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0)
1223 e(0);
1224
1225 if (read(pfd[0], &res, sizeof(res)) != sizeof(res))
1226 e(0);
1227 if (read(pfd[0], &err, sizeof(err)) != sizeof(err))
1228 e(0);
1229
1230 if (res != MIN(idata + edata, len)) e(0);
1231
1232 /* Bail out. */
1233 goto cleanup;
1234 }
1235
1236 /* Sleep and test once more. */
1237 if (usleep(USLEEP_TIME) != 0) e(0);
1238
1239 if (read(pfd[0], buf, 1) != -1) e(0);
1240 if (errno != EAGAIN) e(0);
1241 }
1242
1243 if (act < 12) {
1244 /*
1245 * Now test various ways to terminate the receive call.
1246 */
1247 switch (tstate) {
1248 case 0: if (shutdown(fd[0], SHUT_RD) != 0) e(0); break;
1249 case 1: if (shutdown(fd[1], SHUT_WR) != 0) e(0); break;
1250 case 2: if (close(fd[1]) != 0) e(0); fd[1] = -1; break;
1251 case 3: fd[1] = break_recv(fd[1], data, strlen(data)); break;
1252 }
1253 } else
1254 if (kill(pid, SIGUSR1) != 0) e(0);
1255
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);
1258
1259 if (read(pfd[0], &res, sizeof(res)) != sizeof(res)) e(0);
1260 if (read(pfd[0], &err, sizeof(err)) != sizeof(err)) e(0);
1261
1262 if (act < 12) {
1263 /*
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.
1269 */
1270 if (tstate == 0 && idata + edata < min) {
1271 if (res != 0) e(0);
1272 } else if (idata + edata > 0) {
1273 if (res != MIN(idata + edata, len)) e(0);
1274 } else if (tstate == 3) {
1275 if (fd[1] == -1) {
1276 if (res != -1) e(0);
1277 if (err != ECONNRESET) e(0);
1278 } else
1279 if (res != len) e(0);
1280 } else
1281 if (res != 0) e(0);
1282 } else {
1283 /*
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.
1287 */
1288 if (idata >= min) {
1289 if (res != MIN(idata, len)) e(0);
1290 } else {
1291 if (res != -1) e(0);
1292 if (err != EINTR) e(0);
1293 }
1294 }
1295
1296 cleanup:
1297 if (close(pfd[0]) != 0) e(0);
1298
1299 if (wait(&status) != pid) e(0);
1300 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1301
1302 if (fd[1] != -1 && close(fd[1]) != 0) e(0);
1303 if (close(fd[0]) != 0) e(0);
1304 }
1305
1306 /*
1307 * Test for receiving on stream sockets. In particular, test SO_RCVLOWAT,
1308 * MSG_PEEK, MSG_DONTWAIT, and MSG_WAITALL.
1309 */
1310 void
socklib_stream_recv(int (* socket_pair)(int,int,int,int *),int domain,int type,int (* break_recv)(int,const char *,size_t))1311 socklib_stream_recv(int (* socket_pair)(int, int, int, int *), int domain,
1312 int type, int (* break_recv)(int, const char *, size_t))
1313 {
1314 int idata, istate, rlowat, len, bits, act;
1315
1316 /* Insanity. */
1317 for (idata = 0; idata <= MAX_BYTES; idata++)
1318 for (istate = 0; istate <= 3; istate++)
1319 for (rlowat = 1; rlowat <= MAX_BYTES; rlowat++)
1320 for (len = 1; len <= MAX_BYTES; len++)
1321 for (bits = 0; bits < 8; bits++)
1322 for (act = 0; act <= 12; act++)
1323 socklib_stream_recv_sub
1324 (socket_pair,
1325 domain, type,
1326 idata, istate,
1327 rlowat, len, bits,
1328 act, break_recv);
1329 }
1330
1331 /*
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.
1336 */
1337 int
socklib_find_pcb(const char * path,int protocol,uint16_t local_port,uint16_t remote_port,struct kinfo_pcb * ki)1338 socklib_find_pcb(const char * path, int protocol, uint16_t local_port,
1339 uint16_t remote_port, struct kinfo_pcb * ki)
1340 {
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;
1347
1348 miblen = __arraycount(mib);
1349 if (sysctlnametomib(path, mib, &miblen) != 0) e(0);
1350 if (miblen > __arraycount(mib) - 4) e(0);
1351 mib[miblen++] = 0;
1352 mib[miblen++] = 0;
1353 mib[miblen++] = sizeof(*array);
1354 mib[miblen++] = 0;
1355
1356 if (sysctl(mib, miblen, NULL, &oldlen, NULL, 0) != 0) e(0);
1357 if (oldlen == 0)
1358 return 0; /* should not happen due to added slop space */
1359 if (oldlen % sizeof(*array)) e(0);
1360
1361 if ((array = (struct kinfo_pcb *)malloc(oldlen)) == NULL) e(0);
1362
1363 if (sysctl(mib, miblen, array, &oldlen, NULL, 0) != 0) e(0);
1364 if (oldlen % sizeof(*array)) e(0);
1365
1366 found = -1;
1367 for (i = 0; i < oldlen / sizeof(*array); i++) {
1368 /* Perform some basic checks. */
1369 if (array[i].ki_pcbaddr == 0) e(0);
1370 if (array[i].ki_ppcbaddr == 0) e(0);
1371 if (array[i].ki_family != mib[1]) e(0);
1372
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);
1378
1379 memcpy(&sin6, &array[i].ki_dst, sizeof(sin6));
1380 if (sin6.sin6_family != AF_INET6) e(0);
1381 if (sin6.sin6_len != sizeof(sin6)) e(0);
1382 rport = ntohs(sin6.sin6_port);
1383 } else {
1384 memcpy(&sin, &array[i].ki_src, sizeof(sin));
1385 if (sin.sin_family != AF_INET) e(0);
1386 if (sin.sin_len != sizeof(sin)) e(0);
1387 lport = ntohs(sin.sin_port);
1388
1389 memcpy(&sin, &array[i].ki_dst, sizeof(sin));
1390 if (sin.sin_family != AF_UNSPEC) {
1391 if (sin.sin_family != AF_INET) e(0);
1392 if (sin.sin_len != sizeof(sin)) e(0);
1393 rport = ntohs(sin.sin_port);
1394 } else
1395 rport = 0;
1396 }
1397
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);
1402
1403 found = (int)i;
1404 }
1405 }
1406
1407 if (found >= 0)
1408 memcpy(ki, &array[found], sizeof(*ki));
1409
1410 free(array);
1411
1412 return (found != -1);
1413 }
1414
1415 #ifdef NO_INET6
1416 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
1417 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
1418
1419 void
inet6_getscopeid(struct sockaddr_in6 * sin6 __unused,int flags __unused)1420 inet6_getscopeid(struct sockaddr_in6 * sin6 __unused, int flags __unused)
1421 {
1422
1423 /*
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.
1427 */
1428 }
1429 #endif /* NO_INET6 */
1430
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 */
1435
1436 /*
1437 * Test local and remote IPv6 address handling on TCP or UDP sockets.
1438 */
1439 void
socklib_test_addrs(int type,int protocol)1440 socklib_test_addrs(int type, int protocol)
1441 {
1442 struct sockaddr_in6 sin6, sin6_any, sin6_any_scope, sin6_lo,
1443 sin6_lo_scope, sin6_ll_all, sin6_ll_lo, sin6_ll_rem, sin6_ll_kame,
1444 sin6_ll_bad, sin6_ll_mix, sin6_rem, sin6_v4_any, sin6_v4_lo,
1445 sin6_v4_rem, rsin6;
1446 const struct sockaddr_in6 *sin6p;
1447 const struct {
1448 const struct sockaddr_in6 *addr;
1449 int res;
1450 int flags;
1451 const struct sockaddr_in6 *name;
1452 } bind_array[] = {
1453 { NULL, 0, F_ANY, &sin6_any },
1454 { &sin6_any, 0, F_ANY, &sin6_any },
1455 { &sin6_any_scope, 0, F_ANY, &sin6_any },
1456 { &sin6_lo, 0, 0, &sin6_lo },
1457 { &sin6_lo_scope, 0, 0, &sin6_lo },
1458 { &sin6_ll_lo, 0, 0, &sin6_ll_lo },
1459 { &sin6_v4_lo, 0, F_V4, &sin6_v4_lo },
1460 { &sin6_rem, EADDRNOTAVAIL },
1461 { &sin6_ll_all, EADDRNOTAVAIL },
1462 { &sin6_ll_rem, EADDRNOTAVAIL },
1463 { &sin6_ll_kame, EINVAL },
1464 { &sin6_ll_bad, ENXIO },
1465 { &sin6_v4_any, EADDRNOTAVAIL },
1466 { &sin6_v4_rem, EADDRNOTAVAIL },
1467 /* The following entry MUST be last. */
1468 { &sin6_ll_mix, EADDRNOTAVAIL },
1469 }, *bp;
1470 const struct {
1471 const struct sockaddr_in6 *addr;
1472 int res;
1473 int flags;
1474 const struct sockaddr_in6 *name;
1475 } conn_array[] = {
1476 { &sin6_any, EHOSTUNREACH, 0 },
1477 { &sin6_any_scope, EHOSTUNREACH, 0 },
1478 { &sin6_ll_kame, EINVAL, 0 },
1479 { &sin6_ll_bad, ENXIO, 0 },
1480 { &sin6_v4_any, EHOSTUNREACH, F_V4 },
1481 { &sin6_lo, 0, 0, &sin6_lo },
1482 { &sin6_lo_scope, 0, 0, &sin6_lo },
1483 { &sin6_ll_all, 0, 0, &sin6_ll_lo },
1484 { &sin6_ll_lo, 0, 0, &sin6_ll_lo },
1485 { &sin6_v4_lo, 0, F_V4, &sin6_v4_lo },
1486 { &sin6_rem, 0, F_REM, &sin6_rem },
1487 { &sin6_ll_rem, 0, F_REM, &sin6_ll_rem },
1488 { &sin6_v4_rem, 0, F_V4|F_REM, &sin6_v4_rem },
1489 /* The following entry MUST be last. */
1490 { &sin6_ll_mix, 0, F_REM|F_MIX, &sin6_ll_mix },
1491 }, *cp;
1492 struct ifaddrs *ifa, *ifp, *ifp2;
1493 struct in6_ifreq ifr;
1494 char name[IF_NAMESIZE], buf[1];
1495 socklen_t len;
1496 uint32_t port;
1497 unsigned int i, j, ifindex, ifindex2, have_mix, found;
1498 int r, fd, fd2, fd3, val, sfl, exp, link_state;
1499
1500 ifindex = if_nametoindex(LOOPBACK_IFNAME);
1501 if (ifindex == 0) e(0);
1502
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));
1508
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;
1512
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));
1517
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;
1521
1522 /* An IPv6 link-local address without scope - fe80::1. */
1523 memcpy(&sin6_ll_all, &sin6_any, sizeof(sin6_ll_all));
1524 if (inet_pton(AF_INET6, LOOPBACK_IPV6_LL, &sin6_ll_all.sin6_addr) != 1)
1525 e(0);
1526
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;
1530
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);
1535
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;
1540
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;
1544
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);
1549
1550 /* An IPv4-mapped IPv6 address for 'any' - ::ffff:0.0.0.0. */
1551 memcpy(&sin6_v4_any, &sin6_any, sizeof(sin6_v4_any));
1552 if (inet_pton(AF_INET6, "::ffff:0:0", &sin6_v4_any.sin6_addr) != 1)
1553 e(0);
1554
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);
1559
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);
1564
1565 /*
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.
1569 */
1570 have_mix = 0;
1571 for (i = 1; i < BAD_IFINDEX; i++) {
1572 if (if_indextoname(i, name) == NULL) {
1573 if (errno != ENXIO) e(0);
1574 continue;
1575 }
1576
1577 if (!strcmp(name, LOOPBACK_IFNAME))
1578 continue;
1579
1580 /* Found one! */
1581 memcpy(&sin6_ll_mix, &sin6_ll_all, sizeof(sin6_ll_mix));
1582 sin6_ll_mix.sin6_scope_id = i;
1583 have_mix = 1;
1584 break;
1585 }
1586
1587 /*
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.
1595 */
1596 for (i = 0; i < __arraycount(bind_array) - !have_mix; i++) {
1597 bp = &bind_array[i];
1598
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);
1602
1603 val = 0;
1604 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1605 sizeof(val)) != 0) e(0);
1606
1607 r = bind(fd, (struct sockaddr *)bp->addr,
1608 sizeof(*bp->addr));
1609
1610 /* Did the bind(2) call produce the expected result? */
1611 if (r == 0) {
1612 if (bp->res != 0) e(0);
1613 } else
1614 if (r != -1 || bp->res != errno) e(0);
1615
1616 /* The rest is for successful bind(2) calls. */
1617 if (r != 0) {
1618 if (close(fd) != 0) e(0);
1619
1620 continue;
1621 }
1622
1623 /* Get the bound address. */
1624 len = sizeof(sin6);
1625 if (getsockname(fd, (struct sockaddr *)&sin6,
1626 &len) != 0) e(0);
1627 if (len != sizeof(sin6)) e(0);
1628
1629 /* A port must be set. Clear it for the comparison. */
1630 if ((sin6.sin6_port == 0) == (type != SOCK_RAW)) e(0);
1631
1632 sin6.sin6_port = 0;
1633 if (memcmp(&sin6, bp->name, sizeof(sin6)) != 0) e(0);
1634
1635 if (close(fd) != 0) e(0);
1636 }
1637
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];
1641
1642 /*
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.
1646 */
1647 if ((bp->flags & F_ANY) && (cp->flags & F_REM))
1648 continue;
1649
1650 /*
1651 * Use non-blocking sockets only if connecting is going
1652 * to take a while before ultimately failing; TCP only.
1653 */
1654 sfl = ((cp->flags & F_REM) && (type == SOCK_STREAM)) ?
1655 SOCK_NONBLOCK : 0;
1656 if ((fd = socket(AF_INET6, type | sfl, protocol)) < 0)
1657 e(0);
1658
1659 val = 0;
1660 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1661 sizeof(val)) != 0) e(0);
1662
1663 if (bp->addr != NULL) {
1664 if (bind(fd, (struct sockaddr *)bp->addr,
1665 sizeof(*bp->addr)) != 0) e(0);
1666
1667 len = sizeof(sin6);
1668 if (getsockname(fd, (struct sockaddr *)&sin6,
1669 &len) != 0) e(0);
1670
1671 port = sin6.sin6_port;
1672 } else
1673 port = 0;
1674
1675 memcpy(&sin6, cp->addr, sizeof(sin6));
1676 sin6.sin6_port = htons(TEST_PORT_A);
1677
1678 if ((exp = cp->res) == 0 && type == SOCK_STREAM) {
1679 if (cp->flags & F_REM)
1680 exp = EINPROGRESS;
1681 if (cp->flags & F_MIX)
1682 exp = EHOSTUNREACH;
1683 }
1684
1685 /*
1686 * The IPv4/IPv6 mismatch check precedes most other
1687 * checks, but (currently) not the bad-scope-ID check.
1688 */
1689 if (exp != ENXIO && !(bp->flags & F_ANY) &&
1690 ((bp->flags ^ cp->flags) & F_V4))
1691 exp = EINVAL;
1692
1693 /*
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.
1697 */
1698 if (exp == 0 && !(cp->flags & F_REM)) {
1699 if ((fd2 = socket(AF_INET6, type,
1700 protocol)) < 0) e(0);
1701
1702 val = 0;
1703 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY,
1704 &val, sizeof(val)) != 0) e(0);
1705
1706 val = 1;
1707 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR,
1708 &val, sizeof(val)) != 0) e(0);
1709
1710 memcpy(&rsin6, cp->name, sizeof(rsin6));
1711 rsin6.sin6_port = htons(TEST_PORT_A);
1712
1713 if (bind(fd2, (struct sockaddr *)&rsin6,
1714 sizeof(rsin6)) != 0) e(0);
1715
1716 if (type == SOCK_STREAM && listen(fd2, 1) != 0)
1717 e(0);
1718 } else
1719 fd2 = -1;
1720
1721 r = connect(fd, (struct sockaddr *)&sin6,
1722 sizeof(sin6));
1723
1724 if (r == 0) {
1725 if (exp != 0) e(0);
1726 } else
1727 if (r != -1 || exp != errno) e(0);
1728
1729 if (r != 0) {
1730 if (close(fd) != 0) e(0);
1731
1732 continue;
1733 }
1734
1735 /*
1736 * Connecting should always assign a local address if
1737 * no address was assigned, even if a port was assigned
1738 * already. In the latter case, the port number must
1739 * obviously not change. Test getsockname(2) again, if
1740 * we can.
1741 */
1742 len = sizeof(sin6);
1743 if (getsockname(fd, (struct sockaddr *)&sin6,
1744 &len) != 0) e(0);
1745 if (len != sizeof(sin6)) e(0);
1746
1747 if (type != SOCK_RAW) {
1748 if (sin6.sin6_port == 0) e(0);
1749 if (port != 0 && port != sin6.sin6_port) e(0);
1750 } else
1751 if (sin6.sin6_port != 0) e(0);
1752 port = sin6.sin6_port;
1753
1754 if (!(bp->flags & F_ANY))
1755 sin6p = bp->name;
1756 else if (!(cp->flags & F_REM))
1757 sin6p = cp->name;
1758 else
1759 sin6p = NULL; /* can't test: may vary */
1760
1761 if (sin6p != NULL) {
1762 sin6.sin6_port = 0;
1763
1764 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1765 e(0);
1766 }
1767
1768 /*
1769 * Test getpeername(2). It should always be the
1770 * "normalized" version of the target address.
1771 */
1772 len = sizeof(sin6);
1773 if (getpeername(fd, (struct sockaddr *)&sin6,
1774 &len) != 0) e(0);
1775 if (len != sizeof(sin6)) e(0);
1776
1777 if (type != SOCK_RAW) {
1778 if (sin6.sin6_port != htons(TEST_PORT_A)) e(0);
1779 } else {
1780 if (sin6.sin6_port != 0) e(0);
1781 }
1782
1783 sin6.sin6_port = 0;
1784 if (memcmp(&sin6, cp->name, sizeof(sin6)) != 0) e(0);
1785
1786 /* Test send(2) on UDP sockets. */
1787 if (type != SOCK_STREAM) {
1788 r = send(fd, "A", 1, 0);
1789
1790 /*
1791 * For remote (rejected) addresses and scope
1792 * mixing, actual send calls may fail after the
1793 * connect succeeded.
1794 */
1795 if (r == -1 &&
1796 !(cp->flags & (F_REM | F_MIX))) e(0);
1797 else if (r != -1 && r != 1) e(0);
1798
1799 if (r != 1 && fd2 != -1) {
1800 if (close(fd2) != 0) e(0);
1801 fd2 = -1;
1802 }
1803 }
1804
1805 if (fd2 == -1) {
1806 if (close(fd) != 0) e(0);
1807
1808 continue;
1809 }
1810
1811 /*
1812 * The connect or send call succeeded, so we should now
1813 * be able to check the other end.
1814 */
1815 if (type == SOCK_STREAM) {
1816 /* Test accept(2). */
1817 len = sizeof(sin6);
1818 if ((fd3 = accept(fd2,
1819 (struct sockaddr *)&sin6, &len)) < 0) e(0);
1820 if (len != sizeof(sin6)) e(0);
1821
1822 if (close(fd2) != 0) e(0);
1823
1824 if (sin6.sin6_port != port) e(0);
1825 sin6.sin6_port = 0;
1826
1827 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1828 e(0);
1829
1830 /* Test getpeername(2). */
1831 if (getpeername(fd3, (struct sockaddr *)&sin6,
1832 &len) != 0) e(0);
1833 if (len != sizeof(sin6)) e(0);
1834
1835 if (sin6.sin6_port != port) e(0);
1836 sin6.sin6_port = 0;
1837
1838 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1839 e(0);
1840
1841 /* Test getsockname(2). */
1842 if (getsockname(fd3, (struct sockaddr *)&sin6,
1843 &len) != 0) e(0);
1844 if (len != sizeof(sin6)) e(0);
1845
1846 if (sin6.sin6_port != htons(TEST_PORT_A)) e(0);
1847 sin6.sin6_port = 0;
1848
1849 if (memcmp(&sin6, cp->name, sizeof(sin6)) != 0)
1850 e(0);
1851
1852 if (close(fd3) != 0) e(0);
1853 } else {
1854 /* Test recvfrom(2). */
1855 len = sizeof(sin6);
1856 if (recvfrom(fd2, buf, sizeof(buf), 0,
1857 (struct sockaddr *)&sin6, &len) != 1) e(0);
1858
1859 if (buf[0] != 'A') e(0);
1860 if (len != sizeof(sin6)) e(0);
1861
1862 if (sin6.sin6_port != port) e(0);
1863 sin6.sin6_port = 0;
1864
1865 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
1866 e(0);
1867
1868 if (close(fd2) != 0) e(0);
1869 }
1870
1871 if (close(fd) != 0) e(0);
1872 }
1873
1874 if (type == SOCK_STREAM)
1875 continue;
1876
1877 /* Test sendto(2). */
1878 for (j = 0; j < __arraycount(conn_array) - !have_mix; j++) {
1879 cp = &conn_array[j];
1880
1881 /*
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.
1885 */
1886 if ((bp->flags & F_ANY) && (cp->flags & F_REM))
1887 continue;
1888
1889 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
1890
1891 val = 0;
1892 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1893 sizeof(val)) != 0) e(0);
1894
1895 if (bp->addr != NULL) {
1896 if (bind(fd, (struct sockaddr *)bp->addr,
1897 sizeof(*bp->addr)) != 0) e(0);
1898
1899 len = sizeof(sin6);
1900 if (getsockname(fd, (struct sockaddr *)&sin6,
1901 &len) != 0) e(0);
1902
1903 port = sin6.sin6_port;
1904 } else
1905 port = 0;
1906
1907 memcpy(&sin6, cp->addr, sizeof(sin6));
1908 if (type != SOCK_RAW)
1909 sin6.sin6_port = htons(TEST_PORT_B);
1910
1911 if ((exp = cp->res) == 0) {
1912 if (cp->flags & (F_REM | F_MIX))
1913 exp = EHOSTUNREACH;
1914 }
1915
1916 /*
1917 * The IPv4/IPv6 mismatch check precedes most other
1918 * checks, but (currently) not the bad-scope-ID check.
1919 */
1920 if (exp != ENXIO && !(bp->flags & F_ANY) &&
1921 ((bp->flags ^ cp->flags) & F_V4))
1922 exp = EINVAL;
1923
1924 /*
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.
1928 */
1929 if (exp == 0 && !(cp->flags & F_REM)) {
1930 if ((fd2 = socket(AF_INET6, type,
1931 protocol)) < 0) e(0);
1932
1933 val = 0;
1934 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY,
1935 &val, sizeof(val)) != 0) e(0);
1936
1937 val = 1;
1938 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR,
1939 &val, sizeof(val)) != 0) e(0);
1940
1941 memcpy(&rsin6, cp->name, sizeof(rsin6));
1942 if (type != SOCK_RAW)
1943 rsin6.sin6_port = htons(TEST_PORT_B);
1944
1945 if (bind(fd2, (struct sockaddr *)&rsin6,
1946 sizeof(rsin6)) != 0) e(0);
1947 } else
1948 fd2 = -1;
1949
1950 r = sendto(fd, "B", 1, 0, (struct sockaddr *)&sin6,
1951 sizeof(sin6));
1952
1953 if (r != 1) {
1954 if (r != -1 || exp != errno) e(0);
1955
1956 if (close(fd) != 0) e(0);
1957
1958 continue;
1959 }
1960
1961 if (exp != 0) e(0);
1962
1963 /*
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.
1967 */
1968 len = sizeof(sin6);
1969 if (getsockname(fd, (struct sockaddr *)&sin6,
1970 &len) != 0) e(0);
1971 if (len != sizeof(sin6)) e(0);
1972
1973 if (type != SOCK_RAW) {
1974 if (sin6.sin6_port == 0) e(0);
1975 if (port != 0 && port != sin6.sin6_port) e(0);
1976 } else
1977 if (sin6.sin6_port != 0) e(0);
1978 port = sin6.sin6_port;
1979
1980 sin6.sin6_port = 0;
1981 if (memcmp(&sin6, bp->name, sizeof(sin6)) != 0) e(0);
1982
1983 if (fd2 != -1) {
1984 /* Test recvfrom(2) on the receiving socket. */
1985 len = sizeof(sin6);
1986 if (recvfrom(fd2, buf, sizeof(buf), 0,
1987 (struct sockaddr *)&sin6, &len) != 1) e(0);
1988
1989 if (buf[0] != 'B') e(0);
1990 if (len != sizeof(sin6)) e(0);
1991
1992 if (sin6.sin6_port != port) e(0);
1993 sin6.sin6_port = 0;
1994
1995 if (bp->flags & F_ANY)
1996 sin6p = cp->name;
1997 else
1998 sin6p = bp->name;
1999
2000 if (memcmp(&sin6, sin6p, sizeof(sin6)) != 0)
2001 e(0);
2002
2003 if (close(fd2) != 0) e(0);
2004 }
2005
2006 if (close(fd) != 0) e(0);
2007 }
2008 }
2009
2010 /*
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.
2014 */
2015 if (getifaddrs(&ifa) != 0) e(0);
2016
2017 found = 0;
2018 for (ifp = ifa; ifp != NULL; ifp = ifp->ifa_next) {
2019 if (strcmp(ifp->ifa_name, LOOPBACK_IFNAME) == 0)
2020 continue;
2021
2022 if (!(ifp->ifa_flags & IFF_UP) || ifp->ifa_addr == NULL ||
2023 ifp->ifa_addr->sa_family != AF_INET6)
2024 continue;
2025
2026 memcpy(&sin6, ifp->ifa_addr, sizeof(sin6));
2027
2028 if (!IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
2029 continue;
2030
2031 /*
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).
2038 */
2039 link_state = LINK_STATE_DOWN;
2040
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));
2049
2050 break;
2051 }
2052 }
2053
2054 if (link_state == LINK_STATE_DOWN)
2055 continue;
2056
2057 /*
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.
2061 */
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));
2065
2066 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) e(0);
2067
2068 if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr) != 0) e(0);
2069
2070 if (close(fd) != 0) e(0);
2071
2072 if (ifr.ifr_ifru.ifru_flags6 &
2073 (IN6_IFF_DUPLICATED | IN6_IFF_TENTATIVE))
2074 continue;
2075
2076 /* Compensate for poor decisions made by the KAME project. */
2077 inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL);
2078
2079 if (sin6.sin6_scope_id == 0 || sin6.sin6_scope_id == ifindex)
2080 e(0);
2081
2082 found = 1;
2083
2084 break;
2085 }
2086
2087 freeifaddrs(ifa);
2088
2089 /*
2090 * If no second interface with a link-local address was found, we
2091 * cannot perform the rest of this subtest.
2092 */
2093 if (!found)
2094 return;
2095
2096 /*
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.
2101 */
2102 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2103
2104 if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
2105
2106 len = sizeof(sin6);
2107 if (getsockname(fd, (struct sockaddr *)&sin6, &len) != 0) e(0);
2108 if (len != sizeof(sin6)) e(0);
2109
2110 ifindex2 = sin6.sin6_scope_id;
2111
2112 if (type == SOCK_STREAM) {
2113 if (listen(fd, 2) != 0) e(0);
2114
2115 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2116
2117 /* Connecting to the loopback-scope address should time out. */
2118 signal(SIGALRM, socklib_got_signal);
2119 alarm(1);
2120
2121 sin6.sin6_scope_id = ifindex;
2122
2123 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != -1)
2124 e(0);
2125
2126 if (errno != EINTR) e(0);
2127
2128 if (close(fd2) != 0) e(0);
2129
2130 /* Connecting to the real interface's address should work. */
2131 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2132
2133 sin6.sin6_scope_id = ifindex2;
2134
2135 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0)
2136 e(0);
2137
2138 if (close(fd2) != 0) e(0);
2139 } else {
2140 /*
2141 * First connect+send. Sending to the loopback-scope address
2142 * should result in a rejected packet.
2143 */
2144 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2145
2146 sin6.sin6_scope_id = ifindex;
2147
2148 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0)
2149 e(0);
2150
2151 if (send(fd2, "C", 1, 0) != -1) e(0);
2152 if (errno != EHOSTUNREACH) e(0);
2153
2154 if (close(fd2) != 0) e(0);
2155
2156 /* Sending to the real-interface address should work. */
2157 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2158
2159 sin6.sin6_scope_id = ifindex2;
2160
2161 if (connect(fd2, (struct sockaddr *)&sin6, sizeof(sin6)) != 0)
2162 e(0);
2163
2164 if (send(fd2, "D", 1, 0) != 1) e(0);
2165
2166 if (close(fd2) != 0) e(0);
2167
2168 /*
2169 * Then sendto. Sending to the loopback-scope address should
2170 * result in a rejected packet.
2171 */
2172 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2173
2174 sin6.sin6_scope_id = ifindex;
2175
2176 if (sendto(fd2, "E", 1, 0, (struct sockaddr *)&sin6,
2177 sizeof(sin6)) != -1) e(0);
2178 if (errno != EHOSTUNREACH) e(0);
2179
2180 if (close(fd2) != 0) e(0);
2181
2182 /* Sending to the real-interface address should work. */
2183 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2184
2185 sin6.sin6_scope_id = ifindex2;
2186
2187 if (sendto(fd2, "F", 1, 0, (struct sockaddr *)&sin6,
2188 sizeof(sin6)) != 1) e(0);
2189
2190 if (close(fd2) != 0) e(0);
2191
2192 len = sizeof(sin6);
2193 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6,
2194 &len) != 1) e(0);
2195 if (buf[0] != 'D') e(0);
2196
2197 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6,
2198 &len) != 1) e(0);
2199 if (buf[0] != 'F') e(0);
2200 }
2201
2202 if (close(fd) != 0) e(0);
2203 }
2204
2205 /*
2206 * Test multicast support for the given socket type, which may be SOCK_DGRAM or
2207 * SOCK_RAW.
2208 */
2209 void
socklib_test_multicast(int type,int protocol)2210 socklib_test_multicast(int type, int protocol)
2211 {
2212 struct sockaddr_in sinA, sinB, sin_array[3];
2213 struct sockaddr_in6 sin6A, sin6B, sin6_array[3];
2214 struct ip_mreq imr;
2215 struct ipv6_mreq ipv6mr;
2216 struct in6_pktinfo ipi6;
2217 struct iovec iov;
2218 struct msghdr msg;
2219 struct cmsghdr *cmsg;
2220 socklen_t len, hdrlen;
2221 unsigned int count, ifindex, ifindex2;
2222 union {
2223 struct cmsghdr cmsg;
2224 char buf[256];
2225 } control;
2226 char buf[sizeof(struct ip) + 1], *buf2, name[IF_NAMESIZE];
2227 uint8_t byte, ttl;
2228 int i, j, r, fd, fd2, val;
2229
2230 /*
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.
2237 */
2238 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2239
2240 memset(&imr, 0, sizeof(imr));
2241
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);
2245
2246 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2247 sizeof(imr)) != 0) e(0);
2248
2249 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2250 sizeof(imr)) != 0) e(0);
2251
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);
2255
2256 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2257 sizeof(imr)) != -1) e(0);
2258 if (errno != EEXIST) e(0);
2259
2260 /* If an interface address is specified, it must match an interface. */
2261 imr.imr_interface.s_addr = htonl(TEST_BLACKHOLE_IPV4);
2262
2263 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2264 sizeof(imr)) != -1) e(0);
2265 if (errno != EADDRNOTAVAIL) e(0);
2266
2267 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2268 sizeof(imr)) != -1) e(0);
2269 if (errno != EADDRNOTAVAIL) e(0);
2270
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);
2274
2275 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2276 sizeof(imr)) != -1) e(0);
2277 if (errno != EADDRNOTAVAIL) e(0);
2278
2279 imr.imr_multiaddr.s_addr = htonl(INADDR_LOOPBACK);
2280
2281 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2282 sizeof(imr)) != -1) e(0);
2283 if (errno != EADDRNOTAVAIL) e(0);
2284
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);
2288
2289 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2290 sizeof(imr)) != -1) e(0);
2291 if (errno != ESRCH) e(0);
2292
2293 /*
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.
2297 */
2298 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2299 imr.imr_interface.s_addr = htonl(INADDR_ANY);
2300
2301 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2302 sizeof(imr)) != 0) e(0);
2303
2304 /* There must be a reasonable per-socket group membership limit. */
2305 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
2306
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);
2310
2311 r = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2312 sizeof(imr));
2313
2314 if (r != 0) {
2315 if (r != -1 || errno != ENOBUFS) e(0);
2316 break;
2317 }
2318 }
2319 if (count < 8 || count > IP_MAX_MEMBERSHIPS) e(0);
2320
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);
2324
2325 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2326 sizeof(imr)) != 0) e(0);
2327
2328 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2329 sizeof(imr)) != -1) e(0);
2330 if (errno != ESRCH) e(0);
2331
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);
2335
2336 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2337 sizeof(imr)) != 0) e(0);
2338
2339 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2340 sizeof(imr)) != -1) e(0);
2341 if (errno != ESRCH) e(0);
2342
2343 /* Test leaving a group at the end of the per-socket list. */
2344 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2345
2346 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2347 sizeof(imr)) != 0) e(0);
2348
2349 if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
2350 sizeof(imr)) != -1) e(0);
2351 if (errno != ESRCH) e(0);
2352
2353 if (close(fd) != 0) e(0);
2354
2355 /* Still basic join/leave mechanics.. on to IPv6.. */
2356 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2357
2358 memset(&ipv6mr, 0, sizeof(ipv6mr));
2359
2360 /* Basic join-leave combo. */
2361 ifindex = if_nametoindex(LOOPBACK_IFNAME);
2362
2363 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2364 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2365 ipv6mr.ipv6mr_interface = ifindex;
2366
2367 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2368 sizeof(ipv6mr)) != 0) e(0);
2369
2370 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2371 sizeof(ipv6mr)) != 0) e(0);
2372
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);
2376
2377 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2378 sizeof(ipv6mr)) != -1) e(0);
2379 if (errno != EEXIST) e(0);
2380
2381 /* If an interface index is specified, it must be valid. */
2382 ipv6mr.ipv6mr_interface = BAD_IFINDEX;
2383
2384 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2385 sizeof(ipv6mr)) != -1) e(0);
2386 if (errno != ENXIO) e(0);
2387
2388 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2389 sizeof(ipv6mr)) != -1) e(0);
2390 if (errno != ENXIO) e(0);
2391
2392 ipv6mr.ipv6mr_interface = 0x80000000UL | ifindex;
2393
2394 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2395 sizeof(ipv6mr)) != -1) e(0);
2396 if (errno != ENXIO) e(0);
2397
2398 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2399 sizeof(ipv6mr)) != -1) e(0);
2400 if (errno != ENXIO) e(0);
2401
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));
2405
2406 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2407 sizeof(ipv6mr)) != -1) e(0);
2408 if (errno != EADDRNOTAVAIL) e(0);
2409
2410 memcpy(&ipv6mr.ipv6mr_multiaddr, &in6addr_loopback,
2411 sizeof(in6addr_loopback));
2412
2413 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2414 sizeof(ipv6mr)) != -1) e(0);
2415 if (errno != EADDRNOTAVAIL) e(0);
2416
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]++;
2421
2422 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2423 sizeof(ipv6mr)) != -1) e(0);
2424 if (errno != ESRCH) e(0);
2425
2426 /*
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.
2431 */
2432 ipv6mr.ipv6mr_multiaddr.s6_addr[15]--;
2433 ipv6mr.ipv6mr_interface = ifindex + 1; /* lazy: may or may not exist */
2434
2435 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2436 sizeof(ipv6mr)) != -1) e(0);
2437 if (errno != ENXIO && errno != ESRCH) e(0);
2438
2439 ipv6mr.ipv6mr_interface = 0;
2440
2441 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2442 sizeof(ipv6mr)) != 0) e(0);
2443
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;
2448
2449 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2450 sizeof(ipv6mr)) != -1) e(0);
2451 if (errno != EADDRNOTAVAIL) e(0);
2452
2453 ipv6mr.ipv6mr_interface = ifindex;
2454
2455 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2456 sizeof(ipv6mr)) != 0) e(0);
2457
2458 ipv6mr.ipv6mr_interface = 0;
2459
2460 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2461 sizeof(ipv6mr)) != -1) e(0);
2462 if (errno != EADDRNOTAVAIL) e(0);
2463
2464 ipv6mr.ipv6mr_interface = ifindex;
2465
2466 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2467 sizeof(ipv6mr)) != 0) e(0);
2468
2469 /* IPv4-mapped IPv6 multicast addresses are currently not supported. */
2470 val = 0;
2471 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) != 0)
2472 e(0);
2473
2474 if (inet_pton(AF_INET6, "::ffff:"TEST_MULTICAST_IPV4,
2475 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2476 ipv6mr.ipv6mr_interface = ifindex;
2477
2478 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2479 sizeof(ipv6mr)) != -1) e(0);
2480 if (errno != EADDRNOTAVAIL) e(0);
2481
2482 /*
2483 * There must be a reasonable per-socket group membership limit.
2484 * Apparently there is no IPv6 equivalent of IP_MAX_MEMBERSHIPS..
2485 */
2486 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2487 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2488 ipv6mr.ipv6mr_interface = ifindex;
2489
2490 for (count = 0; count < IP_MAX_MEMBERSHIPS + 1; count++) {
2491 r = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2492 sizeof(ipv6mr));
2493
2494 if (r != 0) {
2495 if (r != -1 || errno != ENOBUFS) e(0);
2496 break;
2497 }
2498
2499 ipv6mr.ipv6mr_multiaddr.s6_addr[15]++;
2500 }
2501 if (count < 8 || count > IP_MAX_MEMBERSHIPS) e(0);
2502
2503 /* Test leaving a group at the start of the per-socket list. */
2504 ipv6mr.ipv6mr_multiaddr.s6_addr[15]--;
2505
2506 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2507 sizeof(ipv6mr)) != 0) e(0);
2508
2509 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2510 sizeof(ipv6mr)) != -1) e(0);
2511 if (errno != ESRCH) e(0);
2512
2513 /* Test leaving a group in the middle of the per-socket list. */
2514 ipv6mr.ipv6mr_multiaddr.s6_addr[15] -= count / 2;
2515
2516 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2517 sizeof(ipv6mr)) != 0) e(0);
2518
2519 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2520 sizeof(ipv6mr)) != -1) e(0);
2521 if (errno != ESRCH) e(0);
2522
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);
2526
2527 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2528 sizeof(ipv6mr)) != 0) e(0);
2529
2530 if (setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
2531 sizeof(ipv6mr)) != -1) e(0);
2532 if (errno != ESRCH) e(0);
2533
2534 if (close(fd) != 0) e(0);
2535
2536 /*
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.
2540 */
2541 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2542
2543 /* For UDP, get an assigned port number. */
2544 memset(&sinA, 0, sizeof(sinA));
2545 sinA.sin_family = AF_INET;
2546
2547 if (type == SOCK_DGRAM) {
2548 sinA.sin_addr.s_addr = htonl(INADDR_ANY);
2549
2550 if (bind(fd, (struct sockaddr *)&sinA,
2551 sizeof(sinA)) != 0) e(0);
2552
2553 len = sizeof(sinA);
2554 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0) e(0);
2555 }
2556
2557 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2558 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
2559
2560 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
2561 sizeof(imr)) != 0) e(0);
2562
2563 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
2564
2565 /* Regular packet, default unicast TTL, sendto. */
2566 sinA.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2567
2568 if (sendto(fd2, "A", 1, 0, (struct sockaddr *)&sinA,
2569 sizeof(sinA)) != 1) e(0);
2570
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);
2574
2575 sinA.sin_addr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
2576
2577 if (sendto(fd2, "B", 1, 0, (struct sockaddr *)&sinA,
2578 sizeof(sinA)) != 1) e(0);
2579
2580 /* Multicast packet, custom multicast TTL, connect+send. */
2581 byte = 123;
2582 if (setsockopt(fd2, IPPROTO_IP, IP_MULTICAST_TTL, &byte,
2583 sizeof(byte)) != 0) e(0);
2584
2585 if (connect(fd2, (struct sockaddr *)&sinA, sizeof(sinA)) != 0) e(0);
2586
2587 if (send(fd2, "C", 1, 0) != 1) e(0);
2588
2589 /* Receive and validate what we sent. */
2590 len = sizeof(sinA);
2591 if (getsockname(fd2, (struct sockaddr *)&sinA, &len) != 0) e(0);
2592
2593 len = sizeof(ttl);
2594 if (getsockopt(fd2, IPPROTO_IP, IP_TTL, &ttl, &len) != 0) e(0);
2595
2596 val = 1;
2597 if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &val, sizeof(val)) != 0)
2598 e(0);
2599
2600 hdrlen = (type == SOCK_RAW) ? sizeof(struct ip) : 0;
2601
2602 memset(&iov, 0, sizeof(iov));
2603 iov.iov_base = buf;
2604 iov.iov_len = hdrlen + 1;
2605
2606 for (i = 0; i < 3; ) {
2607 memset(&msg, 0, sizeof(msg));
2608 msg.msg_name = &sinB;
2609 msg.msg_namelen = sizeof(sinB);
2610 msg.msg_iov = &iov;
2611 msg.msg_iovlen = 1;
2612 msg.msg_control = control.buf;
2613 msg.msg_controllen = sizeof(control);
2614
2615 r = recvmsg(fd, &msg, 0);
2616 if (r < 0) e(0);
2617
2618 if (msg.msg_namelen != sizeof(sinB)) e(0);
2619
2620 /*
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.
2627 */
2628 if (memcmp(&sinA, &sinB, sizeof(sinA)))
2629 continue;
2630
2631 if (r != hdrlen + 1) e(0);
2632 if (buf[hdrlen] != 'A' + i) e(0);
2633
2634 if (msg.msg_flags & MSG_BCAST) e(0);
2635
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));
2641
2642 switch (i) {
2643 case 0:
2644 if (msg.msg_flags & MSG_MCAST) e(0);
2645 if (byte != ttl) e(0);
2646 break;
2647 case 1:
2648 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2649 if (byte != 1) e(0);
2650 break;
2651 case 2:
2652 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2653 if (byte != 123) e(0);
2654 break;
2655 }
2656
2657 i++;
2658 }
2659
2660 if (close(fd2) != 0) e(0);
2661 if (close(fd) != 0) e(0);
2662
2663 /* Still the send tests, but now IPv6.. */
2664 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2665
2666 /* For UDP, get an assigned port number. */
2667 memset(&sin6A, 0, sizeof(sin6A));
2668 sin6A.sin6_family = AF_INET6;
2669
2670 if (type == SOCK_DGRAM) {
2671 if (bind(fd, (struct sockaddr *)&sin6A,
2672 sizeof(sin6A)) != 0) e(0);
2673
2674 len = sizeof(sin6A);
2675 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
2676 e(0);
2677 }
2678
2679 memcpy(&sin6B, &sin6A, sizeof(sin6B));
2680
2681 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2682 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2683 ipv6mr.ipv6mr_interface = ifindex;
2684
2685 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2686 sizeof(ipv6mr)) != 0) e(0);
2687
2688 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2689
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;
2693
2694 if (sendto(fd2, "D", 1, 0, (struct sockaddr *)&sin6A,
2695 sizeof(sin6A)) != 1) e(0);
2696
2697 /* Multicast packet, default multicast TTL, sendto. */
2698 val = (int)ifindex;
2699 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
2700 sizeof(val)) != 0) e(0);
2701
2702 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
2703 &sin6A.sin6_addr) != 1) e(0);
2704 sin6A.sin6_scope_id = 0;
2705
2706 if (sendto(fd2, "E", 1, 0, (struct sockaddr *)&sin6A,
2707 sizeof(sin6A)) != 1) e(0);
2708
2709 /* Multicast packet, custom multicast TTL, connect+send. */
2710 val = 125;
2711 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
2712 sizeof(val)) != 0) e(0);
2713
2714 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2715
2716 if (send(fd2, "F", 1, 0) != 1) e(0);
2717
2718 len = sizeof(sin6A);
2719 if (getsockname(fd2, (struct sockaddr *)&sin6A, &len) != 0) e(0);
2720
2721 /*
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.
2727 */
2728 if (close(fd2) != 0) e(0);
2729
2730 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2731
2732 if (bind(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2733
2734 memcpy(&sin6A, &sin6B, sizeof(sin6A));
2735
2736 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
2737 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
2738 ipv6mr.ipv6mr_interface = ifindex;
2739
2740 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
2741 sizeof(ipv6mr)) != 0) e(0);
2742
2743 /* Link-local multicast packet, sendto. */
2744 val = (int)ifindex;
2745 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
2746 sizeof(val)) != 0) e(0);
2747
2748 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
2749 &sin6A.sin6_addr) != 1) e(0);
2750 sin6A.sin6_scope_id = 0;
2751
2752 if (sendto(fd2, "G", 1, 0, (struct sockaddr *)&sin6A,
2753 sizeof(sin6A)) != 1) e(0);
2754
2755 sin6A.sin6_scope_id = ifindex + 1; /* lazy: may or may not be valid */
2756
2757 if (sendto(fd2, "X", 1, 0, (struct sockaddr *)&sin6A,
2758 sizeof(sin6A)) != -1) e(0);
2759 if (errno != ENXIO && errno != EHOSTUNREACH) e(0);
2760
2761 sin6A.sin6_scope_id = ifindex;
2762
2763 if (sendto(fd2, "H", 1, 0, (struct sockaddr *)&sin6A,
2764 sizeof(sin6A)) != 1) e(0);
2765
2766 /* Link-local multicast packet, connect+send. */
2767 sin6A.sin6_scope_id = 0;
2768
2769 if (connect(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
2770
2771 if (send(fd2, "I", 1, 0) != 1) e(0);
2772
2773 len = sizeof(sin6A);
2774 if (getsockname(fd2, (struct sockaddr *)&sin6A, &len) != 0) e(0);
2775
2776 /* Receive and validate what we sent. */
2777 len = sizeof(val);
2778 if (getsockopt(fd2, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
2779 &len) != 0) e(0);
2780 ttl = (uint8_t)val;
2781
2782 val = 1;
2783 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val,
2784 sizeof(val)) != 0) e(0);
2785
2786 memset(&iov, 0, sizeof(iov));
2787 iov.iov_base = buf;
2788 iov.iov_len = 1;
2789
2790 for (i = 0; i < 6; ) {
2791 memset(&msg, 0, sizeof(msg));
2792 msg.msg_name = &sin6B;
2793 msg.msg_namelen = sizeof(sin6B);
2794 msg.msg_iov = &iov;
2795 msg.msg_iovlen = 1;
2796 msg.msg_control = control.buf;
2797 msg.msg_controllen = sizeof(control);
2798
2799 r = recvmsg(fd, &msg, 0);
2800 if (r < 0) e(0);
2801
2802 if (msg.msg_namelen != sizeof(sin6B)) e(0);
2803
2804 if (memcmp(&sin6A, &sin6B, sizeof(sin6A)))
2805 continue;
2806
2807 if (r != 1) e(0);
2808 if (buf[0] != 'D' + i) e(0);
2809
2810 if (msg.msg_flags & MSG_BCAST) e(0);
2811
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));
2817
2818 switch (i) {
2819 case 0:
2820 if (msg.msg_flags & MSG_MCAST) e(0);
2821 if (val != (int)ttl) e(0);
2822 break;
2823 case 1:
2824 case 3:
2825 case 4:
2826 case 5:
2827 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2828 if (val != 1) e(0);
2829 break;
2830 case 2:
2831 if (!(msg.msg_flags & MSG_MCAST)) e(0);
2832 if (val != 125) e(0);
2833 break;
2834 }
2835
2836 i++;
2837 }
2838
2839 if (close(fd2) != 0) e(0);
2840 if (close(fd) != 0) e(0);
2841
2842 /*
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.
2846 */
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);
2855
2856 for (i = 0; i < __arraycount(sin_array); i++) {
2857 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2858
2859 if (bind(fd, (struct sockaddr *)&sin_array[i],
2860 sizeof(sin_array[i])) != 0) e(0);
2861
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);
2867
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);
2872
2873 len = sizeof(sinA);
2874 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0) e(0);
2875
2876 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
2877
2878 if (setsockopt(fd2, IPPROTO_IP, IP_MULTICAST_IF,
2879 &imr.imr_interface, sizeof(imr.imr_interface)) != 0) e(0);
2880
2881 for (j = 0; j < __arraycount(sin_array); j++) {
2882 memcpy(&sinA.sin_addr, &sin_array[j].sin_addr,
2883 sizeof(sinA.sin_addr));
2884
2885 byte = 'A' + j;
2886 if (sendto(fd2, &byte, sizeof(byte), 0,
2887 (struct sockaddr *)&sinA,
2888 sizeof(sinA)) != sizeof(byte)) e(0);
2889 }
2890
2891 if (recv(fd, buf, sizeof(buf), 0) !=
2892 hdrlen + sizeof(byte)) e(0);
2893 if (buf[hdrlen] != 'A' + i) e(0);
2894
2895 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
2896 if (errno != EWOULDBLOCK) e(0);
2897
2898 if (close(fd2) != 0) e(0);
2899 if (close(fd) != 0) e(0);
2900 }
2901
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);
2913
2914 /*
2915 * As with unicast addresses, binding to link-local multicast addresses
2916 * requires a proper zone ID.
2917 */
2918 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2919
2920 if (bind(fd, (struct sockaddr *)&sin6_array[2],
2921 sizeof(sin6_array[2])) != -1) e(0);
2922 if (errno != EADDRNOTAVAIL) e(0);
2923
2924 sin6_array[2].sin6_scope_id = BAD_IFINDEX;
2925
2926 if (bind(fd, (struct sockaddr *)&sin6_array[2],
2927 sizeof(sin6_array[2])) != -1) e(0);
2928 if (errno != ENXIO) e(0);
2929
2930 sin6_array[2].sin6_scope_id = ifindex;
2931
2932 if (close(fd) != 0) e(0);
2933
2934 for (i = 0; i < __arraycount(sin6_array); i++) {
2935 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
2936
2937 if (bind(fd, (struct sockaddr *)&sin6_array[i],
2938 sizeof(sin6_array[i])) != 0) e(0);
2939
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);
2945
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);
2950
2951 len = sizeof(sin6A);
2952 if (getsockname(fd, (struct sockaddr *)&sin6A,
2953 &len) != 0) e(0);
2954
2955 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
2956
2957 val = (int)ifindex;
2958 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
2959 sizeof(val)) != 0) e(0);
2960
2961 for (j = 0; j < __arraycount(sin6_array); j++) {
2962 memcpy(&sin6A.sin6_addr, &sin6_array[j].sin6_addr,
2963 sizeof(sin6A.sin6_addr));
2964
2965 byte = 'A' + j;
2966 if (sendto(fd2, &byte, sizeof(byte), 0,
2967 (struct sockaddr *)&sin6A,
2968 sizeof(sin6A)) != sizeof(byte)) e(0);
2969 }
2970
2971 if (recv(fd, buf, sizeof(buf), 0) != sizeof(byte)) e(0);
2972 if (buf[0] != 'A' + i) e(0);
2973
2974 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
2975 if (errno != EWOULDBLOCK) e(0);
2976
2977 if (close(fd2) != 0) e(0);
2978 if (close(fd) != 0) e(0);
2979 }
2980
2981 /*
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.
2985 */
2986 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
2987
2988 if (bind(fd, (struct sockaddr *)&sin_array[1],
2989 sizeof(sin_array[1])) != 0) e(0);
2990
2991 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
2992
2993 if (bind(fd2, (struct sockaddr *)&sin_array[0],
2994 sizeof(sin_array[0])) != 0) e(0);
2995
2996 len = sizeof(sinA);
2997 if (getsockname(fd2, (struct sockaddr *)&sinA, &len) != 0) e(0);
2998
2999 if (sendto(fd, "D", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3000 e(0);
3001
3002 len = sizeof(sinB);
3003 if (recvfrom(fd2, buf, sizeof(buf), 0, (struct sockaddr *)&sinB,
3004 &len) != hdrlen + 1) e(0);
3005 if (buf[hdrlen] != 'D') e(0);
3006
3007 if (sinB.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
3008
3009 if (close(fd2) != 0) e(0);
3010 if (close(fd) != 0) e(0);
3011
3012 /* Sending from a bound socket, IPv6 version.. */
3013 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3014
3015 if (bind(fd, (struct sockaddr *)&sin6_array[1],
3016 sizeof(sin6_array[1])) != 0) e(0);
3017
3018 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3019
3020 if (bind(fd2, (struct sockaddr *)&sin6_array[0],
3021 sizeof(sin6_array[0])) != 0) e(0);
3022
3023 len = sizeof(sin6A);
3024 if (getsockname(fd2, (struct sockaddr *)&sin6A, &len) != 0) e(0);
3025
3026 if (sendto(fd, "E", 1, 0, (struct sockaddr *)&sin6A,
3027 sizeof(sin6A)) != 1) e(0);
3028
3029 len = sizeof(sin6B);
3030 if (recvfrom(fd2, buf, sizeof(buf), 0, (struct sockaddr *)&sin6B,
3031 &len) != 1) e(0);
3032 if (buf[0] != 'E') e(0);
3033
3034 if (!IN6_IS_ADDR_LOOPBACK(&sin6B.sin6_addr)) e(0);
3035
3036 if (close(fd2) != 0) e(0);
3037 if (close(fd) != 0) e(0);
3038
3039 /*
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.
3043 */
3044 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
3045
3046 memset(&sinA, 0, sizeof(sinA));
3047 sinA.sin_family = AF_INET;
3048 sinA.sin_addr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
3049
3050 if (bind(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0) e(0);
3051
3052 len = sizeof(sinA);
3053 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0) e(0);
3054
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);
3059
3060 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
3061
3062 memset(&sinB, 0, sizeof(sinB));
3063 sinB.sin_family = AF_INET;
3064 sinB.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3065
3066 if (bind(fd2, (struct sockaddr *)&sinB, sizeof(sinB)) != 0) e(0);
3067
3068 len = sizeof(sinB);
3069 if (getsockname(fd2, (struct sockaddr *)&sinB, &len) != 0) e(0);
3070
3071 if (connect(fd, (struct sockaddr *)&sinB, sizeof(sinB)) != 0) e(0);
3072
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);
3076
3077 if (sendto(fd2, "F", 1, 0, (struct sockaddr *)&sinA,
3078 sizeof(sinA)) != 1) e(0);
3079
3080 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3081 if (buf[hdrlen] != 'F') e(0);
3082
3083 if (close(fd) != 0) e(0);
3084 if (close(fd2) != 0) e(0);
3085
3086 /* Also try connecting with IPv6. */
3087 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3088
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;
3094
3095 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
3096
3097 len = sizeof(sin6A);
3098 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0) e(0);
3099
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);
3105
3106 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3107
3108 memset(&sin6B, 0, sizeof(sin6B));
3109 sin6B.sin6_family = AF_INET6;
3110 memcpy(&sin6B.sin6_addr, &in6addr_loopback, sizeof(sin6B.sin6_addr));
3111
3112 if (bind(fd2, (struct sockaddr *)&sin6B, sizeof(sin6B)) != 0) e(0);
3113
3114 len = sizeof(sin6B);
3115 if (getsockname(fd2, (struct sockaddr *)&sin6B, &len) != 0) e(0);
3116
3117 if (connect(fd, (struct sockaddr *)&sin6B, sizeof(sin6B)) != 0) e(0);
3118
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);
3122
3123 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3124 if (buf[0] != 'G') e(0);
3125
3126 if (close(fd) != 0) e(0);
3127 if (close(fd2) != 0) e(0);
3128
3129 /*
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.
3132 */
3133 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
3134 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
3135
3136 memset(&sinA, 0, sizeof(sinA));
3137 sinA.sin_family = AF_INET;
3138
3139 if (type == SOCK_DGRAM) {
3140 if (bind(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3141 e(0);
3142
3143 len = sizeof(sinA);
3144 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0)
3145 e(0);
3146
3147 val = 1;
3148 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3149 sizeof(val)) != 0) e(0);
3150
3151 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3152 sizeof(val)) != 0) e(0);
3153
3154 if (bind(fd2, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3155 e(0);
3156 }
3157
3158 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
3159 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
3160
3161 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3162 sizeof(imr)) != 0) e(0);
3163
3164 if (setsockopt(fd2, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3165 sizeof(imr)) != 0) e(0);
3166
3167 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface,
3168 sizeof(imr.imr_interface)) != 0) e(0);
3169
3170 sinA.sin_addr.s_addr = imr.imr_multiaddr.s_addr;
3171
3172 if (sendto(fd, "H", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3173 e(0);
3174
3175 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3176 if (buf[hdrlen] != 'H') e(0);
3177
3178 if (recv(fd2, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3179 if (buf[hdrlen] != 'H') e(0);
3180
3181 /*
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.
3185 */
3186 len = 8000;
3187 if ((buf2 = malloc(hdrlen + len + 1)) == NULL) e(0);
3188 buf2[len - 1] = 'I';
3189
3190 if (sendto(fd, buf2, len, 0, (struct sockaddr *)&sinA,
3191 sizeof(sinA)) != len) e(0);
3192
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);
3196
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);
3200
3201 free(buf2);
3202
3203 if (close(fd2) != 0) e(0);
3204 if (close(fd) != 0) e(0);
3205
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);
3209
3210 memset(&sin6A, 0, sizeof(sin6A));
3211 sin6A.sin6_family = AF_INET6;
3212
3213 if (type == SOCK_DGRAM) {
3214 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3215 e(0);
3216
3217 len = sizeof(sin6A);
3218 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
3219 e(0);
3220
3221 val = 1;
3222 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3223 sizeof(val)) != 0) e(0);
3224
3225 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3226 sizeof(val)) != 0) e(0);
3227
3228 if (bind(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3229 e(0);
3230 }
3231
3232 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
3233 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
3234 ipv6mr.ipv6mr_interface = ifindex;
3235
3236 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3237 sizeof(ipv6mr)) != 0) e(0);
3238
3239 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3240 sizeof(ipv6mr)) != 0) e(0);
3241
3242 val = (int)ifindex;
3243 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3244 sizeof(val)) != 0) e(0);
3245
3246 memcpy(&sin6A.sin6_addr, &ipv6mr.ipv6mr_multiaddr,
3247 sizeof(sin6A.sin6_addr));
3248
3249 if (sendto(fd, "J", 1, 0, (struct sockaddr *)&sin6A,
3250 sizeof(sin6A)) != 1) e(0);
3251
3252 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3253 if (buf[0] != 'J') e(0);
3254
3255 if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
3256 if (buf[0] != 'J') e(0);
3257
3258 len = 8000;
3259 if ((buf2 = malloc(len + 1)) == NULL) e(0);
3260 buf2[len - 1] = 'K';
3261
3262 if (sendto(fd, buf2, len, 0, (struct sockaddr *)&sin6A,
3263 sizeof(sin6A)) != len) e(0);
3264
3265 buf2[len - 1] = '\0';
3266 if (recv(fd, buf2, len + 1, 0) != len) e(0);
3267 if (buf2[len - 1] != 'K') e(0);
3268
3269 buf2[len - 1] = '\0';
3270 if (recv(fd2, buf2, len + 1, 0) != len) e(0);
3271 if (buf2[len - 1] != 'K') e(0);
3272
3273 free(buf2);
3274
3275 if (close(fd2) != 0) e(0);
3276 if (close(fd) != 0) e(0);
3277
3278 /*
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.
3285 */
3286 if ((fd = socket(AF_INET, type, protocol)) < 0) e(0);
3287 if ((fd2 = socket(AF_INET, type, protocol)) < 0) e(0);
3288
3289 memset(&sinA, 0, sizeof(sinA));
3290 sinA.sin_family = AF_INET;
3291
3292 if (type == SOCK_DGRAM) {
3293 if (bind(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3294 e(0);
3295
3296 len = sizeof(sinA);
3297 if (getsockname(fd, (struct sockaddr *)&sinA, &len) != 0)
3298 e(0);
3299
3300 val = 1;
3301 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3302 sizeof(val)) != 0) e(0);
3303
3304 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3305 sizeof(val)) != 0) e(0);
3306
3307 if (bind(fd2, (struct sockaddr *)&sinA, sizeof(sinA)) != 0)
3308 e(0);
3309 }
3310
3311 imr.imr_multiaddr.s_addr = inet_addr(TEST_MULTICAST_IPV4);
3312 imr.imr_interface.s_addr = htonl(INADDR_LOOPBACK);
3313
3314 if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3315 sizeof(imr)) != 0) e(0);
3316
3317 imr.imr_multiaddr.s_addr = htonl(ntohl(imr.imr_multiaddr.s_addr) + 1);
3318
3319 if (setsockopt(fd2, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3320 sizeof(imr)) != 0) e(0);
3321
3322 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface,
3323 sizeof(imr.imr_interface)) != 0) e(0);
3324
3325 sinA.sin_addr.s_addr = imr.imr_multiaddr.s_addr;
3326
3327 if (sendto(fd, "L", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3328 e(0);
3329
3330 if (recv(fd2, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3331 if (buf[hdrlen] != 'L') e(0);
3332
3333 if (setsockopt(fd2, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr,
3334 sizeof(imr)) != 0) e(0);
3335
3336 if (sendto(fd, "M", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3337 e(0);
3338
3339 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3340 if (buf[hdrlen] != 'L') e(0);
3341
3342 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3343 if (errno != EWOULDBLOCK) e(0);
3344
3345 if (setsockopt(fd2, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr,
3346 sizeof(imr)) != 0) e(0);
3347
3348 if (sendto(fd, "N", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3349 e(0);
3350
3351 if (recv(fd2, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3352 if (buf[hdrlen] != 'N') e(0);
3353
3354 if (close(fd2) != 0) e(0);
3355
3356 if (sendto(fd, "O", 1, 0, (struct sockaddr *)&sinA, sizeof(sinA)) != 1)
3357 e(0);
3358
3359 if (recv(fd, buf, sizeof(buf), 0) != hdrlen + 1) e(0);
3360 if (buf[hdrlen] != 'N') e(0);
3361
3362 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3363 if (errno != EWOULDBLOCK) e(0);
3364
3365 if (close(fd) != 0) e(0);
3366
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);
3370
3371 memset(&sin6A, 0, sizeof(sin6A));
3372 sin6A.sin6_family = AF_INET6;
3373
3374 if (type == SOCK_DGRAM) {
3375 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3376 e(0);
3377
3378 len = sizeof(sin6A);
3379 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
3380 e(0);
3381
3382 val = 1;
3383 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
3384 sizeof(val)) != 0) e(0);
3385
3386 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &val,
3387 sizeof(val)) != 0) e(0);
3388
3389 if (bind(fd2, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3390 e(0);
3391 }
3392
3393 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6,
3394 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
3395 ipv6mr.ipv6mr_interface = ifindex;
3396
3397 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3398 sizeof(ipv6mr)) != 0) e(0);
3399
3400 ipv6mr.ipv6mr_multiaddr.s6_addr[15]++;
3401
3402 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3403 sizeof(ipv6mr)) != 0) e(0);
3404
3405 val = (int)ifindex;
3406 if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3407 sizeof(val)) != 0) e(0);
3408
3409 memcpy(&sin6A.sin6_addr, &ipv6mr.ipv6mr_multiaddr,
3410 sizeof(sin6A.sin6_addr));
3411
3412 if (sendto(fd, "P", 1, 0, (struct sockaddr *)&sin6A,
3413 sizeof(sin6A)) != 1) e(0);
3414
3415 if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
3416 if (buf[0] != 'P') e(0);
3417
3418 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &ipv6mr,
3419 sizeof(ipv6mr)) != 0) e(0);
3420
3421 if (sendto(fd, "Q", 1, 0, (struct sockaddr *)&sin6A,
3422 sizeof(sin6A)) != 1) e(0);
3423
3424 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3425 if (buf[0] != 'P') e(0);
3426
3427 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3428 if (errno != EWOULDBLOCK) e(0);
3429
3430 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3431 sizeof(ipv6mr)) != 0) e(0);
3432
3433 if (sendto(fd, "R", 1, 0, (struct sockaddr *)&sin6A,
3434 sizeof(sin6A)) != 1) e(0);
3435
3436 if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
3437 if (buf[0] != 'R') e(0);
3438
3439 if (close(fd2) != 0) e(0);
3440
3441 if (sendto(fd, "S", 1, 0, (struct sockaddr *)&sin6A,
3442 sizeof(sin6A)) != 1) e(0);
3443
3444 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
3445 if (buf[0] != 'R') e(0);
3446
3447 if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
3448 if (errno != EWOULDBLOCK) e(0);
3449
3450 if (close(fd) != 0) e(0);
3451
3452 /*
3453 * Lastly, some IPv6-only tests.
3454 */
3455 /*
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.
3459 */
3460 for (ifindex2 = 1; ifindex2 < BAD_IFINDEX; ifindex2++) {
3461 if (if_indextoname(ifindex2, name) == NULL) {
3462 if (errno != ENXIO) e(0);
3463 continue;
3464 }
3465
3466 if (strcmp(name, LOOPBACK_IFNAME))
3467 break;
3468 }
3469
3470 if (ifindex2 == BAD_IFINDEX)
3471 ifindex2 = 0; /* too bad; fallback mode */
3472
3473 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3474
3475 memset(&sin6A, 0, sizeof(sin6A));
3476 sin6A.sin6_family = AF_INET6;
3477
3478 if (type == SOCK_DGRAM) {
3479 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0)
3480 e(0);
3481
3482 len = sizeof(sin6A);
3483 if (getsockname(fd, (struct sockaddr *)&sin6A, &len) != 0)
3484 e(0);
3485 }
3486
3487 if (inet_pton(AF_INET6, TEST_MULTICAST_IPV6_LL,
3488 &ipv6mr.ipv6mr_multiaddr) != 1) e(0);
3489 ipv6mr.ipv6mr_interface = ifindex;
3490
3491 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3492 sizeof(ipv6mr)) != 0) e(0);
3493
3494 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3495
3496 memcpy(&sin6A.sin6_addr, &ipv6mr.ipv6mr_multiaddr,
3497 sizeof(sin6A.sin6_addr));
3498
3499 val = (int)ifindex2;
3500 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3501 sizeof(val)) != 0) e(0);
3502
3503 memset(&iov, 0, sizeof(iov));
3504 iov.iov_base = "T";
3505 iov.iov_len = 1;
3506
3507 memset(&ipi6, 0, sizeof(ipi6));
3508 memcpy(&ipi6.ipi6_addr, &in6addr_loopback, sizeof(ipi6.ipi6_addr));
3509 ipi6.ipi6_ifindex = ifindex;
3510
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));
3515
3516 memset(&msg, 0, sizeof(msg));
3517 msg.msg_name = &sin6A;
3518 msg.msg_namelen = sizeof(sin6A);
3519 msg.msg_iov = &iov;
3520 msg.msg_iovlen = 1;
3521 msg.msg_control = control.buf;
3522 msg.msg_controllen = control.cmsg.cmsg_len;
3523
3524 if (sendmsg(fd2, &msg, 0) != 1) e(0);
3525
3526 len = sizeof(sin6B);
3527 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6B,
3528 &len) != 1) e(0);
3529 if (buf[0] != 'T') e(0);
3530
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);
3536
3537 if (close(fd2) != 0) e(0);
3538
3539 /* Repeat the same test, but now with a sticky IPV6_PKTINFO setting. */
3540 if ((fd2 = socket(AF_INET6, type, protocol)) < 0) e(0);
3541
3542 memset(&ipi6, 0, sizeof(ipi6));
3543 memcpy(&ipi6.ipi6_addr, &in6addr_loopback, sizeof(ipi6.ipi6_addr));
3544 ipi6.ipi6_ifindex = ifindex;
3545
3546 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_PKTINFO, &ipi6,
3547 sizeof(ipi6)) != 0) e(0);
3548
3549 val = (int)ifindex2;
3550 if (setsockopt(fd2, IPPROTO_IPV6, IPV6_MULTICAST_IF, &val,
3551 sizeof(val)) != 0) e(0);
3552
3553 if (sendto(fd2, "U", 1, 0, (struct sockaddr *)&sin6A,
3554 sizeof(sin6A)) != 1) e(0);
3555
3556 len = sizeof(sin6B);
3557 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6B,
3558 &len) != 1) e(0);
3559 if (buf[0] != 'U') e(0);
3560
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);
3566
3567 if (close(fd2) != 0) e(0);
3568 if (close(fd) != 0) e(0);
3569
3570 /*
3571 * Test that invalid multicast addresses are not accepted anywhere.
3572 */
3573 if ((fd = socket(AF_INET6, type, protocol)) < 0) e(0);
3574
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);
3579
3580 if (bind(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != -1) e(0);
3581 if (errno != EINVAL) e(0);
3582
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);
3586
3587 if (sendto(fd, "X", 1, 0, (struct sockaddr *)&sin6A,
3588 sizeof(sin6A)) != -1) e(0);
3589 if (errno != EINVAL) e(0);
3590
3591 memcpy(&ipv6mr.ipv6mr_multiaddr, &sin6A.sin6_addr,
3592 sizeof(ipv6mr.ipv6mr_multiaddr));
3593 ipv6mr.ipv6mr_interface = ifindex;
3594
3595 if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &ipv6mr,
3596 sizeof(ipv6mr)) != -1) e(0);
3597 if (errno != EINVAL) e(0);
3598
3599 if (close(fd) != 0) e(0);
3600 }
3601