2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 * @(#)kern_event.c 1.0 (3/31/2000)
30 #include <sys/param.h>
31 #include <sys/socket.h>
32 #include <sys/protosw.h>
33 #include <sys/domain.h>
35 #include <sys/kern_event.h>
36 #include <sys/malloc.h>
37 #include <sys/sys_domain.h>
38 #include <sys/syslog.h>
42 struct pr_usrreqs event_usrreqs
;
44 struct protosw eventsw
[] = {
46 SOCK_RAW
, &systemdomain
, SYSPROTO_EVENT
, PR_ATOMIC
,
55 struct kern_event_head kern_event_head
;
57 static u_long static_event_id
= 0;
60 * Install the protosw's for the NKE manager. Invoked at
68 if ((retval
= net_add_proto(eventsw
, &systemdomain
)) == 0)
71 log(LOG_WARNING
, "Can't install kernel events protocol (%d)\n", retval
);
75 int kev_attach(struct socket
*so
, int proto
, struct proc
*p
)
78 struct kern_event_pcb
*ev_pcb
;
80 ev_pcb
= _MALLOC(sizeof(struct kern_event_pcb
), M_PCB
, M_WAITOK
);
84 ev_pcb
->ev_socket
= so
;
85 ev_pcb
->vendor_code_filter
= 0xffffffff;
87 so
->so_pcb
= (caddr_t
) ev_pcb
;
88 LIST_INSERT_HEAD(&kern_event_head
, ev_pcb
, ev_link
);
89 error
= soreserve(so
, KEV_SNDSPACE
, KEV_RECVSPACE
);
97 int kev_detach(struct socket
*so
)
99 struct kern_event_pcb
*ev_pcb
= (struct kern_event_pcb
*) so
->so_pcb
;
101 LIST_REMOVE(ev_pcb
, ev_link
);
109 int kev_post_msg(struct kev_msg
*event_msg
)
112 struct kern_event_pcb
*ev_pcb
;
113 struct kern_event_msg
*ev
;
119 m
= m_get(M_DONTWAIT
, MT_DATA
);
123 ev
= mtod(m
, struct kern_event_msg
*);
124 total_size
= KEV_MSG_HEADER_SIZE
;
126 tmp
= (char *) &ev
->event_data
[0];
127 for (i
= 0; i
< 5; i
++) {
128 if (event_msg
->dv
[i
].data_length
== 0)
131 total_size
+= event_msg
->dv
[i
].data_length
;
132 bcopy(event_msg
->dv
[i
].data_ptr
, tmp
,
133 event_msg
->dv
[i
].data_length
);
134 tmp
+= event_msg
->dv
[i
].data_length
;
138 ev
->id
= ++static_event_id
;
139 ev
->total_size
= total_size
;
140 ev
->vendor_code
= event_msg
->vendor_code
;
141 ev
->kev_class
= event_msg
->kev_class
;
142 ev
->kev_subclass
= event_msg
->kev_subclass
;
143 ev
->event_code
= event_msg
->event_code
;
145 m
->m_len
= total_size
;
146 for (ev_pcb
= LIST_FIRST(&kern_event_head
);
148 ev_pcb
= LIST_NEXT(ev_pcb
, ev_link
)) {
150 if (ev_pcb
->vendor_code_filter
!= KEV_ANY_VENDOR
) {
151 if (ev_pcb
->vendor_code_filter
!= ev
->vendor_code
)
154 if (ev_pcb
->class_filter
!= KEV_ANY_CLASS
) {
155 if (ev_pcb
->class_filter
!= ev
->kev_class
)
158 if ((ev_pcb
->subclass_filter
!= KEV_ANY_SUBCLASS
) &&
159 (ev_pcb
->subclass_filter
!= ev
->kev_subclass
))
164 m2
= m_copym(m
, 0, m
->m_len
, M_NOWAIT
);
170 sbappendrecord(&ev_pcb
->ev_socket
->so_rcv
, m2
);
171 sorwakeup(ev_pcb
->ev_socket
);
180 int kev_control(so
, cmd
, data
, ifp
, p
)
184 register struct ifnet
*ifp
;
187 struct kev_request
*kev_req
= (struct kev_request
*) data
;
189 struct kern_event_pcb
*ev_pcb
;
190 u_long
*id_value
= (u_long
*) data
;
196 *id_value
= static_event_id
;
200 ev_pcb
= (struct kern_event_pcb
*) so
->so_pcb
;
201 ev_pcb
->vendor_code_filter
= kev_req
->vendor_code
;
202 ev_pcb
->class_filter
= kev_req
->kev_class
;
203 ev_pcb
->subclass_filter
= kev_req
->kev_subclass
;
207 ev_pcb
= (struct kern_event_pcb
*) so
->so_pcb
;
208 kev_req
->vendor_code
= ev_pcb
->vendor_code_filter
;
209 kev_req
->kev_class
= ev_pcb
->class_filter
;
210 kev_req
->kev_subclass
= ev_pcb
->subclass_filter
;
221 struct pr_usrreqs event_usrreqs
= {
222 pru_abort_notsupp
, pru_accept_notsupp
, kev_attach
, pru_bind_notsupp
, pru_connect_notsupp
,
223 pru_connect2_notsupp
, kev_control
, kev_detach
, pru_disconnect_notsupp
,
224 pru_listen_notsupp
, pru_peeraddr_notsupp
, pru_rcvd_notsupp
, pru_rcvoob_notsupp
,
225 pru_send_notsupp
, pru_sense_null
, pru_shutdown_notsupp
, pru_sockaddr_notsupp
,
226 pru_sosend_notsupp
, soreceive
, sopoll