1*0f4c859eSApple OSS Distributions /*
2*0f4c859eSApple OSS Distributions * Copyright (c) 2023 Apple Inc. All rights reserved.
3*0f4c859eSApple OSS Distributions *
4*0f4c859eSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*0f4c859eSApple OSS Distributions *
6*0f4c859eSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*0f4c859eSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*0f4c859eSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*0f4c859eSApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*0f4c859eSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*0f4c859eSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*0f4c859eSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*0f4c859eSApple OSS Distributions * terms of an Apple operating system software license agreement.
14*0f4c859eSApple OSS Distributions *
15*0f4c859eSApple OSS Distributions * Please obtain a copy of the License at
16*0f4c859eSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*0f4c859eSApple OSS Distributions *
18*0f4c859eSApple OSS Distributions * The Original Code and all software distributed under the License are
19*0f4c859eSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*0f4c859eSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*0f4c859eSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*0f4c859eSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*0f4c859eSApple OSS Distributions * Please see the License for the specific language governing rights and
24*0f4c859eSApple OSS Distributions * limitations under the License.
25*0f4c859eSApple OSS Distributions *
26*0f4c859eSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*0f4c859eSApple OSS Distributions */
28*0f4c859eSApple OSS Distributions
29*0f4c859eSApple OSS Distributions #include <darwintest.h>
30*0f4c859eSApple OSS Distributions
31*0f4c859eSApple OSS Distributions #include <sys/ioctl.h>
32*0f4c859eSApple OSS Distributions #include <sys/sysctl.h>
33*0f4c859eSApple OSS Distributions
34*0f4c859eSApple OSS Distributions #include <net/if.h>
35*0f4c859eSApple OSS Distributions #include <net/if_arp.h>
36*0f4c859eSApple OSS Distributions #include <net/if_fake_var.h>
37*0f4c859eSApple OSS Distributions #include <net/bpf.h>
38*0f4c859eSApple OSS Distributions #include <net/ethernet.h>
39*0f4c859eSApple OSS Distributions
40*0f4c859eSApple OSS Distributions #include <netinet/ip.h>
41*0f4c859eSApple OSS Distributions
42*0f4c859eSApple OSS Distributions #include <stdlib.h>
43*0f4c859eSApple OSS Distributions #include <string.h>
44*0f4c859eSApple OSS Distributions #include <strings.h>
45*0f4c859eSApple OSS Distributions
46*0f4c859eSApple OSS Distributions #include "net_test_lib.h"
47*0f4c859eSApple OSS Distributions #include "bpflib.h"
48*0f4c859eSApple OSS Distributions #include "in_cksum.h"
49*0f4c859eSApple OSS Distributions
50*0f4c859eSApple OSS Distributions T_GLOBAL_META(
51*0f4c859eSApple OSS Distributions T_META_NAMESPACE("xnu.net"),
52*0f4c859eSApple OSS Distributions T_META_ASROOT(true),
53*0f4c859eSApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
54*0f4c859eSApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("networking"),
55*0f4c859eSApple OSS Distributions T_META_CHECK_LEAKS(false));
56*0f4c859eSApple OSS Distributions
57*0f4c859eSApple OSS Distributions
58*0f4c859eSApple OSS Distributions #define MAXBUF 32
59*0f4c859eSApple OSS Distributions static void
HexDump(void * data,size_t len)60*0f4c859eSApple OSS Distributions HexDump(void *data, size_t len)
61*0f4c859eSApple OSS Distributions {
62*0f4c859eSApple OSS Distributions size_t i, j, k;
63*0f4c859eSApple OSS Distributions unsigned char *ptr = (unsigned char *)data;
64*0f4c859eSApple OSS Distributions unsigned char buf[3 * MAXBUF + 1];
65*0f4c859eSApple OSS Distributions
66*0f4c859eSApple OSS Distributions for (i = 0; i < len; i += MAXBUF) {
67*0f4c859eSApple OSS Distributions for (j = i, k = 0; j < i + MAXBUF && j < len; j++) {
68*0f4c859eSApple OSS Distributions unsigned char msnbl = ptr[j] >> 4;
69*0f4c859eSApple OSS Distributions unsigned char lsnbl = ptr[j] & 0x0f;
70*0f4c859eSApple OSS Distributions
71*0f4c859eSApple OSS Distributions buf[k++] = msnbl < 10 ? msnbl + '0' : msnbl + 'a' - 10;
72*0f4c859eSApple OSS Distributions buf[k++] = lsnbl < 10 ? lsnbl + '0' : lsnbl + 'a' - 10;
73*0f4c859eSApple OSS Distributions if ((j % 2) == 1) {
74*0f4c859eSApple OSS Distributions buf[k++] = ' ';
75*0f4c859eSApple OSS Distributions }
76*0f4c859eSApple OSS Distributions if ((j % MAXBUF) == MAXBUF - 1) {
77*0f4c859eSApple OSS Distributions buf[k++] = ' ';
78*0f4c859eSApple OSS Distributions }
79*0f4c859eSApple OSS Distributions }
80*0f4c859eSApple OSS Distributions buf[k] = 0;
81*0f4c859eSApple OSS Distributions T_LOG("%5zd: %s\n", i, buf);
82*0f4c859eSApple OSS Distributions }
83*0f4c859eSApple OSS Distributions }
84*0f4c859eSApple OSS Distributions
85*0f4c859eSApple OSS Distributions static int udp_fd = -1;
86*0f4c859eSApple OSS Distributions static char ifname1[IF_NAMESIZE];
87*0f4c859eSApple OSS Distributions static char ifname2[IF_NAMESIZE];
88*0f4c859eSApple OSS Distributions static int default_fake_max_mtu = 0;
89*0f4c859eSApple OSS Distributions
90*0f4c859eSApple OSS Distributions static void
cleanup(void)91*0f4c859eSApple OSS Distributions cleanup(void)
92*0f4c859eSApple OSS Distributions {
93*0f4c859eSApple OSS Distributions if (udp_fd != -1) {
94*0f4c859eSApple OSS Distributions (void)ifnet_destroy(udp_fd, ifname1, false);
95*0f4c859eSApple OSS Distributions T_LOG("ifnet_destroy %s", ifname1);
96*0f4c859eSApple OSS Distributions
97*0f4c859eSApple OSS Distributions (void)ifnet_destroy(udp_fd, ifname2, false);
98*0f4c859eSApple OSS Distributions T_LOG("ifnet_destroy %s", ifname2);
99*0f4c859eSApple OSS Distributions }
100*0f4c859eSApple OSS Distributions
101*0f4c859eSApple OSS Distributions if (default_fake_max_mtu != 0) {
102*0f4c859eSApple OSS Distributions T_LOG("sysctl net.link.fake.max_mtu=%d", default_fake_max_mtu);
103*0f4c859eSApple OSS Distributions (void) sysctlbyname("net.link.fake.max_mtu", NULL, NULL, &default_fake_max_mtu, sizeof(int));
104*0f4c859eSApple OSS Distributions }
105*0f4c859eSApple OSS Distributions
106*0f4c859eSApple OSS Distributions if (udp_fd != -1) {
107*0f4c859eSApple OSS Distributions (void) close(udp_fd);
108*0f4c859eSApple OSS Distributions }
109*0f4c859eSApple OSS Distributions }
110*0f4c859eSApple OSS Distributions
111*0f4c859eSApple OSS Distributions static void
init(int mtu)112*0f4c859eSApple OSS Distributions init(int mtu)
113*0f4c859eSApple OSS Distributions {
114*0f4c859eSApple OSS Distributions T_ATEND(cleanup);
115*0f4c859eSApple OSS Distributions
116*0f4c859eSApple OSS Distributions udp_fd = inet_dgram_socket();
117*0f4c859eSApple OSS Distributions
118*0f4c859eSApple OSS Distributions if (mtu > 0) {
119*0f4c859eSApple OSS Distributions size_t oldlen = sizeof(int);
120*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname("net.link.fake.max_mtu", &default_fake_max_mtu, &oldlen, &mtu, sizeof(int)),
121*0f4c859eSApple OSS Distributions "sysctl net.link.fake.max_mtu %d -> %d", default_fake_max_mtu, mtu);
122*0f4c859eSApple OSS Distributions }
123*0f4c859eSApple OSS Distributions }
124*0f4c859eSApple OSS Distributions
125*0f4c859eSApple OSS Distributions static int
set_if_mtu(const char * ifname,int mtu)126*0f4c859eSApple OSS Distributions set_if_mtu(const char *ifname, int mtu)
127*0f4c859eSApple OSS Distributions {
128*0f4c859eSApple OSS Distributions int error = 0;
129*0f4c859eSApple OSS Distributions struct ifreq ifr = {};
130*0f4c859eSApple OSS Distributions
131*0f4c859eSApple OSS Distributions strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
132*0f4c859eSApple OSS Distributions ifr.ifr_mtu = mtu;
133*0f4c859eSApple OSS Distributions
134*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ioctl(udp_fd, SIOCSIFMTU, (caddr_t)&ifr), NULL);
135*0f4c859eSApple OSS Distributions
136*0f4c859eSApple OSS Distributions return error;
137*0f4c859eSApple OSS Distributions }
138*0f4c859eSApple OSS Distributions
139*0f4c859eSApple OSS Distributions static int
setup_feth_pair(int mtu)140*0f4c859eSApple OSS Distributions setup_feth_pair(int mtu)
141*0f4c859eSApple OSS Distributions {
142*0f4c859eSApple OSS Distributions int error = 0;
143*0f4c859eSApple OSS Distributions
144*0f4c859eSApple OSS Distributions strlcpy(ifname1, FETH_NAME, sizeof(ifname1));
145*0f4c859eSApple OSS Distributions error = ifnet_create_2(udp_fd, ifname1, sizeof(ifname1));
146*0f4c859eSApple OSS Distributions if (error != 0) {
147*0f4c859eSApple OSS Distributions goto done;
148*0f4c859eSApple OSS Distributions }
149*0f4c859eSApple OSS Distributions T_LOG("created %s", ifname1);
150*0f4c859eSApple OSS Distributions
151*0f4c859eSApple OSS Distributions strlcpy(ifname2, FETH_NAME, sizeof(ifname2));
152*0f4c859eSApple OSS Distributions error = ifnet_create_2(udp_fd, ifname2, sizeof(ifname2));
153*0f4c859eSApple OSS Distributions if (error != 0) {
154*0f4c859eSApple OSS Distributions goto done;
155*0f4c859eSApple OSS Distributions }
156*0f4c859eSApple OSS Distributions T_LOG("created %s", ifname2);
157*0f4c859eSApple OSS Distributions
158*0f4c859eSApple OSS Distributions ifnet_attach_ip(udp_fd, ifname1);
159*0f4c859eSApple OSS Distributions
160*0f4c859eSApple OSS Distributions if ((error = fake_set_peer(udp_fd, ifname1, ifname2)) != 0) {
161*0f4c859eSApple OSS Distributions goto done;
162*0f4c859eSApple OSS Distributions }
163*0f4c859eSApple OSS Distributions if (mtu != 0) {
164*0f4c859eSApple OSS Distributions set_if_mtu(ifname1, mtu);
165*0f4c859eSApple OSS Distributions set_if_mtu(ifname2, mtu);
166*0f4c859eSApple OSS Distributions }
167*0f4c859eSApple OSS Distributions done:
168*0f4c859eSApple OSS Distributions return error;
169*0f4c859eSApple OSS Distributions }
170*0f4c859eSApple OSS Distributions
171*0f4c859eSApple OSS Distributions static int
create_bpf_on_interface(const char * ifname,int * out_fd,int * out_bdlen,u_int write_size_max)172*0f4c859eSApple OSS Distributions create_bpf_on_interface(const char *ifname, int *out_fd, int *out_bdlen, u_int write_size_max)
173*0f4c859eSApple OSS Distributions {
174*0f4c859eSApple OSS Distributions int bpf_fd = -1;
175*0f4c859eSApple OSS Distributions int error = 0;
176*0f4c859eSApple OSS Distributions int bdlen = 0;
177*0f4c859eSApple OSS Distributions
178*0f4c859eSApple OSS Distributions bpf_fd = bpf_new();
179*0f4c859eSApple OSS Distributions if (bpf_fd < 0) {
180*0f4c859eSApple OSS Distributions error = errno;
181*0f4c859eSApple OSS Distributions T_LOG("bpf_new");
182*0f4c859eSApple OSS Distributions goto done;
183*0f4c859eSApple OSS Distributions }
184*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_blen(bpf_fd, 128 * 1024), NULL);
185*0f4c859eSApple OSS Distributions
186*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_get_blen(bpf_fd, &bdlen), NULL);
187*0f4c859eSApple OSS Distributions
188*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_immediate(bpf_fd, 1), NULL);
189*0f4c859eSApple OSS Distributions
190*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_setif(bpf_fd, ifname), "bpf set if %s",
191*0f4c859eSApple OSS Distributions ifname1);
192*0f4c859eSApple OSS Distributions
193*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_see_sent(bpf_fd, 1), NULL);
194*0f4c859eSApple OSS Distributions
195*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_header_complete(bpf_fd, 0), NULL);
196*0f4c859eSApple OSS Distributions
197*0f4c859eSApple OSS Distributions #ifdef BIOCSWRITEMAX
198*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_write_size_max(bpf_fd, write_size_max), NULL);
199*0f4c859eSApple OSS Distributions
200*0f4c859eSApple OSS Distributions u_int value;
201*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_get_write_size_max(bpf_fd, &value), NULL);
202*0f4c859eSApple OSS Distributions
203*0f4c859eSApple OSS Distributions T_LOG("write_size_max %u %s value %u", write_size_max, write_size_max != value ? "!=" : "==", value);
204*0f4c859eSApple OSS Distributions #else
205*0f4c859eSApple OSS Distributions if (write_size_max > 0) {
206*0f4c859eSApple OSS Distributions T_SKIP("BIOCSWRITEMAX not supported");
207*0f4c859eSApple OSS Distributions }
208*0f4c859eSApple OSS Distributions #endif
209*0f4c859eSApple OSS Distributions struct timeval five_seconds = { .tv_sec = 5, .tv_usec = 0 };
210*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_timeout(bpf_fd, &five_seconds), NULL);
211*0f4c859eSApple OSS Distributions
212*0f4c859eSApple OSS Distributions done:
213*0f4c859eSApple OSS Distributions *out_bdlen = bdlen;
214*0f4c859eSApple OSS Distributions *out_fd = bpf_fd;
215*0f4c859eSApple OSS Distributions return error;
216*0f4c859eSApple OSS Distributions }
217*0f4c859eSApple OSS Distributions
218*0f4c859eSApple OSS Distributions static void
do_bpf_write(const char * ifname,u_int ip_len,bool expect_success,u_int write_size_max)219*0f4c859eSApple OSS Distributions do_bpf_write(const char *ifname, u_int ip_len, bool expect_success, u_int write_size_max)
220*0f4c859eSApple OSS Distributions {
221*0f4c859eSApple OSS Distributions int bpf_fd = -1;
222*0f4c859eSApple OSS Distributions int bdlen = 0;
223*0f4c859eSApple OSS Distributions u_int payload_len;
224*0f4c859eSApple OSS Distributions
225*0f4c859eSApple OSS Distributions if (ip_len == 0) {
226*0f4c859eSApple OSS Distributions payload_len = (u_int)sizeof(dhcp_min_payload);
227*0f4c859eSApple OSS Distributions } else {
228*0f4c859eSApple OSS Distributions T_ASSERT_GE((size_t)ip_len, sizeof(struct ip) + sizeof(struct udphdr) + sizeof(dhcp_min_payload),
229*0f4c859eSApple OSS Distributions "ip_len");
230*0f4c859eSApple OSS Distributions payload_len = ip_len - (sizeof(struct ip) + sizeof(struct udphdr));
231*0f4c859eSApple OSS Distributions }
232*0f4c859eSApple OSS Distributions
233*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_ZERO(create_bpf_on_interface(ifname, &bpf_fd, &bdlen, write_size_max), NULL);
234*0f4c859eSApple OSS Distributions T_LOG("bpf bdlen %d", bdlen);
235*0f4c859eSApple OSS Distributions
236*0f4c859eSApple OSS Distributions struct ether_addr src_eaddr = {};
237*0f4c859eSApple OSS Distributions ifnet_get_lladdr(udp_fd, ifname1, &src_eaddr);
238*0f4c859eSApple OSS Distributions
239*0f4c859eSApple OSS Distributions struct in_addr src_ip = { .s_addr = INADDR_ANY };
240*0f4c859eSApple OSS Distributions uint16_t src_port = 68;
241*0f4c859eSApple OSS Distributions
242*0f4c859eSApple OSS Distributions struct ether_addr dst_eaddr = {};
243*0f4c859eSApple OSS Distributions memset(dst_eaddr.octet, 255, ETHER_ADDR_LEN);
244*0f4c859eSApple OSS Distributions
245*0f4c859eSApple OSS Distributions struct in_addr dst_ip = { .s_addr = INADDR_BROADCAST };
246*0f4c859eSApple OSS Distributions
247*0f4c859eSApple OSS Distributions uint16_t dst_port = 67;
248*0f4c859eSApple OSS Distributions
249*0f4c859eSApple OSS Distributions char *payload = calloc(1, payload_len);
250*0f4c859eSApple OSS Distributions
251*0f4c859eSApple OSS Distributions make_dhcp_payload((dhcp_min_payload_t)(void *)payload, &src_eaddr);
252*0f4c859eSApple OSS Distributions
253*0f4c859eSApple OSS Distributions u_int pkt_size = ETHER_HDR_LEN + IP_MAXPACKET;
254*0f4c859eSApple OSS Distributions unsigned char *pkt = calloc(1, pkt_size);
255*0f4c859eSApple OSS Distributions
256*0f4c859eSApple OSS Distributions u_int frame_length = ethernet_udp4_frame_populate((void *)pkt,
257*0f4c859eSApple OSS Distributions pkt_size,
258*0f4c859eSApple OSS Distributions &src_eaddr,
259*0f4c859eSApple OSS Distributions src_ip,
260*0f4c859eSApple OSS Distributions src_port,
261*0f4c859eSApple OSS Distributions &dst_eaddr,
262*0f4c859eSApple OSS Distributions dst_ip,
263*0f4c859eSApple OSS Distributions dst_port,
264*0f4c859eSApple OSS Distributions payload,
265*0f4c859eSApple OSS Distributions payload_len);
266*0f4c859eSApple OSS Distributions
267*0f4c859eSApple OSS Distributions T_LOG("frame_length %u ip_len %u payload_len %u", frame_length, ip_len, payload_len);
268*0f4c859eSApple OSS Distributions
269*0f4c859eSApple OSS Distributions T_ASSERT_GT((size_t)frame_length, (size_t)0, "frame_length must greater than zero");
270*0f4c859eSApple OSS Distributions
271*0f4c859eSApple OSS Distributions
272*0f4c859eSApple OSS Distributions ssize_t nwritten;
273*0f4c859eSApple OSS Distributions nwritten = write(bpf_fd, pkt, frame_length);
274*0f4c859eSApple OSS Distributions
275*0f4c859eSApple OSS Distributions T_LOG("bpf write returned %ld", nwritten);
276*0f4c859eSApple OSS Distributions
277*0f4c859eSApple OSS Distributions if (expect_success) {
278*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(nwritten, "write bpf");
279*0f4c859eSApple OSS Distributions } else {
280*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_FAILURE(nwritten, EMSGSIZE, "write bpf");
281*0f4c859eSApple OSS Distributions goto done;
282*0f4c859eSApple OSS Distributions }
283*0f4c859eSApple OSS Distributions
284*0f4c859eSApple OSS Distributions T_LOG("bpf written %ld bytes over %u", nwritten, frame_length);
285*0f4c859eSApple OSS Distributions HexDump(pkt, MIN((size_t)nwritten, 512));
286*0f4c859eSApple OSS Distributions
287*0f4c859eSApple OSS Distributions unsigned char *buffer = calloc(1, (size_t)bdlen);
288*0f4c859eSApple OSS Distributions T_ASSERT_NOTNULL(buffer, "malloc()");
289*0f4c859eSApple OSS Distributions
290*0f4c859eSApple OSS Distributions ssize_t nread = read(bpf_fd, buffer, (size_t)bdlen);
291*0f4c859eSApple OSS Distributions
292*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(nread, "read bpf");
293*0f4c859eSApple OSS Distributions
294*0f4c859eSApple OSS Distributions T_LOG("bpf read %ld bytes", nread);
295*0f4c859eSApple OSS Distributions
296*0f4c859eSApple OSS Distributions /*
297*0f4c859eSApple OSS Distributions * We need at least the BPF header
298*0f4c859eSApple OSS Distributions */
299*0f4c859eSApple OSS Distributions T_ASSERT_GT((size_t)nread, sizeof(sizeof(struct bpf_hdr)), NULL);
300*0f4c859eSApple OSS Distributions
301*0f4c859eSApple OSS Distributions /*
302*0f4c859eSApple OSS Distributions * Note: The following will fail if there is parasitic traffic and that should not happen
303*0f4c859eSApple OSS Distributions */
304*0f4c859eSApple OSS Distributions struct bpf_hdr *hp = (struct bpf_hdr *)(void *)buffer;
305*0f4c859eSApple OSS Distributions T_LOG("tv_sec %u tv_usec %u caplen %u datalen %u hdrlen %u",
306*0f4c859eSApple OSS Distributions hp->bh_tstamp.tv_sec, hp->bh_tstamp.tv_usec,
307*0f4c859eSApple OSS Distributions hp->bh_caplen, hp->bh_datalen, hp->bh_hdrlen);
308*0f4c859eSApple OSS Distributions
309*0f4c859eSApple OSS Distributions HexDump(buffer, MIN((size_t)(hp->bh_hdrlen + hp->bh_caplen), 512));
310*0f4c859eSApple OSS Distributions
311*0f4c859eSApple OSS Distributions T_ASSERT_EQ_LONG(nwritten, (long)hp->bh_caplen, "bpf read same size as written");
312*0f4c859eSApple OSS Distributions
313*0f4c859eSApple OSS Distributions T_ASSERT_EQ_INT(bcmp(buffer + hp->bh_hdrlen, pkt, (size_t)nwritten), 0, "bpf read same bytes as written");
314*0f4c859eSApple OSS Distributions
315*0f4c859eSApple OSS Distributions if (buffer != NULL) {
316*0f4c859eSApple OSS Distributions free(buffer);
317*0f4c859eSApple OSS Distributions }
318*0f4c859eSApple OSS Distributions done:
319*0f4c859eSApple OSS Distributions if (bpf_fd != -1) {
320*0f4c859eSApple OSS Distributions close(bpf_fd);
321*0f4c859eSApple OSS Distributions }
322*0f4c859eSApple OSS Distributions }
323*0f4c859eSApple OSS Distributions
324*0f4c859eSApple OSS Distributions static void
test_bpf_write(u_int data_len,int mtu,bool expect_success,u_int write_size_max)325*0f4c859eSApple OSS Distributions test_bpf_write(u_int data_len, int mtu, bool expect_success, u_int write_size_max)
326*0f4c859eSApple OSS Distributions {
327*0f4c859eSApple OSS Distributions init(mtu);
328*0f4c859eSApple OSS Distributions
329*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_ZERO(setup_feth_pair(mtu), NULL);
330*0f4c859eSApple OSS Distributions
331*0f4c859eSApple OSS Distributions do_bpf_write(ifname1, data_len, expect_success, write_size_max);
332*0f4c859eSApple OSS Distributions }
333*0f4c859eSApple OSS Distributions
334*0f4c859eSApple OSS Distributions T_DECL(bpf_write_dhcp, "BPF write DHCP feth MTU 1500")
335*0f4c859eSApple OSS Distributions {
336*0f4c859eSApple OSS Distributions test_bpf_write(0, 1500, true, 0);
337*0f4c859eSApple OSS Distributions }
338*0f4c859eSApple OSS Distributions
339*0f4c859eSApple OSS Distributions T_DECL(bpf_write_1024, "BPF write 1024 feth MTU 1500")
340*0f4c859eSApple OSS Distributions {
341*0f4c859eSApple OSS Distributions test_bpf_write(1024, 1500, true, 0);
342*0f4c859eSApple OSS Distributions }
343*0f4c859eSApple OSS Distributions
344*0f4c859eSApple OSS Distributions T_DECL(bpf_write_1514, "BPF write 1500 feth MTU 1500")
345*0f4c859eSApple OSS Distributions {
346*0f4c859eSApple OSS Distributions test_bpf_write(1514, 1500, true, 0);
347*0f4c859eSApple OSS Distributions }
348*0f4c859eSApple OSS Distributions
349*0f4c859eSApple OSS Distributions T_DECL(bpf_write_65482, "BPF write 65482 feth MTU 1500")
350*0f4c859eSApple OSS Distributions {
351*0f4c859eSApple OSS Distributions test_bpf_write(65482, 1500, false, 0);
352*0f4c859eSApple OSS Distributions }
353*0f4c859eSApple OSS Distributions
354*0f4c859eSApple OSS Distributions T_DECL(bpf_write_2048, "BPF write 2048 feth MTU 1500")
355*0f4c859eSApple OSS Distributions {
356*0f4c859eSApple OSS Distributions test_bpf_write(2048, 1500, false, 0);
357*0f4c859eSApple OSS Distributions }
358*0f4c859eSApple OSS Distributions
359*0f4c859eSApple OSS Distributions T_DECL(bpf_write_2048_mtu_4096, "BPF write 2048 feth MTU 4096 ")
360*0f4c859eSApple OSS Distributions {
361*0f4c859eSApple OSS Distributions test_bpf_write(2048, 4096, true, 0);
362*0f4c859eSApple OSS Distributions }
363*0f4c859eSApple OSS Distributions
364*0f4c859eSApple OSS Distributions T_DECL(bpf_write_4110_mtu_4096, "BPF write 4110 feth MTU 4096 ")
365*0f4c859eSApple OSS Distributions {
366*0f4c859eSApple OSS Distributions test_bpf_write(4110, 4096, true, 0);
367*0f4c859eSApple OSS Distributions }
368*0f4c859eSApple OSS Distributions
369*0f4c859eSApple OSS Distributions T_DECL(bpf_write_4096_mtu_9000, "BPF write 4096 feth MTU 9000")
370*0f4c859eSApple OSS Distributions {
371*0f4c859eSApple OSS Distributions test_bpf_write(4096, 9000, true, 0);
372*0f4c859eSApple OSS Distributions }
373*0f4c859eSApple OSS Distributions
374*0f4c859eSApple OSS Distributions T_DECL(bpf_write_8192_mtu_9000, "BPF write 8192 feth MTU 9000")
375*0f4c859eSApple OSS Distributions {
376*0f4c859eSApple OSS Distributions test_bpf_write(8192, 9000, true, 0);
377*0f4c859eSApple OSS Distributions }
378*0f4c859eSApple OSS Distributions
379*0f4c859eSApple OSS Distributions T_DECL(bpf_write_9000_mtu_9000, "BPF write 9000 feth MTU 9000")
380*0f4c859eSApple OSS Distributions {
381*0f4c859eSApple OSS Distributions test_bpf_write(9000, 9000, true, 0);
382*0f4c859eSApple OSS Distributions }
383*0f4c859eSApple OSS Distributions
384*0f4c859eSApple OSS Distributions T_DECL(bpf_write_9018_mtu_9000, "BPF write 9018 feth MTU 9000")
385*0f4c859eSApple OSS Distributions {
386*0f4c859eSApple OSS Distributions test_bpf_write(9018, 9000, true, 0);
387*0f4c859eSApple OSS Distributions }
388*0f4c859eSApple OSS Distributions
389*0f4c859eSApple OSS Distributions T_DECL(bpf_write_16370_mtu_9000, "BPF write 16370 feth MTU 9000")
390*0f4c859eSApple OSS Distributions {
391*0f4c859eSApple OSS Distributions test_bpf_write(16370, 9000, false, 0);
392*0f4c859eSApple OSS Distributions }
393*0f4c859eSApple OSS Distributions
394*0f4c859eSApple OSS Distributions T_DECL(bpf_write_16370_mtu_9000_max_16370, "BPF write 16370 feth MTU 9000 max 16370")
395*0f4c859eSApple OSS Distributions {
396*0f4c859eSApple OSS Distributions test_bpf_write(16370, 9000, true, 16370);
397*0f4c859eSApple OSS Distributions }
398