1 | /* |
2 | * Copyright (c) 2013-2019, 2022 Apple Inc. All rights reserved. |
3 | * |
4 | * @APPLE_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. Please obtain a copy of the License at |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this |
11 | * file. |
12 | * |
13 | * The Original Code and all software distributed under the License are |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
18 | * Please see the License for the specific language governing rights and |
19 | * limitations under the License. |
20 | * |
21 | * @APPLE_LICENSE_HEADER_END@ |
22 | */ |
23 | |
24 | #ifndef __CONTENT_FILTER_H__ |
25 | #define __CONTENT_FILTER_H__ |
26 | |
27 | #include <sys/param.h> |
28 | #include <sys/types.h> |
29 | #include <sys/_types/_timeval64.h> |
30 | #include <sys/socket.h> |
31 | #include <sys/syslog.h> |
32 | #include <netinet/in.h> |
33 | #include <stdint.h> |
34 | #include <corecrypto/ccsha2.h> |
35 | |
36 | #ifdef BSD_KERNEL_PRIVATE |
37 | #include <sys/mbuf.h> |
38 | #include <sys/socketvar.h> |
39 | #endif /* BSD_KERNEL_PRIVATE */ |
40 | |
41 | #ifndef XNU_KERNEL_PRIVATE |
42 | #include <TargetConditionals.h> |
43 | #endif |
44 | |
45 | __BEGIN_DECLS |
46 | |
47 | #ifdef PRIVATE |
48 | |
49 | /* |
50 | * Kernel control name for an instance of a Content Filter |
51 | * Use CTLIOCGINFO to find out the corresponding kernel control id |
52 | * to be set in the sc_id field of sockaddr_ctl for connect(2) |
53 | * Note: the sc_unit is ephemeral |
54 | */ |
55 | #define CONTENT_FILTER_CONTROL_NAME "com.apple.content-filter" |
56 | |
57 | /* |
58 | * Opaque socket identifier |
59 | */ |
60 | typedef uint64_t cfil_sock_id_t; |
61 | |
62 | #define CFIL_SOCK_ID_NONE UINT64_MAX |
63 | |
64 | |
65 | /* |
66 | * CFIL_OPT_NECP_CONTROL_UNIT |
67 | * To set or get the NECP filter control unit for the kernel control socket |
68 | * The option level is SYSPROTO_CONTROL |
69 | */ |
70 | #define CFIL_OPT_NECP_CONTROL_UNIT 1 /* uint32_t */ |
71 | |
72 | /* |
73 | * CFIL_OPT_GET_SOCKET_INFO |
74 | * To get information about a given socket that is being filtered. |
75 | */ |
76 | #define CFIL_OPT_GET_SOCKET_INFO 2 /* uint32_t */ |
77 | |
78 | /* |
79 | * CFIL_OPT_PRESERVE_CONNECTIONS |
80 | * To set or get the preserve-connections setting for the filter |
81 | */ |
82 | #define CFIL_OPT_PRESERVE_CONNECTIONS 3 /* uint32_t */ |
83 | |
84 | /* |
85 | * struct cfil_opt_sock_info |
86 | * |
87 | * Contains information about a socket that is being filtered. |
88 | */ |
89 | struct cfil_opt_sock_info { |
90 | cfil_sock_id_t cfs_sock_id; |
91 | int cfs_sock_family; /* e.g. PF_INET */ |
92 | int cfs_sock_type; /* e.g. SOCK_STREAM */ |
93 | int cfs_sock_protocol; /* e.g. IPPROTO_TCP */ |
94 | union sockaddr_in_4_6 cfs_local; |
95 | union sockaddr_in_4_6 cfs_remote; |
96 | pid_t cfs_pid; |
97 | pid_t cfs_e_pid; |
98 | uuid_t cfs_uuid; |
99 | uuid_t cfs_e_uuid; |
100 | }; |
101 | |
102 | /* |
103 | * How many filter may be active simultaneously |
104 | */ |
105 | |
106 | #define CFIL_MAX_FILTER_COUNT 8 |
107 | |
108 | /* |
109 | * Crypto Support |
110 | */ |
111 | #define CFIL_CRYPTO 1 |
112 | #define CFIL_CRYPTO_SIGNATURE_SIZE 32 |
113 | #define CFIL_CRYPTO_DATA_EVENT 1 |
114 | |
115 | typedef uint8_t cfil_crypto_key[CCSHA256_OUTPUT_SIZE]; |
116 | typedef uint8_t cfil_crypto_signature[CFIL_CRYPTO_SIGNATURE_SIZE]; |
117 | |
118 | typedef struct cfil_crypto_state { |
119 | const struct ccdigest_info *digest_info; |
120 | cfil_crypto_key key; |
121 | } *cfil_crypto_state_t; |
122 | |
123 | typedef struct cfil_crypto_data { |
124 | uuid_t flow_id; |
125 | u_int64_t sock_id; |
126 | u_int32_t direction; |
127 | union sockaddr_in_4_6 remote; |
128 | union sockaddr_in_4_6 local; |
129 | u_int32_t socketProtocol; |
130 | pid_t pid; |
131 | pid_t effective_pid; |
132 | uuid_t uuid; |
133 | uuid_t effective_uuid; |
134 | u_int64_t byte_count_in; |
135 | u_int64_t byte_count_out; |
136 | } *cfil_crypto_data_t; |
137 | |
138 | /* |
139 | * Types of messages |
140 | * |
141 | * Event messages flow from kernel to user space while action |
142 | * messages flow in the reverse direction. |
143 | * A message in entirely represented by a packet sent or received |
144 | * on a Content Filter kernel control socket. |
145 | */ |
146 | #define CFM_TYPE_EVENT 1 /* message from kernel */ |
147 | #define CFM_TYPE_ACTION 2 /* message to kernel */ |
148 | |
149 | /* |
150 | * Operations associated with events from kernel |
151 | */ |
152 | #define CFM_OP_SOCKET_ATTACHED 1 /* a socket has been attached */ |
153 | #define CFM_OP_SOCKET_CLOSED 2 /* a socket is being closed */ |
154 | #define CFM_OP_DATA_OUT 3 /* data being sent */ |
155 | #define CFM_OP_DATA_IN 4 /* data being received */ |
156 | #define CFM_OP_DISCONNECT_OUT 5 /* no more outgoing data */ |
157 | #define CFM_OP_DISCONNECT_IN 6 /* no more incoming data */ |
158 | #define CFM_OP_STATS 7 /* periodic stats report(s) */ |
159 | |
160 | /* |
161 | * Operations associated with action from filter to kernel |
162 | */ |
163 | #define CFM_OP_DATA_UPDATE 16 /* update pass or peek offsets */ |
164 | #define CFM_OP_DROP 17 /* shutdown socket, no more data */ |
165 | #define CFM_OP_BLESS_CLIENT 18 /* mark a client flow as already filtered, passes a uuid */ |
166 | #define CFM_OP_SET_CRYPTO_KEY 19 /* assign client crypto key for message signing */ |
167 | |
168 | /* |
169 | * struct cfil_msg_hdr |
170 | * |
171 | * Header common to all messages |
172 | */ |
173 | struct cfil_msg_hdr { |
174 | uint32_t cfm_len; /* total length */ |
175 | uint32_t cfm_version; |
176 | uint32_t cfm_type; |
177 | uint32_t cfm_op; |
178 | cfil_sock_id_t cfm_sock_id; |
179 | }; |
180 | |
181 | #define CFM_VERSION_CURRENT 1 |
182 | |
183 | /* |
184 | * Connection Direction |
185 | */ |
186 | #define CFS_CONNECTION_DIR_IN 0 |
187 | #define CFS_CONNECTION_DIR_OUT 1 |
188 | |
189 | #define CFS_REAL_AUDIT_TOKEN 1 |
190 | |
191 | #define CFS_MAX_DOMAIN_NAME_LENGTH 256 |
192 | |
193 | |
194 | /* |
195 | * struct cfil_msg_sock_attached |
196 | * |
197 | * Information about a new socket being attached to the content filter |
198 | * |
199 | * Action: No reply is expected as this does not block the creation of the |
200 | * TCP/IP but timely action must be taken to avoid user noticeable delays. |
201 | * |
202 | * Valid Types: CFM_TYPE_EVENT |
203 | * |
204 | * Valid Op: CFM_OP_SOCKET_ATTACHED |
205 | */ |
206 | struct cfil_msg_sock_attached { |
207 | struct cfil_msg_hdr cfs_msghdr; |
208 | int cfs_sock_family; /* e.g. PF_INET */ |
209 | int cfs_sock_type; /* e.g. SOCK_STREAM */ |
210 | int cfs_sock_protocol; /* e.g. IPPROTO_TCP */ |
211 | int cfs_unused; /* padding */ |
212 | pid_t cfs_pid; |
213 | pid_t cfs_e_pid; |
214 | uuid_t cfs_uuid; |
215 | uuid_t cfs_e_uuid; |
216 | union sockaddr_in_4_6 cfs_src; |
217 | union sockaddr_in_4_6 cfs_dst; |
218 | int cfs_conn_dir; |
219 | unsigned int cfs_audit_token[8]; /* Must match audit_token_t */ |
220 | unsigned int cfs_real_audit_token[8]; /* Must match audit_token_t */ |
221 | cfil_crypto_signature cfs_signature; |
222 | uint32_t cfs_signature_length; |
223 | char cfs_remote_domain_name[CFS_MAX_DOMAIN_NAME_LENGTH]; |
224 | }; |
225 | |
226 | /* |
227 | * CFIL data flags |
228 | */ |
229 | #define 0x00000001 /* Data includes IP header */ |
230 | |
231 | /* |
232 | * struct cfil_msg_data_event |
233 | * |
234 | * Event for the content fiter to act on a span of data |
235 | * A data span is described by a pair of offsets over the cumulative |
236 | * number of bytes sent or received on the socket. |
237 | * |
238 | * Action: The event must be acted upon but the filter may buffer |
239 | * data spans until it has enough content to make a decision. |
240 | * The action must be timely to avoid user noticeable delays. |
241 | * |
242 | * Valid Type: CFM_TYPE_EVENT |
243 | * |
244 | * Valid Ops: CFM_OP_DATA_OUT, CFM_OP_DATA_IN |
245 | */ |
246 | struct cfil_msg_data_event { |
247 | struct cfil_msg_hdr cfd_msghdr; |
248 | union sockaddr_in_4_6 cfc_src; |
249 | union sockaddr_in_4_6 cfc_dst; |
250 | uint64_t cfd_start_offset; |
251 | uint64_t cfd_end_offset; |
252 | cfil_crypto_signature cfd_signature; |
253 | uint32_t cfd_signature_length; |
254 | uint32_t cfd_flags; |
255 | /* Actual content data immediatly follows */ |
256 | }; |
257 | |
258 | #define CFI_MAX_TIME_LOG_ENTRY 6 |
259 | /* |
260 | * struct cfil_msg_sock_closed |
261 | * |
262 | * Information about a socket being closed to the content filter |
263 | * |
264 | * Action: No reply is expected as this does not block the closing of the |
265 | * TCP/IP. |
266 | * |
267 | * Valid Types: CFM_TYPE_EVENT |
268 | * |
269 | * Valid Op: CFM_OP_SOCKET_CLOSED |
270 | */ |
271 | struct cfil_msg_sock_closed { |
272 | struct cfil_msg_hdr cfc_msghdr; |
273 | struct timeval64 cfc_first_event; |
274 | uint32_t cfc_op_list_ctr; |
275 | uint32_t cfc_op_time[CFI_MAX_TIME_LOG_ENTRY]; /* time interval in microseconds since first event */ |
276 | unsigned char cfc_op_list[CFI_MAX_TIME_LOG_ENTRY]; |
277 | uint64_t cfc_byte_inbound_count; |
278 | uint64_t cfc_byte_outbound_count; |
279 | #define CFC_CLOSED_EVENT_LADDR 1 |
280 | union sockaddr_in_4_6 cfc_laddr; |
281 | cfil_crypto_signature cfc_signature; |
282 | uint32_t cfc_signature_length; |
283 | } __attribute__((aligned(8))); |
284 | |
285 | /* |
286 | * struct cfil_msg_stats_report |
287 | * |
288 | * Statistics report for flow(s). |
289 | * |
290 | * Action: No reply is expected. |
291 | * |
292 | * Valid Types: CFM_TYPE_EVENT |
293 | * |
294 | * Valid Op: CFM_OP_STATS |
295 | */ |
296 | struct cfil_msg_sock_stats { |
297 | cfil_sock_id_t cfs_sock_id; |
298 | uint64_t cfs_byte_inbound_count; |
299 | uint64_t cfs_byte_outbound_count; |
300 | union sockaddr_in_4_6 cfs_laddr; |
301 | } __attribute__((aligned(8))); |
302 | |
303 | struct cfil_msg_stats_report { |
304 | struct cfil_msg_hdr cfr_msghdr; |
305 | uint32_t cfr_count; |
306 | struct cfil_msg_sock_stats cfr_stats[]; |
307 | } __attribute__((aligned(8))); |
308 | |
309 | /* |
310 | * struct cfil_msg_action |
311 | * |
312 | * Valid Type: CFM_TYPE_ACTION |
313 | * |
314 | * Valid Ops: CFM_OP_DATA_UPDATE, CFM_OP_DROP |
315 | * |
316 | * For CFM_OP_DATA_UPDATE: |
317 | * |
318 | * cfa_in_pass_offset and cfa_out_pass_offset indicates how much data is |
319 | * allowed to pass. A zero value does not modify the corresponding pass offset. |
320 | * |
321 | * cfa_in_peek_offset and cfa_out_peek_offset lets the filter specify how much |
322 | * data it needs to make a decision: the kernel will deliver data up to that |
323 | * offset (if less than cfa_pass_offset it is ignored). Use CFM_MAX_OFFSET |
324 | * if you don't value the corresponding peek offset to be updated. |
325 | */ |
326 | struct cfil_msg_action { |
327 | struct cfil_msg_hdr cfa_msghdr; |
328 | uint64_t cfa_in_pass_offset; |
329 | uint64_t cfa_in_peek_offset; |
330 | uint64_t cfa_out_pass_offset; |
331 | uint64_t cfa_out_peek_offset; |
332 | uint32_t cfa_stats_frequency; // Statistics frequency in milliseconds |
333 | }; |
334 | |
335 | /* |
336 | * struct cfil_msg_bless_client |
337 | * |
338 | * Marks a client UUID as already filtered at a higher level. |
339 | * |
340 | * Valid Type: CFM_TYPE_ACTION |
341 | * |
342 | * Valid Ops: CFM_OP_BLESS_CLIENT |
343 | */ |
344 | struct cfil_msg_bless_client { |
345 | struct cfil_msg_hdr cfb_msghdr; |
346 | uuid_t cfb_client_uuid; |
347 | }; |
348 | |
349 | /* |
350 | * struct cfil_msg_set_crypto_key |
351 | * |
352 | * Filter assigning client crypto key to CFIL for message signing |
353 | * |
354 | * Valid Type: CFM_TYPE_ACTION |
355 | * |
356 | * Valid Ops: CFM_OP_SET_CRYPTO_KEY |
357 | */ |
358 | struct cfil_msg_set_crypto_key { |
359 | struct cfil_msg_hdr cfb_msghdr; |
360 | cfil_crypto_key crypto_key; |
361 | }; |
362 | |
363 | #define CFM_MAX_OFFSET UINT64_MAX |
364 | |
365 | /* |
366 | * Statistics retrieved via sysctl(3) |
367 | */ |
368 | struct cfil_filter_stat { |
369 | uint32_t cfs_len; |
370 | uint32_t cfs_filter_id; |
371 | uint32_t cfs_flags; |
372 | uint32_t cfs_sock_count; |
373 | uint32_t cfs_necp_control_unit; |
374 | }; |
375 | |
376 | struct cfil_entry_stat { |
377 | uint32_t ces_len; |
378 | uint32_t ces_filter_id; |
379 | uint32_t ces_flags; |
380 | uint32_t ces_necp_control_unit; |
381 | struct timeval64 ces_last_event; |
382 | struct timeval64 ces_last_action; |
383 | struct cfe_buf_stat { |
384 | uint64_t cbs_pending_first; |
385 | uint64_t cbs_pending_last; |
386 | uint64_t cbs_ctl_first; |
387 | uint64_t cbs_ctl_last; |
388 | uint64_t cbs_pass_offset; |
389 | uint64_t cbs_peek_offset; |
390 | uint64_t cbs_peeked; |
391 | } ces_snd, ces_rcv; |
392 | }; |
393 | |
394 | struct cfil_sock_stat { |
395 | uint32_t cfs_len; |
396 | int cfs_sock_family; |
397 | int cfs_sock_type; |
398 | int cfs_sock_protocol; |
399 | cfil_sock_id_t cfs_sock_id; |
400 | uint64_t cfs_flags; |
401 | pid_t cfs_pid; |
402 | pid_t cfs_e_pid; |
403 | uuid_t cfs_uuid; |
404 | uuid_t cfs_e_uuid; |
405 | struct cfi_buf_stat { |
406 | uint64_t cbs_pending_first; |
407 | uint64_t cbs_pending_last; |
408 | uint64_t cbs_pass_offset; |
409 | uint64_t cbs_inject_q_len; |
410 | } cfs_snd, cfs_rcv; |
411 | struct cfil_entry_stat ces_entries[CFIL_MAX_FILTER_COUNT]; |
412 | }; |
413 | |
414 | /* |
415 | * Global statistics |
416 | */ |
417 | struct cfil_stats { |
418 | int32_t cfs_ctl_connect_ok; |
419 | int32_t cfs_ctl_connect_fail; |
420 | int32_t cfs_ctl_disconnect_ok; |
421 | int32_t cfs_ctl_disconnect_fail; |
422 | int32_t cfs_ctl_send_ok; |
423 | int32_t cfs_ctl_send_bad; |
424 | int32_t cfs_ctl_rcvd_ok; |
425 | int32_t cfs_ctl_rcvd_bad; |
426 | int32_t cfs_ctl_rcvd_flow_lift; |
427 | int32_t cfs_ctl_action_data_update; |
428 | int32_t cfs_ctl_action_drop; |
429 | int32_t cfs_ctl_action_bad_op; |
430 | int32_t cfs_ctl_action_bad_len; |
431 | |
432 | int32_t cfs_sock_id_not_found; |
433 | |
434 | int32_t cfs_cfi_alloc_ok; |
435 | int32_t cfs_cfi_alloc_fail; |
436 | |
437 | int32_t cfs_sock_userspace_only; |
438 | int32_t cfs_sock_attach_in_vain; |
439 | int32_t cfs_sock_attach_already; |
440 | int32_t cfs_sock_attach_no_mem; |
441 | int32_t cfs_sock_attach_failed; |
442 | int32_t cfs_sock_attached; |
443 | int32_t cfs_sock_detached; |
444 | |
445 | int32_t cfs_attach_event_ok; |
446 | int32_t cfs_attach_event_flow_control; |
447 | int32_t cfs_attach_event_fail; |
448 | |
449 | int32_t cfs_closed_event_ok; |
450 | int32_t cfs_closed_event_flow_control; |
451 | int32_t cfs_closed_event_fail; |
452 | |
453 | int32_t cfs_data_event_ok; |
454 | int32_t cfs_data_event_flow_control; |
455 | int32_t cfs_data_event_fail; |
456 | |
457 | int32_t cfs_stats_event_ok; |
458 | int32_t cfs_stats_event_flow_control; |
459 | int32_t cfs_stats_event_fail; |
460 | |
461 | int32_t cfs_disconnect_in_event_ok; |
462 | int32_t cfs_disconnect_out_event_ok; |
463 | int32_t cfs_disconnect_event_flow_control; |
464 | int32_t cfs_disconnect_event_fail; |
465 | |
466 | int32_t cfs_ctl_q_not_started; |
467 | |
468 | int32_t cfs_close_wait; |
469 | int32_t cfs_close_wait_timeout; |
470 | |
471 | int32_t cfs_flush_in_drop; |
472 | int32_t cfs_flush_out_drop; |
473 | int32_t cfs_flush_in_close; |
474 | int32_t cfs_flush_out_close; |
475 | int32_t cfs_flush_in_free; |
476 | int32_t cfs_flush_out_free; |
477 | |
478 | int32_t cfs_inject_q_nomem; |
479 | int32_t cfs_inject_q_nobufs; |
480 | int32_t cfs_inject_q_detached; |
481 | int32_t cfs_inject_q_in_fail; |
482 | int32_t cfs_inject_q_out_fail; |
483 | |
484 | int32_t cfs_inject_q_in_retry; |
485 | int32_t cfs_inject_q_out_retry; |
486 | |
487 | int32_t cfs_data_in_control; |
488 | int32_t cfs_data_in_oob; |
489 | int32_t cfs_data_out_control; |
490 | int32_t cfs_data_out_oob; |
491 | |
492 | int64_t cfs_ctl_q_in_enqueued __attribute__((aligned(8))); |
493 | int64_t cfs_ctl_q_out_enqueued __attribute__((aligned(8))); |
494 | int64_t cfs_ctl_q_in_peeked __attribute__((aligned(8))); |
495 | int64_t cfs_ctl_q_out_peeked __attribute__((aligned(8))); |
496 | |
497 | int64_t cfs_pending_q_in_enqueued __attribute__((aligned(8))); |
498 | int64_t cfs_pending_q_out_enqueued __attribute__((aligned(8))); |
499 | |
500 | int64_t cfs_inject_q_in_enqueued __attribute__((aligned(8))); |
501 | int64_t cfs_inject_q_out_enqueued __attribute__((aligned(8))); |
502 | int64_t cfs_inject_q_in_passed __attribute__((aligned(8))); |
503 | int64_t cfs_inject_q_out_passed __attribute__((aligned(8))); |
504 | }; |
505 | #endif /* PRIVATE */ |
506 | |
507 | #ifdef BSD_KERNEL_PRIVATE |
508 | |
509 | #define M_SKIPCFIL M_PROTO5 |
510 | |
511 | #define CFIL_DGRAM_FILTERED(so) ((so->so_flags & SOF_CONTENT_FILTER) && (so->so_flow_db != NULL)) |
512 | |
513 | extern int cfil_log_level; |
514 | |
515 | #define CFIL_LOG(level, fmt, ...) \ |
516 | do { \ |
517 | if (cfil_log_level >= level) \ |
518 | printf("%s:%d " fmt "\n",\ |
519 | __FUNCTION__, __LINE__, ##__VA_ARGS__); \ |
520 | } while (0) |
521 | |
522 | |
523 | extern void cfil_register_m_tag(void); |
524 | |
525 | extern void cfil_init(void); |
526 | |
527 | extern boolean_t cfil_filter_present(void); |
528 | extern boolean_t cfil_sock_connected_pending_verdict(struct socket *so); |
529 | extern boolean_t cfil_sock_is_dead(struct socket *so); |
530 | extern boolean_t cfil_sock_tcp_add_time_wait(struct socket *so); |
531 | extern errno_t cfil_sock_attach(struct socket *so, |
532 | struct sockaddr *local, struct sockaddr *remote, int dir); |
533 | extern errno_t cfil_sock_detach(struct socket *so); |
534 | |
535 | extern int cfil_sock_data_out(struct socket *so, struct sockaddr *to, |
536 | struct mbuf *data, struct mbuf *control, |
537 | uint32_t flags, struct soflow_hash_entry *); |
538 | extern int cfil_sock_data_in(struct socket *so, struct sockaddr *from, |
539 | struct mbuf *data, struct mbuf *control, |
540 | uint32_t flags, struct soflow_hash_entry *); |
541 | |
542 | extern int cfil_sock_shutdown(struct socket *so, int *how); |
543 | extern void cfil_sock_is_closed(struct socket *so); |
544 | extern void cfil_sock_notify_shutdown(struct socket *so, int how); |
545 | extern void cfil_sock_close_wait(struct socket *so); |
546 | |
547 | extern boolean_t cfil_sock_data_pending(struct sockbuf *sb); |
548 | extern int cfil_sock_data_space(struct sockbuf *sb); |
549 | extern void cfil_sock_buf_update(struct sockbuf *sb); |
550 | |
551 | extern cfil_sock_id_t cfil_sock_id_from_socket(struct socket *so); |
552 | extern cfil_sock_id_t cfil_sock_id_from_datagram_socket(struct socket *so, struct sockaddr *local, struct sockaddr *remote); |
553 | |
554 | extern struct m_tag *cfil_dgram_get_socket_state(struct mbuf *m, uint32_t *state_change_cnt, |
555 | uint32_t *options, struct sockaddr **faddr, int *inp_flags); |
556 | extern boolean_t cfil_dgram_peek_socket_state(struct mbuf *m, int *inp_flags); |
557 | |
558 | #endif /* BSD_KERNEL_PRIVATE */ |
559 | |
560 | __END_DECLS |
561 | |
562 | #endif /* __CONTENT_FILTER_H__ */ |
563 | |