2 * Copyright (c) 2013-2014 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/errno.h>
30 #include <sys/sysctl.h>
31 #include <net/content_filter.h>
39 #define IPPROTOCOL_TCP 6
40 #define IPPROTOCOL_UDP 17
45 size_t total_len
, curr_len
;
50 if (sysctlbyname("net.cfil.filter_list", NULL
, &total_len
, NULL
, 0) == -1)
51 err(1, "sysctlbyname(net.cfil.filter_list)");
53 buffer
= malloc(total_len
);
56 if (sysctlbyname("net.cfil.filter_list", buffer
, &total_len
, NULL
, 0) == -1)
57 err(1, "sysctlbyname(net.cfil.filter_list)");
62 struct cfil_filter_stat
*filter_stat
;
64 filter_stat
= (struct cfil_filter_stat
*)ptr
;
66 if (curr_len
+ filter_stat
->cfs_len
> total_len
||
67 filter_stat
->cfs_len
< sizeof(struct cfil_filter_stat
))
71 printf("%10s %10s %10s %10s\n",
72 "filter", "flags", "count", "necpunit");
74 printf("%10u 0x%08x %10u %10u\n",
75 filter_stat
->cfs_filter_id
,
76 filter_stat
->cfs_flags
,
77 filter_stat
->cfs_sock_count
,
78 filter_stat
->cfs_necp_control_unit
);
80 ptr
+= filter_stat
->cfs_len
;
81 curr_len
+= filter_stat
->cfs_len
;
88 sprint_offset(char *str
, size_t len
, const char *fmt
, uint64_t offset
)
90 if (offset
== CFM_MAX_OFFSET
)
91 snprintf(str
, len
, "%s", "MAX");
93 snprintf(str
, len
, fmt
, offset
);
99 size_t total_len
, curr_len
;
104 if (sysctlbyname("net.cfil.sock_list", NULL
, &total_len
, NULL
, 0) == -1)
105 err(1, "sysctlbyname(net.cfil.sock_list)");
107 buffer
= malloc(total_len
);
110 if (sysctlbyname("net.cfil.sock_list", buffer
, &total_len
, NULL
, 0) == -1)
111 err(1, "sysctlbyname(net.cfil.sock_list)");
116 struct cfil_sock_stat
*sock_stat
;
119 char namebuffer
[256];
120 char *procName
= "<not found>";
122 sock_stat
= (struct cfil_sock_stat
*)ptr
;
124 if (curr_len
+ sock_stat
->cfs_len
> total_len
||
125 sock_stat
->cfs_len
< sizeof(struct cfil_sock_stat
))
128 if (proc_name(sock_stat
->cfs_e_pid
, namebuffer
, sizeof(namebuffer
)) > 0) {
129 procName
= namebuffer
;
132 sprint_offset(opass
, 32, "%8llu", sock_stat
->cfs_snd
.cbs_pass_offset
);
133 sprint_offset(ipass
, 32, "%8llu", sock_stat
->cfs_rcv
.cbs_pass_offset
);
135 printf("%16s %5s %10s "
136 "%8s %8s %8s %8s %8s %8s %8s "
137 "%8s %8s %8s %8s %8s %8s %8s "
139 "sockid", "proto", "flags",
140 "ofirst", "olast", "oqlen", " ", "opass", " ", " ",
141 "ifirst", "ilast", "iqlen", " ", "ipass", " ", " ",
142 "pid", "epid", "eprocname");
144 printf("%016llu %5s 0x%08llx "
145 "%8llu %8llu %8llu %8s %8s %8s %8s "
146 "%8llu %8llu %8llu %8s %8s %8s %8s "
149 sock_stat
->cfs_sock_id
,
150 sock_stat
->cfs_sock_protocol
== IPPROTOCOL_TCP
? "TCP" : "UDP",
151 sock_stat
->cfs_flags
,
153 sock_stat
->cfs_snd
.cbs_pending_first
,
154 sock_stat
->cfs_snd
.cbs_pending_last
,
155 sock_stat
->cfs_snd
.cbs_inject_q_len
,
161 sock_stat
->cfs_rcv
.cbs_pending_first
,
162 sock_stat
->cfs_rcv
.cbs_pending_last
,
163 sock_stat
->cfs_rcv
.cbs_inject_q_len
,
169 sock_stat
->cfs_e_pid
,
173 printf("%7s %10s %10s "
174 "%8s %8s %8s %8s %8s %8s %8s "
175 "%8s %8s %8s %8s %8s %8s %8s\n",
178 "octlfrst", "octllast", "opndfrst", "opndlast", "opass", "opked", "opeek",
179 "ictlfrst", "ictllast", "ipndfrst", "ipndlast", "ipass", "ipked", "ipeek");
180 for (i
= 0; i
< CFIL_MAX_FILTER_COUNT
; i
++) {
181 struct cfil_entry_stat
*estat
;
189 estat
= &sock_stat
->ces_entries
[i
];
191 sprint_offset(spass
, 32, "%8llu", estat
->ces_snd
.cbs_pass_offset
);
192 sprint_offset(speek
, 32, "%8llu", estat
->ces_snd
.cbs_peek_offset
);
193 sprint_offset(spked
, 32, "%8llu", estat
->ces_snd
.cbs_peeked
);
195 sprint_offset(rpass
, 32, "%8llu", estat
->ces_rcv
.cbs_pass_offset
);
196 sprint_offset(rpeek
, 32, "%8llu", estat
->ces_rcv
.cbs_peek_offset
);
197 sprint_offset(rpked
, 32, "%8llu", estat
->ces_rcv
.cbs_peeked
);
199 printf("%7s %10u 0x%08x "
200 "%8llu %8llu %8llu %8llu %8s %8s %8s "
201 "%8llu %8llu %8llu %8llu %8s %8s %8s\n",
204 estat
->ces_filter_id
,
207 estat
->ces_snd
.cbs_ctl_first
,
208 estat
->ces_snd
.cbs_ctl_last
,
209 estat
->ces_snd
.cbs_pending_first
,
210 estat
->ces_snd
.cbs_pending_last
,
215 estat
->ces_rcv
.cbs_ctl_first
,
216 estat
->ces_rcv
.cbs_ctl_last
,
217 estat
->ces_rcv
.cbs_pending_first
,
218 estat
->ces_rcv
.cbs_pending_last
,
225 ptr
+= sock_stat
->cfs_len
;
226 curr_len
+= sock_stat
->cfs_len
;
233 #define PR32(x) printf(#x " %u\n", stats-> x)
234 #define PR64(x) printf(#x " %llu\n", stats-> x)
238 size_t len
, alloc_len
;
240 struct cfil_stats
*stats
;
242 if (sysctlbyname("net.cfil.stats", NULL
, &len
, NULL
, 0) == -1)
243 err(1, "sysctlbyname(net.cfil.stats)");
245 if (len
< sizeof(struct cfil_stats
))
246 alloc_len
= sizeof(struct cfil_stats
);
250 buffer
= malloc(alloc_len
);
253 if (sysctlbyname("net.cfil.stats", buffer
, &len
, NULL
, 0) == -1)
254 err(1, "sysctlbyname(net.cfil.stats)");
255 stats
= (struct cfil_stats
*)buffer
;
257 PR32(cfs_ctl_connect_ok
);
258 PR32(cfs_ctl_connect_fail
);
259 PR32(cfs_ctl_connect_ok
);
260 PR32(cfs_ctl_connect_fail
);
261 PR32(cfs_ctl_disconnect_ok
);
262 PR32(cfs_ctl_disconnect_fail
);
263 PR32(cfs_ctl_send_ok
);
264 PR32(cfs_ctl_send_bad
);
265 PR32(cfs_ctl_rcvd_ok
);
266 PR32(cfs_ctl_rcvd_bad
);
267 PR32(cfs_ctl_rcvd_flow_lift
);
268 PR32(cfs_ctl_action_data_update
);
269 PR32(cfs_ctl_action_drop
);
270 PR32(cfs_ctl_action_bad_op
);
271 PR32(cfs_ctl_action_bad_len
);
273 PR32(cfs_sock_id_not_found
);
275 PR32(cfs_cfi_alloc_ok
);
276 PR32(cfs_cfi_alloc_fail
);
278 PR32(cfs_sock_userspace_only
);
279 PR32(cfs_sock_attach_in_vain
);
280 PR32(cfs_sock_attach_already
);
281 PR32(cfs_sock_attach_no_mem
);
282 PR32(cfs_sock_attach_failed
);
283 PR32(cfs_sock_attached
);
284 PR32(cfs_sock_detached
);
286 PR32(cfs_attach_event_ok
);
287 PR32(cfs_attach_event_flow_control
);
288 PR32(cfs_attach_event_fail
);
290 PR32(cfs_closed_event_ok
);
291 PR32(cfs_closed_event_flow_control
);
292 PR32(cfs_closed_event_fail
);
294 PR32(cfs_data_event_ok
);
295 PR32(cfs_data_event_flow_control
);
296 PR32(cfs_data_event_fail
);
298 PR32(cfs_disconnect_in_event_ok
);
299 PR32(cfs_disconnect_out_event_ok
);
300 PR32(cfs_disconnect_event_flow_control
);
301 PR32(cfs_disconnect_event_fail
);
303 PR32(cfs_ctl_q_not_started
);
305 PR32(cfs_close_wait
);
306 PR32(cfs_close_wait_timeout
);
308 PR32(cfs_flush_in_drop
);
309 PR32(cfs_flush_out_drop
);
310 PR32(cfs_flush_in_close
);
311 PR32(cfs_flush_out_close
);
312 PR32(cfs_flush_in_free
);
313 PR32(cfs_flush_out_free
);
315 PR32(cfs_inject_q_nomem
);
316 PR32(cfs_inject_q_nobufs
);
317 PR32(cfs_inject_q_detached
);
318 PR32(cfs_inject_q_in_fail
);
319 PR32(cfs_inject_q_out_fail
);
321 PR32(cfs_inject_q_in_retry
);
322 PR32(cfs_inject_q_out_retry
);
324 PR32(cfs_data_in_control
);
325 PR32(cfs_data_in_oob
);
326 PR32(cfs_data_out_control
);
327 PR32(cfs_data_out_oob
);
329 PR64(cfs_ctl_q_in_enqueued
);
330 PR64(cfs_ctl_q_out_enqueued
);
331 PR64(cfs_ctl_q_in_peeked
);
332 PR64(cfs_ctl_q_out_peeked
);
334 PR64(cfs_pending_q_in_enqueued
);
335 PR64(cfs_pending_q_out_enqueued
);
337 PR64(cfs_inject_q_in_enqueued
);
338 PR64(cfs_inject_q_out_enqueued
);
339 PR64(cfs_inject_q_in_passed
);
340 PR64(cfs_inject_q_out_passed
);