xref: /xnu-8019.80.24/tests/ipsec.m (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
1*a325d9c4SApple OSS Distributions#import <darwintest.h>
2*a325d9c4SApple OSS Distributions#import <darwintest_utils.h>
3*a325d9c4SApple OSS Distributions#import <dispatch/dispatch.h>
4*a325d9c4SApple OSS Distributions#import <net/pfkeyv2.h>
5*a325d9c4SApple OSS Distributions#import <netinet6/ipsec.h>
6*a325d9c4SApple OSS Distributions#import <arpa/inet.h>
7*a325d9c4SApple OSS Distributions#import <NetworkExtension/NetworkExtensionPrivate.h>
8*a325d9c4SApple OSS Distributions#import <System/net/bpf.h>
9*a325d9c4SApple OSS Distributions#import <System/netinet/ip.h>
10*a325d9c4SApple OSS Distributions#import <System/netinet/ip6.h>
11*a325d9c4SApple OSS Distributions
12*a325d9c4SApple OSS DistributionsT_GLOBAL_META(
13*a325d9c4SApple OSS Distributions	T_META_NAMESPACE("xnu.ipsec"),
14*a325d9c4SApple OSS Distributions	T_META_ASROOT(true),
15*a325d9c4SApple OSS Distributions	T_META_CHECK_LEAKS(false));
16*a325d9c4SApple OSS Distributions
17*a325d9c4SApple OSS Distributionstypedef enum {
18*a325d9c4SApple OSS Distributions	TEST_INVALID = 0,
19*a325d9c4SApple OSS Distributions	TEST_IPSEC_IPv4_ENCAPSULATE_PANIC = 1,
20*a325d9c4SApple OSS Distributions	TEST_IPSEC_IPv6_ENCAPSULATE_PANIC = 2,
21*a325d9c4SApple OSS Distributions} test_identifier;
22*a325d9c4SApple OSS Distributions
23*a325d9c4SApple OSS Distributions#define TEST_SRC_ADDRESS_IPv4                           "10.0.0.2"
24*a325d9c4SApple OSS Distributions#define TEST_DST_ADDRESS_IPv4                           "10.0.0.3"
25*a325d9c4SApple OSS Distributions#define TEST_IPSEC_IPv4_INTERFACE_ADDRESS               "192.168.10.10"
26*a325d9c4SApple OSS Distributions#define TEST_IPSEC_IPv6_INTERFACE_ADDRESS               "fdd3:0f89:9afd:9b9c::1234"
27*a325d9c4SApple OSS Distributions#define TEST_DELEGATE_IPSEC_INTERFACE_ADDRESS           "192.168.20.10"
28*a325d9c4SApple OSS Distributions#define TEST_IPSEC_IPv4_INTERFACE_MASK                  "255.255.255.255"
29*a325d9c4SApple OSS Distributions#define TEST_IPSEC_IPv6_INTERFACE_MASK                  "ffff:ffff:ffff:ffff::"
30*a325d9c4SApple OSS Distributions
31*a325d9c4SApple OSS Distributionsstatic test_identifier test_id = TEST_INVALID;
32*a325d9c4SApple OSS Distributionsstatic dispatch_source_t pfkey_source = NULL;
33*a325d9c4SApple OSS Distributionsstatic NEVirtualInterfaceRef ipsecInterface = NULL;
34*a325d9c4SApple OSS Distributionsstatic NEVirtualInterfaceRef delegateIPsecInterface = NULL;
35*a325d9c4SApple OSS Distributionsstatic int bpf_fd = -1;
36*a325d9c4SApple OSS Distributions
37*a325d9c4SApple OSS Distributionsstatic void bpf_write(int fd);
38*a325d9c4SApple OSS Distributionsstatic void pfkey_cleanup(void);
39*a325d9c4SApple OSS Distributionsstatic void pfkey_process_message_test_encapsulate_panic(uint8_t **mhp, int pfkey_socket);
40*a325d9c4SApple OSS Distributions
41*a325d9c4SApple OSS Distributionsstatic void(*const process_pfkey_message_tests[])(uint8_t * *mhp, int pfkey_socket) =
42*a325d9c4SApple OSS Distributions{
43*a325d9c4SApple OSS Distributions	NULL,
44*a325d9c4SApple OSS Distributions	pfkey_process_message_test_encapsulate_panic,    // TEST_IPSEC_IPv4_ENCAPSULATE_PANIC
45*a325d9c4SApple OSS Distributions	pfkey_process_message_test_encapsulate_panic,    // TEST_IPSEC_IPv6_ENCAPSULATE_PANIC
46*a325d9c4SApple OSS Distributions};
47*a325d9c4SApple OSS Distributions
48*a325d9c4SApple OSS Distributionsstatic void
49*a325d9c4SApple OSS Distributionssend_pkey_add_sa(int pfkey_socket, uint32_t spi, const char *src, const char *dst, int family)
50*a325d9c4SApple OSS Distributions{
51*a325d9c4SApple OSS Distributions	uint8_t payload[MCLBYTES] __attribute__ ((aligned(32)));
52*a325d9c4SApple OSS Distributions	bzero(payload, sizeof(payload));
53*a325d9c4SApple OSS Distributions	uint16_t tlen = 0;
54*a325d9c4SApple OSS Distributions
55*a325d9c4SApple OSS Distributions	struct sadb_msg *msg_payload = (struct sadb_msg *)payload;
56*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_version = PF_KEY_V2;
57*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_type = SADB_ADD;
58*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_errno = 0;
59*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_satype = SADB_SATYPE_ESP;
60*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen);
61*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_reserved = 0;
62*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_seq = 0;
63*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_pid = (u_int32_t)getpid();
64*a325d9c4SApple OSS Distributions	tlen += sizeof(*msg_payload);
65*a325d9c4SApple OSS Distributions
66*a325d9c4SApple OSS Distributions	struct sadb_sa_2 *sa2_payload = (struct sadb_sa_2 *)(void *)(payload + tlen);
67*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_len = PFKEY_UNIT64(sizeof(*sa2_payload));
68*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_exttype = SADB_EXT_SA;
69*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_spi = htonl(spi);
70*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_replay = 4;
71*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_state = SADB_SASTATE_LARVAL;
72*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_auth = SADB_X_AALG_SHA2_256;
73*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_encrypt = SADB_X_EALG_AESCBC;
74*a325d9c4SApple OSS Distributions	sa2_payload->sa.sadb_sa_flags |= (SADB_X_EXT_NATT | SADB_X_EXT_NATT_KEEPALIVE);
75*a325d9c4SApple OSS Distributions	sa2_payload->sadb_sa_natt_src_port = htons(4500);
76*a325d9c4SApple OSS Distributions	sa2_payload->sadb_sa_natt_port = 4500;
77*a325d9c4SApple OSS Distributions	sa2_payload->sadb_sa_natt_interval = 20;
78*a325d9c4SApple OSS Distributions	sa2_payload->sadb_sa_natt_offload_interval = 0;
79*a325d9c4SApple OSS Distributions	tlen += sizeof(*sa2_payload);
80*a325d9c4SApple OSS Distributions
81*a325d9c4SApple OSS Distributions	struct sadb_x_sa2 *sa2_x_payload = (struct sadb_x_sa2 *)(void *)(payload + tlen);
82*a325d9c4SApple OSS Distributions	sa2_x_payload->sadb_x_sa2_len = PFKEY_UNIT64(sizeof(*sa2_x_payload));
83*a325d9c4SApple OSS Distributions	sa2_x_payload->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
84*a325d9c4SApple OSS Distributions	sa2_x_payload->sadb_x_sa2_mode = IPSEC_MODE_TUNNEL;
85*a325d9c4SApple OSS Distributions	sa2_x_payload->sadb_x_sa2_reqid = 0;
86*a325d9c4SApple OSS Distributions	tlen += sizeof(*sa2_x_payload);
87*a325d9c4SApple OSS Distributions
88*a325d9c4SApple OSS Distributions	uint8_t prefixlen = (family == AF_INET) ? (sizeof(struct in_addr) << 3) : (sizeof(struct in6_addr) << 3);
89*a325d9c4SApple OSS Distributions
90*a325d9c4SApple OSS Distributions	struct sadb_address *src_address_payload = (struct sadb_address *)(void *)(payload + tlen);
91*a325d9c4SApple OSS Distributions	src_address_payload->sadb_address_exttype = SADB_EXT_ADDRESS_SRC & 0xffff;
92*a325d9c4SApple OSS Distributions	src_address_payload->sadb_address_proto = IPSEC_ULPROTO_ANY & 0xff;
93*a325d9c4SApple OSS Distributions	src_address_payload->sadb_address_prefixlen = prefixlen;
94*a325d9c4SApple OSS Distributions	src_address_payload->sadb_address_reserved = 0;
95*a325d9c4SApple OSS Distributions	tlen += sizeof(*src_address_payload);
96*a325d9c4SApple OSS Distributions
97*a325d9c4SApple OSS Distributions	if (family == AF_INET) {
98*a325d9c4SApple OSS Distributions		struct sockaddr_in *src4 = (struct sockaddr_in *)(void *)(payload + tlen);
99*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET, src, &src4->sin_addr), 1, "src address fail");
100*a325d9c4SApple OSS Distributions		src4->sin_family = AF_INET;
101*a325d9c4SApple OSS Distributions		src4->sin_len = sizeof(*src4);
102*a325d9c4SApple OSS Distributions		uint16_t len = sizeof(*src_address_payload) + PFKEY_ALIGN8(src4->sin_len);
103*a325d9c4SApple OSS Distributions		src_address_payload->sadb_address_len = PFKEY_UNIT64(len);
104*a325d9c4SApple OSS Distributions		tlen += PFKEY_ALIGN8(src4->sin_len);
105*a325d9c4SApple OSS Distributions	} else {
106*a325d9c4SApple OSS Distributions		struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)(void *)(payload + tlen);
107*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET6, src, &src6->sin6_addr), 1, "src address fail");
108*a325d9c4SApple OSS Distributions		src6->sin6_family = AF_INET6;
109*a325d9c4SApple OSS Distributions		src6->sin6_len = sizeof(*src6);
110*a325d9c4SApple OSS Distributions		uint16_t len = sizeof(*src_address_payload) + PFKEY_ALIGN8(src6->sin6_len);
111*a325d9c4SApple OSS Distributions		src_address_payload->sadb_address_len = PFKEY_UNIT64(len);
112*a325d9c4SApple OSS Distributions		tlen += PFKEY_ALIGN8(src6->sin6_len);
113*a325d9c4SApple OSS Distributions	}
114*a325d9c4SApple OSS Distributions
115*a325d9c4SApple OSS Distributions	struct sadb_address *dst_address_payload = (struct sadb_address *)(void *)(payload + tlen);
116*a325d9c4SApple OSS Distributions	dst_address_payload->sadb_address_exttype = SADB_EXT_ADDRESS_DST & 0xffff;
117*a325d9c4SApple OSS Distributions	dst_address_payload->sadb_address_proto = IPSEC_ULPROTO_ANY & 0xff;
118*a325d9c4SApple OSS Distributions	dst_address_payload->sadb_address_prefixlen = prefixlen;
119*a325d9c4SApple OSS Distributions	dst_address_payload->sadb_address_reserved = 0;
120*a325d9c4SApple OSS Distributions	tlen += sizeof(*dst_address_payload);
121*a325d9c4SApple OSS Distributions
122*a325d9c4SApple OSS Distributions	if (family == AF_INET) {
123*a325d9c4SApple OSS Distributions		struct sockaddr_in *dst4 = (struct sockaddr_in *)(void *)(payload + tlen);
124*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET, dst, &dst4->sin_addr), 1, "dst address fail");
125*a325d9c4SApple OSS Distributions		dst4->sin_family = AF_INET;
126*a325d9c4SApple OSS Distributions		dst4->sin_len = sizeof(*dst4);
127*a325d9c4SApple OSS Distributions		uint16_t len = sizeof(*dst_address_payload) + PFKEY_ALIGN8(dst4->sin_len);
128*a325d9c4SApple OSS Distributions		dst_address_payload->sadb_address_len = PFKEY_UNIT64(len);
129*a325d9c4SApple OSS Distributions		tlen += PFKEY_ALIGN8(dst4->sin_len);
130*a325d9c4SApple OSS Distributions	} else {
131*a325d9c4SApple OSS Distributions		struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)(void *)(payload + tlen);
132*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET6, dst, &dst6->sin6_addr), 1, "dst address fail");
133*a325d9c4SApple OSS Distributions		dst6->sin6_family = AF_INET6;
134*a325d9c4SApple OSS Distributions		dst6->sin6_len = sizeof(*dst6);
135*a325d9c4SApple OSS Distributions		uint16_t len = sizeof(*dst_address_payload) + PFKEY_ALIGN8(dst6->sin6_len);
136*a325d9c4SApple OSS Distributions		dst_address_payload->sadb_address_len = PFKEY_UNIT64(len);
137*a325d9c4SApple OSS Distributions		tlen += PFKEY_ALIGN8(dst6->sin6_len);
138*a325d9c4SApple OSS Distributions	}
139*a325d9c4SApple OSS Distributions
140*a325d9c4SApple OSS Distributions	CFStringRef ipsecIfName = NEVirtualInterfaceCopyName(ipsecInterface);
141*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(ipsecIfName, "failed to get ipsec interface name");
142*a325d9c4SApple OSS Distributions	char ifname[IFNAMSIZ];
143*a325d9c4SApple OSS Distributions	CFStringGetCString(ipsecIfName, ifname, IFNAMSIZ, kCFStringEncodingUTF8);
144*a325d9c4SApple OSS Distributions
145*a325d9c4SApple OSS Distributions	CFStringRef delegateIPsecIfName = NEVirtualInterfaceCopyName(delegateIPsecInterface);
146*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(delegateIPsecIfName, "failed to get delegate ipsec interface name");
147*a325d9c4SApple OSS Distributions	char delegateIfname[IFNAMSIZ];
148*a325d9c4SApple OSS Distributions	CFStringGetCString(delegateIPsecIfName, delegateIfname, IFNAMSIZ, kCFStringEncodingUTF8);
149*a325d9c4SApple OSS Distributions
150*a325d9c4SApple OSS Distributions	struct sadb_x_ipsecif *ipsec_if_payload = (struct sadb_x_ipsecif *)(void *)(payload + tlen);
151*a325d9c4SApple OSS Distributions	ipsec_if_payload->sadb_x_ipsecif_len = PFKEY_UNIT64(sizeof(*ipsec_if_payload));
152*a325d9c4SApple OSS Distributions	ipsec_if_payload->sadb_x_ipsecif_exttype = SADB_X_EXT_IPSECIF;
153*a325d9c4SApple OSS Distributions	strncpy(ipsec_if_payload->sadb_x_ipsecif_ipsec_if, ifname, strlen(ifname));
154*a325d9c4SApple OSS Distributions	strncpy(ipsec_if_payload->sadb_x_ipsecif_outgoing_if, delegateIfname, strlen(delegateIfname));
155*a325d9c4SApple OSS Distributions	tlen += sizeof(*ipsec_if_payload);
156*a325d9c4SApple OSS Distributions
157*a325d9c4SApple OSS Distributions	struct sadb_key *encrypt_key_payload = (struct sadb_key *)(void *)(payload + tlen);
158*a325d9c4SApple OSS Distributions	uint16_t len = sizeof(*encrypt_key_payload) + PFKEY_ALIGN8(32);
159*a325d9c4SApple OSS Distributions	encrypt_key_payload->sadb_key_len = PFKEY_UNIT64(len);
160*a325d9c4SApple OSS Distributions	encrypt_key_payload->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
161*a325d9c4SApple OSS Distributions	encrypt_key_payload->sadb_key_bits = (uint16_t)(32 << 3);
162*a325d9c4SApple OSS Distributions	encrypt_key_payload->sadb_key_reserved = 0;
163*a325d9c4SApple OSS Distributions	tlen += sizeof(*encrypt_key_payload);
164*a325d9c4SApple OSS Distributions	arc4random_buf(payload + tlen, 32);
165*a325d9c4SApple OSS Distributions	tlen += PFKEY_ALIGN8(32);
166*a325d9c4SApple OSS Distributions
167*a325d9c4SApple OSS Distributions	struct sadb_key *auth_key_payload = (struct sadb_key *)(void *)(payload + tlen);
168*a325d9c4SApple OSS Distributions	len = sizeof(*auth_key_payload) + PFKEY_ALIGN8(32);
169*a325d9c4SApple OSS Distributions	auth_key_payload->sadb_key_len = PFKEY_UNIT64(len);
170*a325d9c4SApple OSS Distributions	auth_key_payload->sadb_key_exttype = SADB_EXT_KEY_AUTH;
171*a325d9c4SApple OSS Distributions	auth_key_payload->sadb_key_bits = (uint16_t)(32 << 3);
172*a325d9c4SApple OSS Distributions	auth_key_payload->sadb_key_reserved = 0;
173*a325d9c4SApple OSS Distributions	tlen += sizeof(*auth_key_payload);
174*a325d9c4SApple OSS Distributions	arc4random_buf(payload + tlen, 32);
175*a325d9c4SApple OSS Distributions	tlen += PFKEY_ALIGN8(32);
176*a325d9c4SApple OSS Distributions
177*a325d9c4SApple OSS Distributions	struct sadb_lifetime *hard_lifetime_payload = (struct sadb_lifetime *)(void *)(payload + tlen);
178*a325d9c4SApple OSS Distributions	hard_lifetime_payload->sadb_lifetime_len = PFKEY_UNIT64(sizeof(*hard_lifetime_payload));
179*a325d9c4SApple OSS Distributions	hard_lifetime_payload->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
180*a325d9c4SApple OSS Distributions	tlen += sizeof(*hard_lifetime_payload);
181*a325d9c4SApple OSS Distributions
182*a325d9c4SApple OSS Distributions	struct sadb_lifetime *soft_lifetime_payload = (struct sadb_lifetime *)(void *)(payload + tlen);
183*a325d9c4SApple OSS Distributions	soft_lifetime_payload->sadb_lifetime_len = PFKEY_UNIT64(sizeof(*soft_lifetime_payload));
184*a325d9c4SApple OSS Distributions	soft_lifetime_payload->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
185*a325d9c4SApple OSS Distributions	tlen += sizeof(*soft_lifetime_payload);
186*a325d9c4SApple OSS Distributions
187*a325d9c4SApple OSS Distributions	// Update the total length
188*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen);
189*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_POSIX_SUCCESS(send(pfkey_socket, payload, (size_t)PFKEY_UNUNIT64(msg_payload->sadb_msg_len), 0), "pfkey send update sa");
190*a325d9c4SApple OSS Distributions}
191*a325d9c4SApple OSS Distributions
192*a325d9c4SApple OSS Distributionsstatic void
193*a325d9c4SApple OSS Distributionssend_pfkey_flush_sa(int pfkey_socket)
194*a325d9c4SApple OSS Distributions{
195*a325d9c4SApple OSS Distributions	uint8_t payload[MCLBYTES] __attribute__ ((aligned(32)));
196*a325d9c4SApple OSS Distributions	bzero(payload, sizeof(payload));
197*a325d9c4SApple OSS Distributions	uint16_t tlen = 0;
198*a325d9c4SApple OSS Distributions
199*a325d9c4SApple OSS Distributions	struct sadb_msg *msg_payload = (struct sadb_msg *)payload;
200*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_version = PF_KEY_V2;
201*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_type = SADB_FLUSH;
202*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_errno = 0;
203*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_satype = SADB_SATYPE_UNSPEC;
204*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen);
205*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_reserved = 0;
206*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_seq = 0;
207*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_pid = (u_int32_t)getpid();
208*a325d9c4SApple OSS Distributions	tlen += sizeof(*msg_payload);
209*a325d9c4SApple OSS Distributions
210*a325d9c4SApple OSS Distributions	// Update the total length
211*a325d9c4SApple OSS Distributions	msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen);
212*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_POSIX_SUCCESS(send(pfkey_socket, payload, (size_t)PFKEY_UNUNIT64(msg_payload->sadb_msg_len), 0), "pfkey flush sa");
213*a325d9c4SApple OSS Distributions}
214*a325d9c4SApple OSS Distributions
215*a325d9c4SApple OSS Distributionsstatic void
216*a325d9c4SApple OSS Distributionspfkey_cleanup(void)
217*a325d9c4SApple OSS Distributions{
218*a325d9c4SApple OSS Distributions	if (pfkey_source != NULL) {
219*a325d9c4SApple OSS Distributions		int pfkey_socket = (int)dispatch_source_get_handle(pfkey_source);
220*a325d9c4SApple OSS Distributions		if (pfkey_socket > 0) {
221*a325d9c4SApple OSS Distributions			send_pfkey_flush_sa(pfkey_socket);
222*a325d9c4SApple OSS Distributions		}
223*a325d9c4SApple OSS Distributions		dispatch_source_cancel(pfkey_source);
224*a325d9c4SApple OSS Distributions		pfkey_source = NULL;
225*a325d9c4SApple OSS Distributions	}
226*a325d9c4SApple OSS Distributions}
227*a325d9c4SApple OSS Distributions
228*a325d9c4SApple OSS Distributionsstatic void
229*a325d9c4SApple OSS Distributionspfkey_align(struct sadb_msg *msg, uint8_t **mhp)
230*a325d9c4SApple OSS Distributions{
231*a325d9c4SApple OSS Distributions	struct sadb_ext *ext;
232*a325d9c4SApple OSS Distributions	int i;
233*a325d9c4SApple OSS Distributions	uint8_t *p;
234*a325d9c4SApple OSS Distributions	uint8_t *ep;     /* XXX should be passed from upper layer */
235*a325d9c4SApple OSS Distributions
236*a325d9c4SApple OSS Distributions	/* validity check */
237*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(msg, "pfkey align msg");
238*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(mhp, "pfkey align mhp");
239*a325d9c4SApple OSS Distributions
240*a325d9c4SApple OSS Distributions	/* initialize */
241*a325d9c4SApple OSS Distributions	for (i = 0; i < SADB_EXT_MAX + 1; i++) {
242*a325d9c4SApple OSS Distributions		mhp[i] = NULL;
243*a325d9c4SApple OSS Distributions	}
244*a325d9c4SApple OSS Distributions
245*a325d9c4SApple OSS Distributions	mhp[0] = (void *)msg;
246*a325d9c4SApple OSS Distributions
247*a325d9c4SApple OSS Distributions	/* initialize */
248*a325d9c4SApple OSS Distributions	p = (void *) msg;
249*a325d9c4SApple OSS Distributions	ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
250*a325d9c4SApple OSS Distributions
251*a325d9c4SApple OSS Distributions	/* skip base header */
252*a325d9c4SApple OSS Distributions	p += sizeof(struct sadb_msg);
253*a325d9c4SApple OSS Distributions
254*a325d9c4SApple OSS Distributions	while (p < ep) {
255*a325d9c4SApple OSS Distributions		ext = (void *)p;
256*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_GE_PTR((void *)ep, (void *)(p + sizeof(*ext)), "pfkey extension header beyond end of buffer");
257*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_GE_ULONG((unsigned long)PFKEY_EXTLEN(ext), sizeof(*ext), "pfkey extension shorter than extension header");
258*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_GE_PTR((void *)ep, (void *)(p + PFKEY_EXTLEN(ext)), "pfkey extension length beyond end of buffer");
259*a325d9c4SApple OSS Distributions
260*a325d9c4SApple OSS Distributions		T_QUIET; T_EXPECT_NULL(mhp[ext->sadb_ext_type], "duplicate extension type %u payload", ext->sadb_ext_type);
261*a325d9c4SApple OSS Distributions
262*a325d9c4SApple OSS Distributions		/* set pointer */
263*a325d9c4SApple OSS Distributions		switch (ext->sadb_ext_type) {
264*a325d9c4SApple OSS Distributions		case SADB_EXT_SA:
265*a325d9c4SApple OSS Distributions		case SADB_EXT_LIFETIME_CURRENT:
266*a325d9c4SApple OSS Distributions		case SADB_EXT_LIFETIME_HARD:
267*a325d9c4SApple OSS Distributions		case SADB_EXT_LIFETIME_SOFT:
268*a325d9c4SApple OSS Distributions		case SADB_EXT_ADDRESS_SRC:
269*a325d9c4SApple OSS Distributions		case SADB_EXT_ADDRESS_DST:
270*a325d9c4SApple OSS Distributions		case SADB_EXT_ADDRESS_PROXY:
271*a325d9c4SApple OSS Distributions		case SADB_EXT_KEY_AUTH:
272*a325d9c4SApple OSS Distributions		/* XXX should to be check weak keys. */
273*a325d9c4SApple OSS Distributions		case SADB_EXT_KEY_ENCRYPT:
274*a325d9c4SApple OSS Distributions		/* XXX should to be check weak keys. */
275*a325d9c4SApple OSS Distributions		case SADB_EXT_IDENTITY_SRC:
276*a325d9c4SApple OSS Distributions		case SADB_EXT_IDENTITY_DST:
277*a325d9c4SApple OSS Distributions		case SADB_EXT_SENSITIVITY:
278*a325d9c4SApple OSS Distributions		case SADB_EXT_PROPOSAL:
279*a325d9c4SApple OSS Distributions		case SADB_EXT_SUPPORTED_AUTH:
280*a325d9c4SApple OSS Distributions		case SADB_EXT_SUPPORTED_ENCRYPT:
281*a325d9c4SApple OSS Distributions		case SADB_EXT_SPIRANGE:
282*a325d9c4SApple OSS Distributions		case SADB_X_EXT_POLICY:
283*a325d9c4SApple OSS Distributions		case SADB_X_EXT_SA2:
284*a325d9c4SApple OSS Distributions		case SADB_EXT_SESSION_ID:
285*a325d9c4SApple OSS Distributions		case SADB_EXT_SASTAT:
286*a325d9c4SApple OSS Distributions#ifdef SADB_X_EXT_NAT_T_TYPE
287*a325d9c4SApple OSS Distributions		case SADB_X_EXT_NAT_T_TYPE:
288*a325d9c4SApple OSS Distributions		case SADB_X_EXT_NAT_T_SPORT:
289*a325d9c4SApple OSS Distributions		case SADB_X_EXT_NAT_T_DPORT:
290*a325d9c4SApple OSS Distributions		case SADB_X_EXT_NAT_T_OA:
291*a325d9c4SApple OSS Distributions#endif
292*a325d9c4SApple OSS Distributions#ifdef SADB_X_EXT_TAG
293*a325d9c4SApple OSS Distributions		case SADB_X_EXT_TAG:
294*a325d9c4SApple OSS Distributions#endif
295*a325d9c4SApple OSS Distributions#ifdef SADB_X_EXT_PACKET
296*a325d9c4SApple OSS Distributions		case SADB_X_EXT_PACKET:
297*a325d9c4SApple OSS Distributions#endif
298*a325d9c4SApple OSS Distributions		case SADB_X_EXT_IPSECIF:
299*a325d9c4SApple OSS Distributions		case SADB_X_EXT_ADDR_RANGE_SRC_START:
300*a325d9c4SApple OSS Distributions		case SADB_X_EXT_ADDR_RANGE_SRC_END:
301*a325d9c4SApple OSS Distributions		case SADB_X_EXT_ADDR_RANGE_DST_START:
302*a325d9c4SApple OSS Distributions		case SADB_X_EXT_ADDR_RANGE_DST_END:
303*a325d9c4SApple OSS Distributions#ifdef SADB_MIGRATE
304*a325d9c4SApple OSS Distributions		case SADB_EXT_MIGRATE_ADDRESS_SRC:
305*a325d9c4SApple OSS Distributions		case SADB_EXT_MIGRATE_ADDRESS_DST:
306*a325d9c4SApple OSS Distributions		case SADB_X_EXT_MIGRATE_IPSECIF:
307*a325d9c4SApple OSS Distributions#endif
308*a325d9c4SApple OSS Distributions			mhp[ext->sadb_ext_type] = (void *)ext;
309*a325d9c4SApple OSS Distributions			break;
310*a325d9c4SApple OSS Distributions		default:
311*a325d9c4SApple OSS Distributions			T_FAIL("bad extension type %u", ext->sadb_ext_type);
312*a325d9c4SApple OSS Distributions			T_END;
313*a325d9c4SApple OSS Distributions		}
314*a325d9c4SApple OSS Distributions
315*a325d9c4SApple OSS Distributions		p += PFKEY_EXTLEN(ext);
316*a325d9c4SApple OSS Distributions	}
317*a325d9c4SApple OSS Distributions
318*a325d9c4SApple OSS Distributions	T_QUIET; T_EXPECT_EQ_PTR((void *)ep, (void *)p, "invalid pfkey message length");
319*a325d9c4SApple OSS Distributions	return;
320*a325d9c4SApple OSS Distributions}
321*a325d9c4SApple OSS Distributions
322*a325d9c4SApple OSS Distributionsstatic void
323*a325d9c4SApple OSS Distributionspfkey_process_message_test_encapsulate_panic(uint8_t **mhp, __unused int pfkey_socket)
324*a325d9c4SApple OSS Distributions{
325*a325d9c4SApple OSS Distributions	struct sadb_msg *message = (struct sadb_msg *)(void *)mhp[0];
326*a325d9c4SApple OSS Distributions	static uint32_t spi = 0;
327*a325d9c4SApple OSS Distributions	static uint8_t added_sa_counter = 0;
328*a325d9c4SApple OSS Distributions
329*a325d9c4SApple OSS Distributions	if (message->sadb_msg_pid != (uint32_t)getpid()) {
330*a325d9c4SApple OSS Distributions		return;
331*a325d9c4SApple OSS Distributions	}
332*a325d9c4SApple OSS Distributions
333*a325d9c4SApple OSS Distributions	if (message->sadb_msg_errno != 0) {
334*a325d9c4SApple OSS Distributions		T_FAIL("SADB add SA received error %d", message->sadb_msg_errno);
335*a325d9c4SApple OSS Distributions		T_END;
336*a325d9c4SApple OSS Distributions	}
337*a325d9c4SApple OSS Distributions
338*a325d9c4SApple OSS Distributions	switch (message->sadb_msg_type) {
339*a325d9c4SApple OSS Distributions	case SADB_ADD:
340*a325d9c4SApple OSS Distributions	{
341*a325d9c4SApple OSS Distributions		struct sadb_sa *sa_message = (struct sadb_sa *)(void *)mhp[SADB_EXT_SA];
342*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_NOTNULL(sa_message, "add sa message is NULL");
343*a325d9c4SApple OSS Distributions		spi = ntohl(sa_message->sadb_sa_spi);
344*a325d9c4SApple OSS Distributions		T_LOG("added sa 0x%x", spi);
345*a325d9c4SApple OSS Distributions		added_sa_counter++;
346*a325d9c4SApple OSS Distributions		if (added_sa_counter == 2) {
347*a325d9c4SApple OSS Distributions			bpf_write(bpf_fd);
348*a325d9c4SApple OSS Distributions		}
349*a325d9c4SApple OSS Distributions		break;
350*a325d9c4SApple OSS Distributions	}
351*a325d9c4SApple OSS Distributions	case SADB_FLUSH:
352*a325d9c4SApple OSS Distributions	case SADB_X_SPDFLUSH:
353*a325d9c4SApple OSS Distributions		break;
354*a325d9c4SApple OSS Distributions	default:
355*a325d9c4SApple OSS Distributions		T_FAIL("bad SADB message type %u", message->sadb_msg_type);
356*a325d9c4SApple OSS Distributions		T_END;
357*a325d9c4SApple OSS Distributions	}
358*a325d9c4SApple OSS Distributions	return;
359*a325d9c4SApple OSS Distributions}
360*a325d9c4SApple OSS Distributions
361*a325d9c4SApple OSS Distributionsstatic void
362*a325d9c4SApple OSS Distributionsrecv_pfkey_message(int pfkey_socket)
363*a325d9c4SApple OSS Distributions{
364*a325d9c4SApple OSS Distributions	uint8_t buffer[8192] __attribute__((aligned(4)));
365*a325d9c4SApple OSS Distributions	struct iovec iovecs[1] = {
366*a325d9c4SApple OSS Distributions		{ buffer, sizeof(buffer) },
367*a325d9c4SApple OSS Distributions	};
368*a325d9c4SApple OSS Distributions	struct msghdr msg = {
369*a325d9c4SApple OSS Distributions		NULL,
370*a325d9c4SApple OSS Distributions		0,
371*a325d9c4SApple OSS Distributions		iovecs,
372*a325d9c4SApple OSS Distributions		sizeof(iovecs) / sizeof(iovecs[0]),
373*a325d9c4SApple OSS Distributions		NULL,
374*a325d9c4SApple OSS Distributions		0,
375*a325d9c4SApple OSS Distributions		0,
376*a325d9c4SApple OSS Distributions	};
377*a325d9c4SApple OSS Distributions
378*a325d9c4SApple OSS Distributions	do {
379*a325d9c4SApple OSS Distributions		ssize_t result = -1;
380*a325d9c4SApple OSS Distributions		memset(buffer, 0, sizeof(buffer));
381*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_POSIX_SUCCESS(result = recvmsg(pfkey_socket, &msg, 0), NULL);
382*a325d9c4SApple OSS Distributions
383*a325d9c4SApple OSS Distributions		if (result > 0) {
384*a325d9c4SApple OSS Distributions			T_QUIET; T_ASSERT_GE_ULONG((size_t)result, sizeof(struct sadb_msg), "Invalid PFKey message size: %zu", result);
385*a325d9c4SApple OSS Distributions			struct sadb_msg *hdr = (struct sadb_msg *)buffer;
386*a325d9c4SApple OSS Distributions			uint8_t *mhp[SADB_EXT_MAX + 1];
387*a325d9c4SApple OSS Distributions			pfkey_align(hdr, mhp);
388*a325d9c4SApple OSS Distributions			(*process_pfkey_message_tests[test_id])(mhp, pfkey_socket);
389*a325d9c4SApple OSS Distributions		} else if (result == 0) {
390*a325d9c4SApple OSS Distributions			T_LOG("PFKey socket received EOF");
391*a325d9c4SApple OSS Distributions			break;
392*a325d9c4SApple OSS Distributions		}
393*a325d9c4SApple OSS Distributions	} while (1);
394*a325d9c4SApple OSS Distributions}
395*a325d9c4SApple OSS Distributions
396*a325d9c4SApple OSS Distributionsstatic int
397*a325d9c4SApple OSS Distributionspfkey_setup_socket(void)
398*a325d9c4SApple OSS Distributions{
399*a325d9c4SApple OSS Distributions	int pfkey_socket = -1;
400*a325d9c4SApple OSS Distributions	int bufsiz = 0;
401*a325d9c4SApple OSS Distributions	const unsigned long newbufk = 1536;
402*a325d9c4SApple OSS Distributions	unsigned long oldmax;
403*a325d9c4SApple OSS Distributions	size_t  oldmaxsize = sizeof(oldmax);
404*a325d9c4SApple OSS Distributions	unsigned long newmax = newbufk * (1024 + 128);
405*a325d9c4SApple OSS Distributions
406*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_POSIX_SUCCESS(pfkey_socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2), NULL);
407*a325d9c4SApple OSS Distributions
408*a325d9c4SApple OSS Distributions	if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax, &oldmaxsize, &newmax, sizeof(newmax)) != 0) {
409*a325d9c4SApple OSS Distributions		bufsiz = 233016;        /* Max allowed by default */
410*a325d9c4SApple OSS Distributions	} else {
411*a325d9c4SApple OSS Distributions		bufsiz = newbufk * 1024;
412*a325d9c4SApple OSS Distributions	}
413*a325d9c4SApple OSS Distributions
414*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_POSIX_SUCCESS(setsockopt(pfkey_socket, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)), "pfkey set snd socket buf failed %d", bufsiz);
415*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_POSIX_SUCCESS(setsockopt(pfkey_socket, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)), "pfkey set recv socket buf failed %d", bufsiz);
416*a325d9c4SApple OSS Distributions
417*a325d9c4SApple OSS Distributions	pfkey_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)pfkey_socket, 0, dispatch_get_main_queue());
418*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(pfkey_source, "dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, ...)");
419*a325d9c4SApple OSS Distributions	dispatch_source_set_event_handler(pfkey_source, ^{
420*a325d9c4SApple OSS Distributions		recv_pfkey_message(pfkey_socket);
421*a325d9c4SApple OSS Distributions	});
422*a325d9c4SApple OSS Distributions	dispatch_source_set_cancel_handler(pfkey_source, ^{
423*a325d9c4SApple OSS Distributions		close(pfkey_socket);
424*a325d9c4SApple OSS Distributions	});
425*a325d9c4SApple OSS Distributions	dispatch_resume(pfkey_source);
426*a325d9c4SApple OSS Distributions	return pfkey_socket;
427*a325d9c4SApple OSS Distributions}
428*a325d9c4SApple OSS Distributions
429*a325d9c4SApple OSS Distributionsstatic int
430*a325d9c4SApple OSS Distributionsbpf_new(void)
431*a325d9c4SApple OSS Distributions{
432*a325d9c4SApple OSS Distributions	char bpfdev[256];
433*a325d9c4SApple OSS Distributions	int i;
434*a325d9c4SApple OSS Distributions	int fd = -1;
435*a325d9c4SApple OSS Distributions
436*a325d9c4SApple OSS Distributions	for (i = 0; true; i++) {
437*a325d9c4SApple OSS Distributions		snprintf(bpfdev, sizeof(bpfdev), "/dev/bpf%d", i);
438*a325d9c4SApple OSS Distributions		fd = open(bpfdev, O_RDWR, 0);
439*a325d9c4SApple OSS Distributions		if (fd >= 0) {
440*a325d9c4SApple OSS Distributions			break;
441*a325d9c4SApple OSS Distributions		}
442*a325d9c4SApple OSS Distributions		if (errno != EBUSY) {
443*a325d9c4SApple OSS Distributions			break;
444*a325d9c4SApple OSS Distributions		}
445*a325d9c4SApple OSS Distributions	}
446*a325d9c4SApple OSS Distributions	return fd;
447*a325d9c4SApple OSS Distributions}
448*a325d9c4SApple OSS Distributions
449*a325d9c4SApple OSS Distributionsstatic int
450*a325d9c4SApple OSS Distributionsbpf_setif(int fd, const char *en_name)
451*a325d9c4SApple OSS Distributions{
452*a325d9c4SApple OSS Distributions	struct ifreq ifr;
453*a325d9c4SApple OSS Distributions
454*a325d9c4SApple OSS Distributions	strlcpy(ifr.ifr_name, en_name, sizeof(ifr.ifr_name));
455*a325d9c4SApple OSS Distributions	return ioctl(fd, BIOCSETIF, &ifr);
456*a325d9c4SApple OSS Distributions}
457*a325d9c4SApple OSS Distributions
458*a325d9c4SApple OSS Distributionsstatic int
459*a325d9c4SApple OSS Distributionsbpf_sethdr_complete(int fd)
460*a325d9c4SApple OSS Distributions{
461*a325d9c4SApple OSS Distributions	u_int8_t hdr_complete = 1;
462*a325d9c4SApple OSS Distributions	return ioctl(fd, BIOCSHDRCMPLT, &hdr_complete);
463*a325d9c4SApple OSS Distributions}
464*a325d9c4SApple OSS Distributions
465*a325d9c4SApple OSS Distributionsstatic void
466*a325d9c4SApple OSS Distributionsbpf_write(int fd)
467*a325d9c4SApple OSS Distributions{
468*a325d9c4SApple OSS Distributions	if (test_id == TEST_IPSEC_IPv4_ENCAPSULATE_PANIC) {
469*a325d9c4SApple OSS Distributions		char buffer[500];
470*a325d9c4SApple OSS Distributions		struct ip *ipheader = (void *)buffer;
471*a325d9c4SApple OSS Distributions		ipheader->ip_v = IPVERSION;
472*a325d9c4SApple OSS Distributions		ipheader->ip_hl = (sizeof(struct ip) - 4) >> 2;
473*a325d9c4SApple OSS Distributions		ipheader->ip_ttl = MAXTTL;
474*a325d9c4SApple OSS Distributions		ipheader->ip_p = IPPROTO_UDP;
475*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_POSIX_SUCCESS(write(fd, buffer, 500), "bpf write call failed");
476*a325d9c4SApple OSS Distributions		T_PASS("wrote bad ip header successfully");
477*a325d9c4SApple OSS Distributions		T_END;
478*a325d9c4SApple OSS Distributions	} else if (test_id == TEST_IPSEC_IPv6_ENCAPSULATE_PANIC) {
479*a325d9c4SApple OSS Distributions		struct ip6_hdr ip6 = {0};
480*a325d9c4SApple OSS Distributions		ip6.ip6_vfc |= IPV6_VERSION;
481*a325d9c4SApple OSS Distributions		T_QUIET; T_ASSERT_POSIX_SUCCESS(write(fd, &ip6, sizeof(ip6) - 4), "bpf write call failed");
482*a325d9c4SApple OSS Distributions		T_PASS("wrote bad ipv6 header successfully");
483*a325d9c4SApple OSS Distributions		T_END;
484*a325d9c4SApple OSS Distributions	}
485*a325d9c4SApple OSS Distributions}
486*a325d9c4SApple OSS Distributions
487*a325d9c4SApple OSS Distributionsstatic void
488*a325d9c4SApple OSS Distributionsbpf_socket_setup(void)
489*a325d9c4SApple OSS Distributions{
490*a325d9c4SApple OSS Distributions	int status = -1;
491*a325d9c4SApple OSS Distributions
492*a325d9c4SApple OSS Distributions	bpf_fd = bpf_new();
493*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NE(bpf_fd, -1, "failed to create bpf file descriptor");
494*a325d9c4SApple OSS Distributions
495*a325d9c4SApple OSS Distributions	CFStringRef ipsecIfName = NEVirtualInterfaceCopyName(ipsecInterface);
496*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(ipsecIfName, "failed to get ipsec interface name");
497*a325d9c4SApple OSS Distributions
498*a325d9c4SApple OSS Distributions	char ifname[IFNAMSIZ];
499*a325d9c4SApple OSS Distributions	CFStringGetCString(ipsecIfName, ifname, IFNAMSIZ, kCFStringEncodingUTF8);
500*a325d9c4SApple OSS Distributions
501*a325d9c4SApple OSS Distributions	status = bpf_setif(bpf_fd, ifname);
502*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NE(status, -1, "failed to set bpf interface");
503*a325d9c4SApple OSS Distributions
504*a325d9c4SApple OSS Distributions	status = bpf_sethdr_complete(bpf_fd);
505*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NE(status, -1, "failed to set bpf header complete");
506*a325d9c4SApple OSS Distributions}
507*a325d9c4SApple OSS Distributions
508*a325d9c4SApple OSS Distributionsstatic NEVirtualInterfaceRef
509*a325d9c4SApple OSS Distributionsipsec_interface_setup(CFStringRef interfaceAddress, CFStringRef interfaceMask)
510*a325d9c4SApple OSS Distributions{
511*a325d9c4SApple OSS Distributions	Boolean status = FALSE;
512*a325d9c4SApple OSS Distributions
513*a325d9c4SApple OSS Distributions	NEVirtualInterfaceRef interface = NEVirtualInterfaceCreate(NULL, kNEVirtualInterfaceValTypeIPSec, dispatch_get_main_queue(), NULL);
514*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(interface, "ipsec interface creation failed");
515*a325d9c4SApple OSS Distributions	status = NEVirtualInterfaceSetMTU(interface, 1400);
516*a325d9c4SApple OSS Distributions	if (status == FALSE) {
517*a325d9c4SApple OSS Distributions		T_FAIL("Failed to set MTU on ipsec interface");
518*a325d9c4SApple OSS Distributions		T_END;
519*a325d9c4SApple OSS Distributions	}
520*a325d9c4SApple OSS Distributions
521*a325d9c4SApple OSS Distributions	status = NEVirtualInterfaceAddAddress(interface, interfaceAddress, interfaceMask);
522*a325d9c4SApple OSS Distributions	if (status == FALSE) {
523*a325d9c4SApple OSS Distributions		T_FAIL("Failed to set address on ipsec interface");
524*a325d9c4SApple OSS Distributions		T_END;
525*a325d9c4SApple OSS Distributions	}
526*a325d9c4SApple OSS Distributions
527*a325d9c4SApple OSS Distributions	CFStringRef ipsecIfName = NEVirtualInterfaceCopyName(interface);
528*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(ipsecIfName, "failed to get ipsec interface name");
529*a325d9c4SApple OSS Distributions
530*a325d9c4SApple OSS Distributions	char ifname[IFNAMSIZ];
531*a325d9c4SApple OSS Distributions	CFStringGetCString(ipsecIfName, ifname, IFNAMSIZ, kCFStringEncodingUTF8);
532*a325d9c4SApple OSS Distributions
533*a325d9c4SApple OSS Distributions	T_LOG("%s interface setup", ifname);
534*a325d9c4SApple OSS Distributions	return interface;
535*a325d9c4SApple OSS Distributions}
536*a325d9c4SApple OSS Distributions
537*a325d9c4SApple OSS Distributionsstatic void
538*a325d9c4SApple OSS Distributionsipsec_interface_set_delegate(NEVirtualInterfaceRef interface, CFStringRef delegateInterfaceName)
539*a325d9c4SApple OSS Distributions{
540*a325d9c4SApple OSS Distributions	Boolean status = NEVirtualInterfaceSetDelegateInterface(interface, delegateInterfaceName);
541*a325d9c4SApple OSS Distributions	if (status == FALSE) {
542*a325d9c4SApple OSS Distributions		T_FAIL("Failed to set delegate on ipsec interface");
543*a325d9c4SApple OSS Distributions		T_END;
544*a325d9c4SApple OSS Distributions	}
545*a325d9c4SApple OSS Distributions
546*a325d9c4SApple OSS Distributions	return;
547*a325d9c4SApple OSS Distributions}
548*a325d9c4SApple OSS Distributions
549*a325d9c4SApple OSS Distributionsstatic void
550*a325d9c4SApple OSS Distributionsipsec_cleanup(void)
551*a325d9c4SApple OSS Distributions{
552*a325d9c4SApple OSS Distributions	pfkey_cleanup();
553*a325d9c4SApple OSS Distributions
554*a325d9c4SApple OSS Distributions	if (ipsecInterface != NULL) {
555*a325d9c4SApple OSS Distributions		NEVirtualInterfaceInvalidate(ipsecInterface);
556*a325d9c4SApple OSS Distributions		ipsecInterface = NULL;
557*a325d9c4SApple OSS Distributions	}
558*a325d9c4SApple OSS Distributions
559*a325d9c4SApple OSS Distributions	if (delegateIPsecInterface != NULL) {
560*a325d9c4SApple OSS Distributions		NEVirtualInterfaceInvalidate(delegateIPsecInterface);
561*a325d9c4SApple OSS Distributions		delegateIPsecInterface = NULL;
562*a325d9c4SApple OSS Distributions	}
563*a325d9c4SApple OSS Distributions
564*a325d9c4SApple OSS Distributions	if (bpf_fd != -1) {
565*a325d9c4SApple OSS Distributions		close(bpf_fd);
566*a325d9c4SApple OSS Distributions		bpf_fd = -1;
567*a325d9c4SApple OSS Distributions	}
568*a325d9c4SApple OSS Distributions}
569*a325d9c4SApple OSS Distributions
570*a325d9c4SApple OSS DistributionsT_DECL(ipsec_ipv4_encapsulate_panic_63139357, "ipsec: outer ip header length less than 20")
571*a325d9c4SApple OSS Distributions{
572*a325d9c4SApple OSS Distributions	test_id = TEST_IPSEC_IPv4_ENCAPSULATE_PANIC;
573*a325d9c4SApple OSS Distributions
574*a325d9c4SApple OSS Distributions	T_ATEND(ipsec_cleanup);
575*a325d9c4SApple OSS Distributions
576*a325d9c4SApple OSS Distributions	ipsecInterface = ipsec_interface_setup(CFSTR(TEST_IPSEC_IPv4_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv4_INTERFACE_MASK));
577*a325d9c4SApple OSS Distributions	delegateIPsecInterface = ipsec_interface_setup(CFSTR(TEST_DELEGATE_IPSEC_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv4_INTERFACE_MASK));
578*a325d9c4SApple OSS Distributions
579*a325d9c4SApple OSS Distributions	CFStringRef delegateIPsecIfName = NEVirtualInterfaceCopyName(delegateIPsecInterface);
580*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(delegateIPsecIfName, "failed to get ipsec interface name");
581*a325d9c4SApple OSS Distributions	ipsec_interface_set_delegate(ipsecInterface, delegateIPsecIfName);
582*a325d9c4SApple OSS Distributions
583*a325d9c4SApple OSS Distributions	bpf_socket_setup();
584*a325d9c4SApple OSS Distributions
585*a325d9c4SApple OSS Distributions	int pfkey_socket = pfkey_setup_socket();
586*a325d9c4SApple OSS Distributions	send_pfkey_flush_sa(pfkey_socket);
587*a325d9c4SApple OSS Distributions
588*a325d9c4SApple OSS Distributions	send_pkey_add_sa(pfkey_socket, 0x12345678, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET);
589*a325d9c4SApple OSS Distributions	send_pkey_add_sa(pfkey_socket, 0x23456789, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET);
590*a325d9c4SApple OSS Distributions
591*a325d9c4SApple OSS Distributions	dispatch_main();
592*a325d9c4SApple OSS Distributions}
593*a325d9c4SApple OSS Distributions
594*a325d9c4SApple OSS DistributionsT_DECL(ipsec_ipv6_encapsulate_panic_63139357, "ipsec: payload less than IPv6 header")
595*a325d9c4SApple OSS Distributions{
596*a325d9c4SApple OSS Distributions	test_id = TEST_IPSEC_IPv6_ENCAPSULATE_PANIC;
597*a325d9c4SApple OSS Distributions
598*a325d9c4SApple OSS Distributions	T_ATEND(ipsec_cleanup);
599*a325d9c4SApple OSS Distributions
600*a325d9c4SApple OSS Distributions	ipsecInterface = ipsec_interface_setup(CFSTR(TEST_IPSEC_IPv6_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv6_INTERFACE_MASK));
601*a325d9c4SApple OSS Distributions	delegateIPsecInterface = ipsec_interface_setup(CFSTR(TEST_DELEGATE_IPSEC_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv4_INTERFACE_MASK));
602*a325d9c4SApple OSS Distributions
603*a325d9c4SApple OSS Distributions	CFStringRef delegateIPsecIfName = NEVirtualInterfaceCopyName(delegateIPsecInterface);
604*a325d9c4SApple OSS Distributions	T_QUIET; T_ASSERT_NOTNULL(delegateIPsecIfName, "failed to get ipsec interface name");
605*a325d9c4SApple OSS Distributions	ipsec_interface_set_delegate(ipsecInterface, delegateIPsecIfName);
606*a325d9c4SApple OSS Distributions
607*a325d9c4SApple OSS Distributions	bpf_socket_setup();
608*a325d9c4SApple OSS Distributions
609*a325d9c4SApple OSS Distributions	int pfkey_socket = pfkey_setup_socket();
610*a325d9c4SApple OSS Distributions	send_pfkey_flush_sa(pfkey_socket);
611*a325d9c4SApple OSS Distributions
612*a325d9c4SApple OSS Distributions	send_pkey_add_sa(pfkey_socket, 0x12345678, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET);
613*a325d9c4SApple OSS Distributions	send_pkey_add_sa(pfkey_socket, 0x23456789, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET);
614*a325d9c4SApple OSS Distributions
615*a325d9c4SApple OSS Distributions	dispatch_main();
616*a325d9c4SApple OSS Distributions}
617