1/*
2 * Copyright (c) 2000-2014 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */
29/*!
30	@header kern_event.h
31	This header defines in-kernel functions for generating kernel events as
32	well as functions for receiving kernel events using a kernel event
33	socket.
34 */
35
36#ifndef SYS_KERN_EVENT_H
37#define	SYS_KERN_EVENT_H
38
39#include <sys/appleapiopts.h>
40#include <sys/ioccom.h>
41#include <sys/sys_domain.h>
42
43#define	KEV_SNDSPACE	(4 * 1024)
44#define	KEV_RECVSPACE	(32 * 1024)
45
46#define	KEV_ANY_VENDOR		0
47#define	KEV_ANY_CLASS		0
48#define	KEV_ANY_SUBCLASS	0
49
50/*
51 * Vendor Code
52 */
53
54/*!
55	@defined KEV_VENDOR_APPLE
56	@discussion Apple generated kernel events use the hard coded vendor code
57	value of 1. Third party kernel events use a dynamically allocated vendor
58	code. The vendor code can be found using the SIOCGKEVVENDOR ioctl.
59*/
60#define	KEV_VENDOR_APPLE	1
61
62/*
63 * Definition of top-level classifications for KEV_VENDOR_APPLE
64 */
65
66/*!
67	@defined KEV_NETWORK_CLASS
68	@discussion Network kernel event class.
69 */
70#define	KEV_NETWORK_CLASS	1
71
72/*!
73	@defined KEV_IOKIT_CLASS
74	@discussion IOKit kernel event class.
75 */
76#define	KEV_IOKIT_CLASS		2
77
78/*!
79	@defined KEV_SYSTEM_CLASS
80	@discussion System kernel event class.
81 */
82#define	KEV_SYSTEM_CLASS	3
83
84/*!
85	@defined KEV_APPLESHARE_CLASS
86	@discussion AppleShare kernel event class.
87 */
88#define	KEV_APPLESHARE_CLASS	4
89
90/*!
91	@defined KEV_FIREWALL_CLASS
92	@discussion Firewall kernel event class.
93 */
94#define	KEV_FIREWALL_CLASS	5
95
96/*!
97	@defined KEV_IEEE80211_CLASS
98	@discussion IEEE 802.11 kernel event class.
99 */
100#define	KEV_IEEE80211_CLASS	6
101
102/*!
103	@struct kern_event_msg
104	@discussion This structure is prepended to all kernel events. This
105		structure is used to determine the format of the remainder of
106		the kernel event. This structure will appear on all messages
107		received on a kernel event socket. To post a kernel event, a
108		slightly different structure is used.
109	@field total_size Total size of the kernel event message including the
110		header.
111	@field vendor_code The vendor code indicates which vendor generated the
112		kernel event. This gives every vendor a unique set of classes
113		and subclasses to use. Use the SIOCGKEVVENDOR ioctl to look up
114		vendor codes for vendors other than Apple. Apple uses
115		KEV_VENDOR_APPLE.
116	@field kev_class The class of the kernel event.
117	@field kev_subclass The subclass of the kernel event.
118	@field id Monotonically increasing value.
119	@field event_code The event code.
120	@field event_data Any additional data about this event. Format will
121		depend on the vendor_code, kev_class, kev_subclass, and
122		event_code. The length of the event_data can be determined
123		using total_size - KEV_MSG_HEADER_SIZE.
124 */
125struct kern_event_msg {
126	u_int32_t	total_size;	/* Size of entire event msg */
127	u_int32_t	vendor_code;	/* For non-Apple extensibility */
128	u_int32_t	kev_class;	/* Layer of event source */
129	u_int32_t	kev_subclass;	/* Component within layer */
130	u_int32_t	id;		/* Monotonically increasing value */
131	u_int32_t	event_code;	/* unique code */
132	u_int32_t	event_data[1];	/* One or more data words */
133};
134
135/*!
136	@defined KEV_MSG_HEADER_SIZE
137	@discussion Size of the header portion of the kern_event_msg structure.
138		This accounts for everything right up to event_data. The size
139		of the data can be found by subtracting KEV_MSG_HEADER_SIZE
140		from the total size from the kern_event_msg.
141 */
142#define	KEV_MSG_HEADER_SIZE (offsetof(struct kern_event_msg, event_data[0]))
143
144/*!
145	@struct kev_request
146	@discussion This structure is used with the SIOCSKEVFILT and
147		SIOCGKEVFILT to set and get the control filter setting for a
148		kernel control socket.
149	@field total_size Total size of the kernel event message including the
150		header.
151	@field vendor_code All kernel events that don't match this vendor code
152		will be ignored. KEV_ANY_VENDOR can be used to receive kernel
153		events with any vendor code.
154	@field kev_class All kernel events that don't match this class will be
155		ignored. KEV_ANY_CLASS can be used to receive kernel events with
156		any class.
157	@field kev_subclass All kernel events that don't match this subclass
158		will be ignored. KEV_ANY_SUBCLASS can be used to receive kernel
159		events with any subclass.
160 */
161struct kev_request {
162	u_int32_t	vendor_code;
163	u_int32_t	kev_class;
164	u_int32_t	kev_subclass;
165};
166
167/*!
168	@defined KEV_VENDOR_CODE_MAX_STR_LEN
169	@discussion This define sets the maximum length of a string that can be
170		used to identify a vendor or kext when looking up a vendor code.
171 */
172#define	KEV_VENDOR_CODE_MAX_STR_LEN	200
173
174/*!
175	@struct kev_vendor_code
176	@discussion This structure is used with the SIOCGKEVVENDOR ioctl to
177		convert from a string identifying a kext or vendor, in the
178		form of a bundle identifier, to a vendor code.
179	@field vendor_code After making the SIOCGKEVVENDOR ioctl call, this will
180		be filled in with the vendor code if there is one.
181	@field vendor_string A bundle style identifier.
182 */
183#pragma pack(4)
184struct kev_vendor_code {
185	u_int32_t	vendor_code;
186	char		vendor_string[KEV_VENDOR_CODE_MAX_STR_LEN];
187};
188#pragma pack()
189
190/*!
191	@defined SIOCGKEVID
192	@discussion Retrieve the current event id. Each event generated will
193		have a new id. The next event to be generated will have an id
194		of id+1.
195 */
196#define	SIOCGKEVID	_IOR('e', 1, u_int32_t)
197
198/*!
199	@defined SIOCSKEVFILT
200	@discussion Set the kernel event filter for this socket. Kernel events
201		not matching this filter will not be received on this socket.
202 */
203#define	SIOCSKEVFILT	_IOW('e', 2, struct kev_request)
204
205/*!
206	@defined SIOCGKEVFILT
207	@discussion Retrieve the kernel event filter for this socket. Kernel
208		events not matching this filter will not be received on this
209		socket.
210 */
211#define	SIOCGKEVFILT	_IOR('e', 3, struct kev_request)
212
213/*!
214	@defined SIOCGKEVVENDOR
215	@discussion Lookup the vendor code for the specified vendor. ENOENT will
216		be returned if a vendor code for that vendor string does not
217		exist.
218 */
219#define	SIOCGKEVVENDOR	_IOWR('e', 4, struct kev_vendor_code)
220
221#ifdef PRIVATE
222struct xkevtpcb {
223	u_int32_t	kep_len;
224	u_int32_t	kep_kind;
225	u_int64_t	kep_evtpcb;
226	u_int32_t 	kep_vendor_code_filter;
227	u_int32_t 	kep_class_filter;
228	u_int32_t 	kep_subclass_filter;
229};
230
231struct kevtstat {
232	u_int64_t	kes_pcbcount __attribute__((aligned(8)));
233	u_int64_t	kes_gencnt __attribute__((aligned(8)));
234	u_int64_t	kes_badvendor __attribute__((aligned(8)));
235	u_int64_t	kes_toobig __attribute__((aligned(8)));
236	u_int64_t	kes_nomem __attribute__((aligned(8)));
237	u_int64_t	kes_fullsock __attribute__((aligned(8)));
238	u_int64_t	kes_posted __attribute__((aligned(8)));
239
240};
241#endif /* PRIVATE */
242
243#ifdef KERNEL
244/*!
245	@define N_KEV_VECTORS
246	@discussion The maximum number of kev_d_vectors for a kernel event.
247 */
248#define	N_KEV_VECTORS	5
249
250/*!
251	@struct kev_d_vectors
252	@discussion This structure is used to append some data to a kernel
253		event.
254	@field data_length The length of data.
255	@field data_ptr A pointer to data.
256 */
257struct kev_d_vectors {
258	u_int32_t	data_length;	/* Length of the event data */
259	void		*data_ptr;	/* Pointer to event data */
260};
261
262/*!
263	@struct kev_msg
264	@discussion This structure is used when posting a kernel event.
265	@field vendor_code The vendor code assigned by kev_vendor_code_find.
266	@field kev_class The event's class.
267	@field kev_class The event's subclass.
268	@field kev_class The event's code.
269	@field dv An array of vectors describing additional data to be appended
270		to the kernel event.
271 */
272struct kev_msg {
273	u_int32_t vendor_code;		/* For non-Apple extensibility */
274	u_int32_t kev_class;		/* Layer of event source */
275	u_int32_t kev_subclass;		/* Component within layer */
276	u_int32_t event_code;		/* The event code */
277	struct kev_d_vectors dv[N_KEV_VECTORS];	/* Up to n data vectors */
278};
279
280/*!
281	@function kev_vendor_code_find
282	@discussion Lookup a vendor_code given a unique string. If the vendor
283		code has not been used since launch, a unique integer will be
284		assigned for that string. Vendor codes will remain the same
285		until the machine is rebooted.
286	@param vendor_string A bundle style vendor identifier(i.e. com.apple).
287	@param vendor_code Upon return, a unique vendor code for use when
288		posting kernel events.
289	@result May return ENOMEM if memory constraints prevent allocation of a
290		new vendor code.
291 */
292errno_t	kev_vendor_code_find(const char *vendor_string, u_int32_t *vendor_code);
293
294/*!
295	@function kev_msg_post
296	@discussion Post a kernel event message.
297	@param event_msg A structure defining the kernel event message to post.
298	@result Will return zero upon success. May return a number of errors
299		depending on the type of failure. EINVAL indicates that there
300		was something wrong with the kerne event. The vendor code of
301		the kernel event must be assigned using kev_vendor_code_find.
302		If the message is too large, EMSGSIZE will be returned.
303 */
304errno_t kev_msg_post(struct kev_msg *event_msg);
305
306#ifdef PRIVATE
307/*
308 * Internal version of kev_msg_post. Allows posting Apple vendor code kernel
309 * events.
310 */
311int	kev_post_msg(struct kev_msg *event);
312
313LIST_HEAD(kern_event_head, kern_event_pcb);
314
315struct kern_event_pcb {
316	decl_lck_mtx_data(, evp_mtx);	/* per-socket mutex */
317	LIST_ENTRY(kern_event_pcb) evp_link;	/* glue on list of all PCBs */
318	struct socket *evp_socket;		/* pointer back to socket */
319	u_int32_t evp_vendor_code_filter;
320	u_int32_t evp_class_filter;
321	u_int32_t evp_subclass_filter;
322};
323
324#define	sotoevpcb(so)   ((struct kern_event_pcb *)((so)->so_pcb))
325
326#endif /* PRIVATE */
327#endif /* KERNEL */
328#endif /* SYS_KERN_EVENT_H */
329