1 /*
2 * Copyright (c) 2019-2021 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
29
30 #include <stddef.h>
31 #include <stdint.h>
32 #include <errno.h>
33 #include <skywalk/os_packet.h>
34 #include <skywalk/os_channel_event.h>
35
36 #ifndef LIBSYSCALL_INTERFACE
37 #error "LIBSYSCALL_INTERFACE not defined"
38 #endif /* !LIBSYSCALL_INTERFACE */
39
40 int
os_channel_event_get_next_event(const os_channel_event_handle_t event_handle,const os_channel_event_t prev_event,os_channel_event_t * event)41 os_channel_event_get_next_event(const os_channel_event_handle_t event_handle,
42 const os_channel_event_t prev_event, os_channel_event_t *event)
43 {
44 struct __kern_channel_event *cev, *pev;
45 buflet_t buflet;
46 uint16_t bdlen;
47 char *baddr, *estart;
48
49 *event = NULL;
50 if (!event_handle) {
51 return EINVAL;
52 }
53 buflet = os_packet_get_next_buflet(event_handle, NULL);
54 if (__improbable(buflet == NULL)) {
55 return EINVAL;
56 }
57 baddr = os_buflet_get_object_address(buflet);
58 if (__improbable(baddr == NULL)) {
59 return ENXIO;
60 }
61 bdlen = os_buflet_get_data_length(buflet);
62 baddr += os_buflet_get_data_offset(buflet);
63 estart = baddr + __KERN_CHANNEL_EVENT_OFFSET;
64 pev = (struct __kern_channel_event *)prev_event;
65 if (pev == NULL) {
66 cev = (struct __kern_channel_event *)estart;
67 } else {
68 if ((pev->ev_flags & CHANNEL_EVENT_FLAG_MORE_EVENT) == 0) {
69 return ENODATA;
70 }
71 cev = (struct __kern_channel_event *)((char *)pev + sizeof(*pev) +
72 pev->ev_dlen);
73 }
74 if (__improbable((char *)cev < estart)) {
75 return ENXIO;
76 }
77 if (__improbable((cev->ev_dlen + (char *)cev) > (baddr + bdlen))) {
78 return ENXIO;
79 }
80 *event = (os_channel_event_t)cev;
81 return 0;
82 }
83
84 int
os_channel_event_get_event_data(const os_channel_event_t event,struct os_channel_event_data * event_data)85 os_channel_event_get_event_data(const os_channel_event_t event,
86 struct os_channel_event_data *event_data)
87 {
88 struct __kern_channel_event *kev;
89
90 if (__improbable(event == 0 || event_data == NULL)) {
91 return EINVAL;
92 }
93 kev = (struct __kern_channel_event *)event;
94 if (__improbable(kev->ev_type < CHANNEL_EVENT_MIN ||
95 kev->ev_type > CHANNEL_EVENT_MAX)) {
96 return ENXIO;
97 }
98 event_data->event_type = kev->ev_type;
99 event_data->event_more =
100 (kev->ev_flags & CHANNEL_EVENT_FLAG_MORE_EVENT) != 0;
101 event_data->event_data_length = kev->ev_dlen;
102 event_data->event_data = kev->ev_data;
103 return 0;
104 }
105