2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
24 * @(#)kern_event.c 1.0 (3/31/2000)
27 #include <sys/param.h>
28 #include <sys/socket.h>
29 #include <sys/protosw.h>
30 #include <sys/domain.h>
32 #include <sys/kern_event.h>
33 #include <sys/malloc.h>
34 #include <sys/sys_domain.h>
35 #include <sys/syslog.h>
39 struct pr_usrreqs event_usrreqs
;
41 struct protosw eventsw
[] = {
43 SOCK_RAW
, &systemdomain
, SYSPROTO_EVENT
, PR_ATOMIC
,
52 struct kern_event_head kern_event_head
;
54 static u_long static_event_id
= 0;
57 * Install the protosw's for the NKE manager. Invoked at
65 if ((retval
= net_add_proto(eventsw
, &systemdomain
)) == 0)
68 log(LOG_WARNING
, "Can't install kernel events protocol (%d)\n", retval
);
72 int kev_attach(struct socket
*so
, int proto
, struct proc
*p
)
75 struct kern_event_pcb
*ev_pcb
;
77 ev_pcb
= _MALLOC(sizeof(struct kern_event_pcb
), M_PCB
, M_WAITOK
);
81 ev_pcb
->ev_socket
= so
;
82 ev_pcb
->vendor_code_filter
= 0xffffffff;
84 so
->so_pcb
= (caddr_t
) ev_pcb
;
85 LIST_INSERT_HEAD(&kern_event_head
, ev_pcb
, ev_link
);
86 error
= soreserve(so
, KEV_SNDSPACE
, KEV_RECVSPACE
);
94 int kev_detach(struct socket
*so
)
96 struct kern_event_pcb
*ev_pcb
= (struct kern_event_pcb
*) so
->so_pcb
;
98 LIST_REMOVE(ev_pcb
, ev_link
);
106 int kev_post_msg(struct kev_msg
*event_msg
)
109 struct kern_event_pcb
*ev_pcb
;
110 struct kern_event_msg
*ev
;
116 m
= m_get(M_DONTWAIT
, MT_DATA
);
120 ev
= mtod(m
, struct kern_event_msg
*);
121 total_size
= KEV_MSG_HEADER_SIZE
;
123 tmp
= (char *) &ev
->event_data
[0];
124 for (i
= 0; i
< 5; i
++) {
125 if (event_msg
->dv
[i
].data_length
== 0)
128 total_size
+= event_msg
->dv
[i
].data_length
;
129 bcopy(event_msg
->dv
[i
].data_ptr
, tmp
,
130 event_msg
->dv
[i
].data_length
);
131 tmp
+= event_msg
->dv
[i
].data_length
;
135 ev
->id
= ++static_event_id
;
136 ev
->total_size
= total_size
;
137 ev
->vendor_code
= event_msg
->vendor_code
;
138 ev
->kev_class
= event_msg
->kev_class
;
139 ev
->kev_subclass
= event_msg
->kev_subclass
;
140 ev
->event_code
= event_msg
->event_code
;
142 m
->m_len
= total_size
;
143 for (ev_pcb
= LIST_FIRST(&kern_event_head
);
145 ev_pcb
= LIST_NEXT(ev_pcb
, ev_link
)) {
147 if (ev_pcb
->vendor_code_filter
!= KEV_ANY_VENDOR
) {
148 if (ev_pcb
->vendor_code_filter
!= ev
->vendor_code
)
151 if (ev_pcb
->class_filter
!= KEV_ANY_CLASS
) {
152 if (ev_pcb
->class_filter
!= ev
->kev_class
)
155 if ((ev_pcb
->subclass_filter
!= KEV_ANY_SUBCLASS
) &&
156 (ev_pcb
->subclass_filter
!= ev
->kev_subclass
))
161 m2
= m_copym(m
, 0, m
->m_len
, M_NOWAIT
);
167 sbappendrecord(&ev_pcb
->ev_socket
->so_rcv
, m2
);
168 sorwakeup(ev_pcb
->ev_socket
);
177 int kev_control(so
, cmd
, data
, ifp
, p
)
181 register struct ifnet
*ifp
;
184 struct kev_request
*kev_req
= (struct kev_request
*) data
;
186 struct kern_event_pcb
*ev_pcb
;
187 u_long
*id_value
= (u_long
*) data
;
193 *id_value
= static_event_id
;
197 ev_pcb
= (struct kern_event_pcb
*) so
->so_pcb
;
198 ev_pcb
->vendor_code_filter
= kev_req
->vendor_code
;
199 ev_pcb
->class_filter
= kev_req
->kev_class
;
200 ev_pcb
->subclass_filter
= kev_req
->kev_subclass
;
204 ev_pcb
= (struct kern_event_pcb
*) so
->so_pcb
;
205 kev_req
->vendor_code
= ev_pcb
->vendor_code_filter
;
206 kev_req
->kev_class
= ev_pcb
->class_filter
;
207 kev_req
->kev_subclass
= ev_pcb
->subclass_filter
;
218 struct pr_usrreqs event_usrreqs
= {
219 pru_abort_notsupp
, pru_accept_notsupp
, kev_attach
, pru_bind_notsupp
, pru_connect_notsupp
,
220 pru_connect2_notsupp
, kev_control
, kev_detach
, pru_disconnect_notsupp
,
221 pru_listen_notsupp
, pru_peeraddr_notsupp
, pru_rcvd_notsupp
, pru_rcvoob_notsupp
,
222 pru_send_notsupp
, pru_sense_null
, pru_shutdown_notsupp
, pru_sockaddr_notsupp
,
223 pru_sosend_notsupp
, soreceive
, sopoll