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