xref: /xnu-12377.1.9/tests/mcast_ssm.c (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1 /*
2  * Copyright (c) 2025 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #include <darwintest.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 
33 #include "net_test_lib.h"
34 
35 network_interface interface;
36 
37 static void
cleanup(void)38 cleanup(void)
39 {
40 	network_interface_destroy(&interface);
41 }
42 
43 T_DECL(net_multicast_igmp_ssm, "IGMP SSM test", T_META_ASROOT(true))
44 {
45 	int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
46 
47 	T_ATEND(cleanup);
48 	network_interface_create(&interface, FETH_NAME);
49 	struct in_addr addr;
50 	addr.s_addr = inet_addr("192.168.55.1");
51 	struct in_addr mask;
52 	mask.s_addr = inet_addr("255.255.255.0");
53 	ifnet_add_ip_address(interface.if_name, addr, mask);
54 
55 	struct ip_mreq_source mr = {};
56 	mr.imr_sourceaddr.s_addr = inet_addr("192.168.55.2");
57 	mr.imr_multiaddr.s_addr = inet_addr("239.1.2.3");
58 	mr.imr_interface.s_addr = INADDR_ANY;
59 
60 	for (int i = 0; i < 20; i++) {
61 		mr.imr_sourceaddr.s_addr += i;
62 		T_ASSERT_POSIX_SUCCESS(setsockopt(s, IPPROTO_IP,
63 		    IP_ADD_SOURCE_MEMBERSHIP, &mr,
64 		    sizeof(mr)),
65 		    "IP_ADD_SOURCE_MEMBERSHIP");
66 	}
67 	close(s);
68 }
69 
70 T_DECL(net_multicast_mld_ssm, "MLD SSM test", T_META_ASROOT(true))
71 {
72 	int s6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
73 
74 	T_ATEND(cleanup);
75 	network_interface_create(&interface, FETH_NAME);
76 	ifnet_start_ipv6(interface.if_name);
77 
78 	struct sockaddr_storage group_storage = {}, source_storage = {};
79 
80 	struct sockaddr_in6 *group = (struct sockaddr_in6 *)&group_storage;
81 
82 	group->sin6_family = AF_INET6;
83 	group->sin6_len = sizeof(*group);
84 	char address[128] = {};
85 	snprintf(address, sizeof(address), "ff02::1234%%%s", interface.if_name);
86 	inet_pton(AF_INET6, address, &group->sin6_addr);
87 
88 	struct sockaddr_in6 *source = (struct sockaddr_in6 *)&source_storage;
89 	source->sin6_family = AF_INET6;
90 	source->sin6_len = sizeof(*source);
91 	inet_pton(AF_INET6, "2001:db8::1", &source->sin6_addr);
92 
93 	struct group_source_req gr = {};
94 	gr.gsr_interface = interface.if_index;
95 	gr.gsr_group = group_storage;
96 	gr.gsr_source = source_storage;
97 
98 	for (int i = 0; i < 20; i++) {
99 		((struct sockaddr_in6 *)&gr.gsr_source)->sin6_addr.__u6_addr.__u6_addr8[15] += i;
100 		T_ASSERT_POSIX_SUCCESS(setsockopt(s6, IPPROTO_IPV6,
101 		    MCAST_JOIN_SOURCE_GROUP, &gr,
102 		    sizeof(gr)),
103 		    "MCAST_JOIN_SOURCE_GROUP");
104 	}
105 }
106