xref: /xnu-11417.140.69/bsd/net/kctl_test.c (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1*43a90889SApple OSS Distributions /*
2*43a90889SApple OSS Distributions  * Copyright (c) 2023 Apple Computer, Inc. All rights reserved.
3*43a90889SApple OSS Distributions  *
4*43a90889SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*43a90889SApple OSS Distributions  *
6*43a90889SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*43a90889SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*43a90889SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*43a90889SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*43a90889SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*43a90889SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*43a90889SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*43a90889SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*43a90889SApple OSS Distributions  *
15*43a90889SApple OSS Distributions  * Please obtain a copy of the License at
16*43a90889SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*43a90889SApple OSS Distributions  *
18*43a90889SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*43a90889SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*43a90889SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*43a90889SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*43a90889SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*43a90889SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*43a90889SApple OSS Distributions  * limitations under the License.
25*43a90889SApple OSS Distributions  *
26*43a90889SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*43a90889SApple OSS Distributions  */
28*43a90889SApple OSS Distributions 
29*43a90889SApple OSS Distributions #include <mach/vm_types.h>
30*43a90889SApple OSS Distributions #include <mach/kmod.h>
31*43a90889SApple OSS Distributions #include <sys/socket.h>
32*43a90889SApple OSS Distributions #include <sys/syslog.h>
33*43a90889SApple OSS Distributions #include <sys/errno.h>
34*43a90889SApple OSS Distributions #include <netinet/in.h>
35*43a90889SApple OSS Distributions 
36*43a90889SApple OSS Distributions #include <sys/kern_control.h>
37*43a90889SApple OSS Distributions #include <libkern/libkern.h>
38*43a90889SApple OSS Distributions #include <os/log.h>
39*43a90889SApple OSS Distributions 
40*43a90889SApple OSS Distributions #include <net/kctl_test.h>
41*43a90889SApple OSS Distributions 
42*43a90889SApple OSS Distributions static errno_t kctl_test_connect(kern_ctl_ref kctlref, struct sockaddr_ctl *sac, void **unitinfo);
43*43a90889SApple OSS Distributions static errno_t kctl_test_disconnect(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo);
44*43a90889SApple OSS Distributions static errno_t kctl_test_send(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, mbuf_t m, int flags);
45*43a90889SApple OSS Distributions static errno_t kctl_test_setopt(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, int opt, void *data, size_t len);
46*43a90889SApple OSS Distributions static errno_t kctl_test_getopt(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, int opt, void *data, size_t *len);
47*43a90889SApple OSS Distributions static errno_t kctl_test_send_list(kern_ctl_ref kctlref, u_int32_t unit,
48*43a90889SApple OSS Distributions     void *unitinfo, mbuf_t m, int flags);
49*43a90889SApple OSS Distributions 
50*43a90889SApple OSS Distributions static struct kern_ctl_reg kctl_test_reg = {
51*43a90889SApple OSS Distributions 	.ctl_name = KCTL_TEST_CONTROL_NAME,
52*43a90889SApple OSS Distributions 	.ctl_id = 0,
53*43a90889SApple OSS Distributions 	.ctl_unit = 0,
54*43a90889SApple OSS Distributions 	.ctl_flags = CTL_FLAG_PRIVILEGED | CTL_FLAG_REG_EXTENDED,
55*43a90889SApple OSS Distributions 	.ctl_sendsize = 256 * 1024, /* 256 KiB */
56*43a90889SApple OSS Distributions 	.ctl_recvsize = 2 * 1024 * 1024, /* 2 MiB */
57*43a90889SApple OSS Distributions 	.ctl_connect = kctl_test_connect,
58*43a90889SApple OSS Distributions 	.ctl_disconnect = kctl_test_disconnect,
59*43a90889SApple OSS Distributions 	.ctl_send = kctl_test_send,
60*43a90889SApple OSS Distributions 	.ctl_setopt = kctl_test_setopt,
61*43a90889SApple OSS Distributions 	.ctl_getopt = kctl_test_getopt,
62*43a90889SApple OSS Distributions 	.ctl_send_list = kctl_test_send_list
63*43a90889SApple OSS Distributions };
64*43a90889SApple OSS Distributions static kern_ctl_ref kctl_test_ref;
65*43a90889SApple OSS Distributions static u_int32_t kctl_test_id;
66*43a90889SApple OSS Distributions 
67*43a90889SApple OSS Distributions 
68*43a90889SApple OSS Distributions static errno_t
kctl_test_connect(kern_ctl_ref kctlref,struct sockaddr_ctl * sac,void ** unitinfo)69*43a90889SApple OSS Distributions kctl_test_connect(kern_ctl_ref kctlref, struct sockaddr_ctl *sac, void **unitinfo)
70*43a90889SApple OSS Distributions {
71*43a90889SApple OSS Distributions #pragma unused(unitinfo)
72*43a90889SApple OSS Distributions 	errno_t error = 0;
73*43a90889SApple OSS Distributions 	size_t space;
74*43a90889SApple OSS Distributions 
75*43a90889SApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "kctl_test_connect: ref %p id %u port %u",
76*43a90889SApple OSS Distributions 	    kctlref, sac->sc_id, sac->sc_unit);
77*43a90889SApple OSS Distributions 
78*43a90889SApple OSS Distributions 	error = ctl_getenqueuespace(kctlref, sac->sc_unit, &space);
79*43a90889SApple OSS Distributions 	if (error != 0) {
80*43a90889SApple OSS Distributions 		os_log(OS_LOG_DEFAULT, "kctl_test_connect; ctl_getenqueuespace failed %d", error);
81*43a90889SApple OSS Distributions 		goto out;
82*43a90889SApple OSS Distributions 	}
83*43a90889SApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "kctl_test_connect: ctl_getenqueuespace %ld", space);
84*43a90889SApple OSS Distributions out:
85*43a90889SApple OSS Distributions 	return error;
86*43a90889SApple OSS Distributions }
87*43a90889SApple OSS Distributions 
88*43a90889SApple OSS Distributions static errno_t
kctl_test_disconnect(kern_ctl_ref kctlref,u_int32_t unit,void * unitinfo)89*43a90889SApple OSS Distributions kctl_test_disconnect(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo)
90*43a90889SApple OSS Distributions {
91*43a90889SApple OSS Distributions #pragma unused(unitinfo)
92*43a90889SApple OSS Distributions 	errno_t error = 0;
93*43a90889SApple OSS Distributions 	size_t space;
94*43a90889SApple OSS Distributions 
95*43a90889SApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "kctl_test_disconnect: ref %p", kctlref);
96*43a90889SApple OSS Distributions 
97*43a90889SApple OSS Distributions 	error = ctl_getenqueuespace(kctlref, unit, &space);
98*43a90889SApple OSS Distributions 	if (error != 0) {
99*43a90889SApple OSS Distributions 		os_log(OS_LOG_DEFAULT, "kctl_test_disconnect; ctl_getenqueuespace failed %d", error);
100*43a90889SApple OSS Distributions 		goto out;
101*43a90889SApple OSS Distributions 	}
102*43a90889SApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "kctl_test_disconnect: ctl_getenqueuespace %ld", space);
103*43a90889SApple OSS Distributions out:
104*43a90889SApple OSS Distributions 
105*43a90889SApple OSS Distributions 	return error;
106*43a90889SApple OSS Distributions }
107*43a90889SApple OSS Distributions 
108*43a90889SApple OSS Distributions static errno_t
kctl_test_send(kern_ctl_ref kctlref,u_int32_t unit,void * unitinfo,mbuf_t m,int flags)109*43a90889SApple OSS Distributions kctl_test_send(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, mbuf_t m, int flags)
110*43a90889SApple OSS Distributions {
111*43a90889SApple OSS Distributions #pragma unused(unitinfo, flags)
112*43a90889SApple OSS Distributions 	errno_t error = 0;
113*43a90889SApple OSS Distributions 
114*43a90889SApple OSS Distributions 	error = ctl_enqueuembuf(kctlref, unit, m, CTL_DATA_EOR);
115*43a90889SApple OSS Distributions 	if (error != 0) {
116*43a90889SApple OSS Distributions 		os_log(OS_LOG_DEFAULT, "kctl_test_send: ctl_enqueuembuf() failed %d", error);
117*43a90889SApple OSS Distributions 		mbuf_freem(m);
118*43a90889SApple OSS Distributions 	}
119*43a90889SApple OSS Distributions 
120*43a90889SApple OSS Distributions 	return error;
121*43a90889SApple OSS Distributions }
122*43a90889SApple OSS Distributions 
123*43a90889SApple OSS Distributions static int optval = 0;
124*43a90889SApple OSS Distributions 
125*43a90889SApple OSS Distributions static errno_t
kctl_test_setopt(kern_ctl_ref kctlref,u_int32_t unit,void * unitinfo,int opt,void * data,size_t len)126*43a90889SApple OSS Distributions kctl_test_setopt(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, int opt, void *data, size_t len)
127*43a90889SApple OSS Distributions {
128*43a90889SApple OSS Distributions #pragma unused(unit, unitinfo)
129*43a90889SApple OSS Distributions 	errno_t error = 0;
130*43a90889SApple OSS Distributions 
131*43a90889SApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "kctl_test_setopt: ref %p", kctlref);
132*43a90889SApple OSS Distributions 
133*43a90889SApple OSS Distributions 	switch (opt) {
134*43a90889SApple OSS Distributions 	case 0:
135*43a90889SApple OSS Distributions 		if (len < sizeof(int)) {
136*43a90889SApple OSS Distributions 			error = EINVAL;
137*43a90889SApple OSS Distributions 		} else {
138*43a90889SApple OSS Distributions 			optval = *(int*)data;
139*43a90889SApple OSS Distributions 		}
140*43a90889SApple OSS Distributions 		break;
141*43a90889SApple OSS Distributions 	default:
142*43a90889SApple OSS Distributions 		error = ENOPROTOOPT;
143*43a90889SApple OSS Distributions 		break;
144*43a90889SApple OSS Distributions 	}
145*43a90889SApple OSS Distributions 
146*43a90889SApple OSS Distributions 	return error;
147*43a90889SApple OSS Distributions }
148*43a90889SApple OSS Distributions 
149*43a90889SApple OSS Distributions static errno_t
kctl_test_getopt(kern_ctl_ref kctlref,u_int32_t unit,void * unitinfo,int opt,void * data,size_t * len)150*43a90889SApple OSS Distributions kctl_test_getopt(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, int opt, void *data, size_t *len)
151*43a90889SApple OSS Distributions {
152*43a90889SApple OSS Distributions #pragma unused(unitinfo, unit)
153*43a90889SApple OSS Distributions 	errno_t error = 0;
154*43a90889SApple OSS Distributions 
155*43a90889SApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "kctl_test_getopt: ref %p", kctlref);
156*43a90889SApple OSS Distributions 
157*43a90889SApple OSS Distributions 	switch (opt) {
158*43a90889SApple OSS Distributions 	case 0:
159*43a90889SApple OSS Distributions 		if (*len < sizeof(int)) {
160*43a90889SApple OSS Distributions 			error = EINVAL;
161*43a90889SApple OSS Distributions 		} else {
162*43a90889SApple OSS Distributions 			*(int*)data = optval;
163*43a90889SApple OSS Distributions 			*len = sizeof(int);
164*43a90889SApple OSS Distributions 		}
165*43a90889SApple OSS Distributions 		break;
166*43a90889SApple OSS Distributions 	default:
167*43a90889SApple OSS Distributions 		error = ENOPROTOOPT;
168*43a90889SApple OSS Distributions 		break;
169*43a90889SApple OSS Distributions 	}
170*43a90889SApple OSS Distributions 
171*43a90889SApple OSS Distributions 	return error;
172*43a90889SApple OSS Distributions }
173*43a90889SApple OSS Distributions 
174*43a90889SApple OSS Distributions static errno_t
kctl_test_send_list(kern_ctl_ref kctlref,u_int32_t unit,void * unitinfo,mbuf_t m,int flags)175*43a90889SApple OSS Distributions kctl_test_send_list(kern_ctl_ref kctlref, u_int32_t unit,
176*43a90889SApple OSS Distributions     void *unitinfo, mbuf_t m, int flags)
177*43a90889SApple OSS Distributions {
178*43a90889SApple OSS Distributions #pragma unused(unitinfo)
179*43a90889SApple OSS Distributions 	errno_t error = 0;
180*43a90889SApple OSS Distributions 	mbuf_ref_t m_remain = NULL;
181*43a90889SApple OSS Distributions 	uint32_t unsent_count = 0;
182*43a90889SApple OSS Distributions 
183*43a90889SApple OSS Distributions 	error = ctl_enqueuembuf_list(kctlref, unit, m, flags, &m_remain);
184*43a90889SApple OSS Distributions 	if (m_remain != NULL) {
185*43a90889SApple OSS Distributions 		mbuf_ref_t tmp = m_remain;
186*43a90889SApple OSS Distributions 
187*43a90889SApple OSS Distributions 		while (tmp != NULL) {
188*43a90889SApple OSS Distributions 			unsent_count += 1;
189*43a90889SApple OSS Distributions 			tmp = mbuf_next(tmp);
190*43a90889SApple OSS Distributions 		}
191*43a90889SApple OSS Distributions 
192*43a90889SApple OSS Distributions 		mbuf_freem_list(m_remain);
193*43a90889SApple OSS Distributions 	}
194*43a90889SApple OSS Distributions 	if (error != 0) {
195*43a90889SApple OSS Distributions 		os_log(OS_LOG_DEFAULT, "kctl_test_send_list: ctl_enqueuembuf_list() error %d unsent packets %u",
196*43a90889SApple OSS Distributions 		    error, unsent_count);
197*43a90889SApple OSS Distributions 	}
198*43a90889SApple OSS Distributions 	return error;
199*43a90889SApple OSS Distributions }
200*43a90889SApple OSS Distributions 
201*43a90889SApple OSS Distributions int
kctl_test_init(void)202*43a90889SApple OSS Distributions kctl_test_init(void)
203*43a90889SApple OSS Distributions {
204*43a90889SApple OSS Distributions 	errno_t error = 0;
205*43a90889SApple OSS Distributions 	struct kern_ctl_reg kern_ctl_reg = kctl_test_reg;
206*43a90889SApple OSS Distributions 
207*43a90889SApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "kctl_test_init ctl_sendsize %u ctl_recvsize %u",
208*43a90889SApple OSS Distributions 	    kctl_test_reg.ctl_sendsize, kctl_test_reg.ctl_recvsize);
209*43a90889SApple OSS Distributions 
210*43a90889SApple OSS Distributions 	error = ctl_register(&kern_ctl_reg, &kctl_test_ref);
211*43a90889SApple OSS Distributions 	if (error == 0) {
212*43a90889SApple OSS Distributions 		kctl_test_id = kern_ctl_reg.ctl_id;
213*43a90889SApple OSS Distributions 		os_log(OS_LOG_DEFAULT, "kctl_test_register: OK kctlref %p kctlid %x ctl_sendsize %u ctl_recvsize %u",
214*43a90889SApple OSS Distributions 		    kctl_test_ref, kctl_test_id, kern_ctl_reg.ctl_sendsize, kern_ctl_reg.ctl_recvsize);
215*43a90889SApple OSS Distributions 	} else {
216*43a90889SApple OSS Distributions 		os_log(OS_LOG_DEFAULT, "kctl_test_register: error %d", error);
217*43a90889SApple OSS Distributions 	}
218*43a90889SApple OSS Distributions 	return (error == 0) ? KERN_SUCCESS : KERN_FAILURE;
219*43a90889SApple OSS Distributions }
220