]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kpi_socketfilter.c
f456d62465351787213c5e5a46d2fe4c03327773
[apple/xnu.git] / bsd / kern / kpi_socketfilter.c
1 /*
2 * Copyright (c) 2003-2007 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 #include <sys/kpi_socketfilter.h>
30
31 #include <sys/socket.h>
32 #include <sys/param.h>
33 #include <sys/errno.h>
34 #include <sys/malloc.h>
35 #include <sys/protosw.h>
36 #include <sys/domain.h>
37 #include <sys/proc.h>
38 #include <kern/locks.h>
39 #include <kern/thread.h>
40 #include <kern/debug.h>
41 #include <net/kext_net.h>
42 #include <net/if.h>
43 #include <netinet/in_var.h>
44 #include <netinet/ip.h>
45 #include <netinet/ip_var.h>
46 #include <netinet/tcp.h>
47 #include <netinet/tcp_var.h>
48 #include <netinet/udp.h>
49 #include <netinet/udp_var.h>
50
51 #include <libkern/libkern.h>
52 #include <libkern/OSAtomic.h>
53
54 #include <string.h>
55
56 #define SFEF_ATTACHED 0x1 /* SFE is on socket list */
57 #define SFEF_NODETACH 0x2 /* Detach should not be called */
58 #define SFEF_NOSOCKET 0x4 /* Socket is gone */
59
60 struct socket_filter_entry {
61 struct socket_filter_entry *sfe_next_onsocket;
62 struct socket_filter_entry *sfe_next_onfilter;
63 struct socket_filter_entry *sfe_next_oncleanup;
64
65 struct socket_filter *sfe_filter;
66 struct socket *sfe_socket;
67 void *sfe_cookie;
68
69 uint32_t sfe_flags;
70 int32_t sfe_refcount;
71 };
72
73 struct socket_filter {
74 TAILQ_ENTRY(socket_filter) sf_protosw_next;
75 TAILQ_ENTRY(socket_filter) sf_global_next;
76 struct socket_filter_entry *sf_entry_head;
77
78 struct protosw *sf_proto;
79 struct sflt_filter sf_filter;
80 u_int32_t sf_refcount;
81 };
82
83 TAILQ_HEAD(socket_filter_list, socket_filter);
84
85 static struct socket_filter_list sock_filter_head;
86 static lck_rw_t *sock_filter_lock = NULL;
87 static lck_mtx_t *sock_filter_cleanup_lock = NULL;
88 static struct socket_filter_entry *sock_filter_cleanup_entries = NULL;
89 static thread_t sock_filter_cleanup_thread = NULL;
90
91 static void sflt_cleanup_thread(void *, wait_result_t);
92 static void sflt_detach_locked(struct socket_filter_entry *entry);
93
94 #pragma mark -- Internal State Management --
95
96 __private_extern__ void
97 sflt_init(void)
98 {
99 lck_grp_attr_t *grp_attrib = 0;
100 lck_attr_t *lck_attrib = 0;
101 lck_grp_t *lck_group = 0;
102
103 TAILQ_INIT(&sock_filter_head);
104
105 /* Allocate a rw lock */
106 grp_attrib = lck_grp_attr_alloc_init();
107 lck_group = lck_grp_alloc_init("socket filter lock", grp_attrib);
108 lck_grp_attr_free(grp_attrib);
109 lck_attrib = lck_attr_alloc_init();
110 sock_filter_lock = lck_rw_alloc_init(lck_group, lck_attrib);
111 sock_filter_cleanup_lock = lck_mtx_alloc_init(lck_group, lck_attrib);
112 lck_grp_free(lck_group);
113 lck_attr_free(lck_attrib);
114 }
115
116 static void
117 sflt_retain_locked(
118 struct socket_filter *filter)
119 {
120 filter->sf_refcount++;
121 }
122
123 static void
124 sflt_release_locked(
125 struct socket_filter *filter)
126 {
127 filter->sf_refcount--;
128 if (filter->sf_refcount == 0)
129 {
130 // Call the unregistered function
131 if (filter->sf_filter.sf_unregistered) {
132 lck_rw_unlock_exclusive(sock_filter_lock);
133 filter->sf_filter.sf_unregistered(filter->sf_filter.sf_handle);
134 lck_rw_lock_exclusive(sock_filter_lock);
135 }
136
137 // Free the entry
138 FREE(filter, M_IFADDR);
139 }
140 }
141
142 static void
143 sflt_entry_retain(
144 struct socket_filter_entry *entry)
145 {
146 if (OSIncrementAtomic(&entry->sfe_refcount) <= 0)
147 panic("sflt_entry_retain - sfe_refcount <= 0\n");
148 }
149
150 static void
151 sflt_entry_release(
152 struct socket_filter_entry *entry)
153 {
154 SInt32 old = OSDecrementAtomic(&entry->sfe_refcount);
155 if (old == 1) {
156 // That was the last reference
157
158 // Take the cleanup lock
159 lck_mtx_lock(sock_filter_cleanup_lock);
160
161 // Put this item on the cleanup list
162 entry->sfe_next_oncleanup = sock_filter_cleanup_entries;
163 sock_filter_cleanup_entries = entry;
164
165 // If the item is the first item in the list
166 if (entry->sfe_next_oncleanup == NULL) {
167 if (sock_filter_cleanup_thread == NULL) {
168 // Create a thread
169 kernel_thread_start(sflt_cleanup_thread, NULL, &sock_filter_cleanup_thread);
170 } else {
171 // Wakeup the thread
172 wakeup(&sock_filter_cleanup_entries);
173 }
174 }
175
176 // Drop the cleanup lock
177 lck_mtx_unlock(sock_filter_cleanup_lock);
178 }
179 else if (old <= 0)
180 {
181 panic("sflt_entry_release - sfe_refcount (%d) <= 0\n", (int)old);
182 }
183 }
184
185 static void
186 sflt_cleanup_thread(
187 __unused void * blah,
188 __unused wait_result_t blah2)
189 {
190 while (1) {
191 lck_mtx_lock(sock_filter_cleanup_lock);
192 while (sock_filter_cleanup_entries == NULL) {
193 // Sleep until we've got something better to do
194 msleep(&sock_filter_cleanup_entries, sock_filter_cleanup_lock, PWAIT, "sflt_cleanup", NULL);
195 }
196
197 // Pull the current list of dead items
198 struct socket_filter_entry *dead = sock_filter_cleanup_entries;
199 sock_filter_cleanup_entries = NULL;
200
201 // Drop the lock
202 lck_mtx_unlock(sock_filter_cleanup_lock);
203
204 // Take the socket filter lock
205 lck_rw_lock_exclusive(sock_filter_lock);
206
207 // Cleanup every dead item
208 struct socket_filter_entry *entry;
209 for (entry = dead; entry; entry = dead) {
210 struct socket_filter_entry **nextpp;
211
212 dead = entry->sfe_next_oncleanup;
213
214 // Call the detach function if necessary - drop the lock
215 if ((entry->sfe_flags & SFEF_NODETACH) == 0 &&
216 entry->sfe_filter->sf_filter.sf_detach) {
217 entry->sfe_flags |= SFEF_NODETACH;
218 lck_rw_unlock_exclusive(sock_filter_lock);
219
220 // Warning - passing a potentially dead socket may be bad
221 entry->sfe_filter->sf_filter.
222 sf_detach(entry->sfe_cookie, entry->sfe_socket);
223
224 lck_rw_lock_exclusive(sock_filter_lock);
225 }
226
227 // Pull entry off the socket list -- if the socket still exists
228 if ((entry->sfe_flags & SFEF_NOSOCKET) == 0) {
229 for (nextpp = &entry->sfe_socket->so_filt; *nextpp;
230 nextpp = &(*nextpp)->sfe_next_onsocket) {
231 if (*nextpp == entry) {
232 *nextpp = entry->sfe_next_onsocket;
233 break;
234 }
235 }
236 }
237
238 // Pull entry off the filter list
239 for (nextpp = &entry->sfe_filter->sf_entry_head; *nextpp;
240 nextpp = &(*nextpp)->sfe_next_onfilter) {
241 if (*nextpp == entry) {
242 *nextpp = entry->sfe_next_onfilter;
243 break;
244 }
245 }
246
247 // Release the filter -- may drop lock, but that's okay
248 sflt_release_locked(entry->sfe_filter);
249 entry->sfe_socket = NULL;
250 entry->sfe_filter = NULL;
251 FREE(entry, M_IFADDR);
252 }
253
254 // Drop the socket filter lock
255 lck_rw_unlock_exclusive(sock_filter_lock);
256 }
257 // Not reached
258 }
259
260 static int
261 sflt_attach_locked(
262 struct socket *so,
263 struct socket_filter *filter,
264 int socklocked)
265 {
266 int error = 0;
267 struct socket_filter_entry *entry = NULL;
268
269 if (filter == NULL)
270 return ENOENT;
271
272 for (entry = so->so_filt; entry; entry = entry->sfe_next_onfilter)
273 if (entry->sfe_filter->sf_filter.sf_handle ==
274 filter->sf_filter.sf_handle)
275 return EEXIST;
276
277 /* allocate the socket filter entry */
278 MALLOC(entry, struct socket_filter_entry *, sizeof(*entry), M_IFADDR,
279 M_WAITOK);
280 if (entry == NULL)
281 return ENOMEM;
282
283 /* Initialize the socket filter entry */
284 entry->sfe_cookie = NULL;
285 entry->sfe_flags = SFEF_ATTACHED;
286 entry->sfe_refcount = 1; // corresponds to SFEF_ATTACHED flag set
287
288 /* Put the entry in the filter list */
289 sflt_retain_locked(filter);
290 entry->sfe_filter = filter;
291 entry->sfe_next_onfilter = filter->sf_entry_head;
292 filter->sf_entry_head = entry;
293
294 /* Put the entry on the socket filter list */
295 entry->sfe_socket = so;
296 entry->sfe_next_onsocket = so->so_filt;
297 so->so_filt = entry;
298
299 if (entry->sfe_filter->sf_filter.sf_attach) {
300 // Retain the entry while we call attach
301 sflt_entry_retain(entry);
302
303 // Release the filter lock -- callers must be aware we will do this
304 lck_rw_unlock_exclusive(sock_filter_lock);
305
306 // Unlock the socket
307 if (socklocked)
308 socket_unlock(so, 0);
309
310 // It's finally safe to call the filter function
311 error = entry->sfe_filter->sf_filter.sf_attach(&entry->sfe_cookie, so);
312
313 // Lock the socket again
314 if (socklocked)
315 socket_lock(so, 0);
316
317 // Lock the filters again
318 lck_rw_lock_exclusive(sock_filter_lock);
319
320 // If the attach function returns an error, this filter must be detached
321 if (error) {
322 entry->sfe_flags |= SFEF_NODETACH; // don't call sf_detach
323 sflt_detach_locked(entry);
324 }
325
326 // Release the retain we held through the attach call
327 sflt_entry_release(entry);
328 }
329
330 return error;
331 }
332
333 errno_t
334 sflt_attach_internal(
335 socket_t socket,
336 sflt_handle handle)
337 {
338 if (socket == NULL || handle == 0)
339 return EINVAL;
340
341 int result = EINVAL;
342
343 lck_rw_lock_exclusive(sock_filter_lock);
344
345 struct socket_filter *filter = NULL;
346 TAILQ_FOREACH(filter, &sock_filter_head, sf_global_next) {
347 if (filter->sf_filter.sf_handle == handle) break;
348 }
349
350 if (filter) {
351 result = sflt_attach_locked(socket, filter, 1);
352 }
353
354 lck_rw_unlock_exclusive(sock_filter_lock);
355
356 return result;
357 }
358
359 static void
360 sflt_detach_locked(
361 struct socket_filter_entry *entry)
362 {
363 if ((entry->sfe_flags & SFEF_ATTACHED) != 0) {
364 entry->sfe_flags &= ~SFEF_ATTACHED;
365 sflt_entry_release(entry);
366 }
367 }
368
369 #pragma mark -- Socket Layer Hooks --
370
371 __private_extern__ void
372 sflt_initsock(
373 struct socket *so)
374 {
375 struct protosw *proto = so->so_proto;
376
377 lck_rw_lock_shared(sock_filter_lock);
378 if (TAILQ_FIRST(&proto->pr_filter_head) != NULL) {
379 // Promote lock to exclusive
380 if (!lck_rw_lock_shared_to_exclusive(sock_filter_lock))
381 lck_rw_lock_exclusive(sock_filter_lock);
382
383 // Warning: A filter unregistering will be pulled out of the list.
384 // This could happen while we drop the lock in sftl_attach_locked
385 // or sflt_release_locked. For this reason we retain a reference
386 // on the filter (or next_filter) while calling this function
387 //
388 // This protects us from a panic, but it could result in a
389 // socket being created without all of the global filters if
390 // we're attaching a filter as it is removed, if that's possible.
391 struct socket_filter *filter = TAILQ_FIRST(&proto->pr_filter_head);
392 sflt_retain_locked(filter);
393
394 while (filter)
395 {
396 struct socket_filter *filter_next;
397
398 // Warning: sflt_attach_private_locked will drop the lock
399 sflt_attach_locked(so, filter, 0);
400
401 filter_next = TAILQ_NEXT(filter, sf_protosw_next);
402 if (filter_next)
403 sflt_retain_locked(filter_next);
404
405 // Warning: filt_release_locked may remove the filter from the queue
406 sflt_release_locked(filter);
407 filter = filter_next;
408 }
409 }
410 lck_rw_done(sock_filter_lock);
411 }
412
413 /*
414 * sflt_termsock
415 *
416 * Detaches all filters from the socket.
417 */
418
419 __private_extern__ void
420 sflt_termsock(
421 struct socket *so)
422 {
423 lck_rw_lock_exclusive(sock_filter_lock);
424
425 struct socket_filter_entry *entry;
426
427 while ((entry = so->so_filt) != NULL) {
428 // Pull filter off the socket
429 so->so_filt = entry->sfe_next_onsocket;
430 entry->sfe_flags |= SFEF_NOSOCKET;
431
432 // Call detach
433 sflt_detach_locked(entry);
434
435 // On sflt_termsock, we can't return until the detach function has been called
436 // Call the detach function - this is gross because the socket filter
437 // entry could be freed when we drop the lock, so we make copies on
438 // the stack and retain everything we need before dropping the lock
439 if ((entry->sfe_flags & SFEF_NODETACH) == 0 &&
440 entry->sfe_filter->sf_filter.sf_detach) {
441 void *sfe_cookie = entry->sfe_cookie;
442 struct socket_filter *sfe_filter = entry->sfe_filter;
443
444 // Retain the socket filter
445 sflt_retain_locked(sfe_filter);
446
447 // Mark that we've called the detach function
448 entry->sfe_flags |= SFEF_NODETACH;
449
450 // Drop the lock around the call to the detach function
451 lck_rw_unlock_exclusive(sock_filter_lock);
452 sfe_filter->sf_filter.sf_detach(sfe_cookie, so);
453 lck_rw_lock_exclusive(sock_filter_lock);
454
455 // Release the filter
456 sflt_release_locked(sfe_filter);
457 }
458 }
459
460 lck_rw_unlock_exclusive(sock_filter_lock);
461 }
462
463
464 static void
465 sflt_notify_internal(
466 struct socket *so,
467 sflt_event_t event,
468 void *param,
469 sflt_handle handle)
470 {
471 if (so->so_filt == NULL) return;
472
473 struct socket_filter_entry *entry;
474 int unlocked = 0;
475
476 lck_rw_lock_shared(sock_filter_lock);
477 for (entry = so->so_filt; entry; entry = entry->sfe_next_onsocket) {
478 if ((entry->sfe_flags & SFEF_ATTACHED)
479 && entry->sfe_filter->sf_filter.sf_notify &&
480 ((handle && entry->sfe_filter->sf_filter.sf_handle != handle) ||
481 !handle)) {
482 // Retain the filter entry and release the socket filter lock
483 sflt_entry_retain(entry);
484 lck_rw_unlock_shared(sock_filter_lock);
485
486 // If the socket isn't already unlocked, unlock it
487 if (unlocked == 0) {
488 unlocked = 1;
489 socket_unlock(so, 0);
490 }
491
492 // Finally call the filter
493 entry->sfe_filter->sf_filter.
494 sf_notify(entry->sfe_cookie, so, event, param);
495
496 // Take the socket filter lock again and release the entry
497 lck_rw_lock_shared(sock_filter_lock);
498 sflt_entry_release(entry);
499 }
500 }
501 lck_rw_unlock_shared(sock_filter_lock);
502
503 if (unlocked != 0) {
504 socket_lock(so, 0);
505 }
506 }
507
508 __private_extern__ void
509 sflt_notify(
510 struct socket *so,
511 sflt_event_t event,
512 void *param)
513 {
514 sflt_notify_internal(so, event, param, 0);
515 }
516
517 static void
518 sflt_notify_after_register(
519 struct socket *so,
520 sflt_event_t event,
521 sflt_handle handle)
522 {
523 sflt_notify_internal(so, event, NULL, handle);
524 }
525
526 __private_extern__ int
527 sflt_ioctl(
528 struct socket *so,
529 u_long cmd,
530 caddr_t data)
531 {
532 if (so->so_filt == NULL) return 0;
533
534 struct socket_filter_entry *entry;
535 int unlocked = 0;
536 int error = 0;
537
538 lck_rw_lock_shared(sock_filter_lock);
539 for (entry = so->so_filt; entry && error == 0;
540 entry = entry->sfe_next_onsocket) {
541 if ((entry->sfe_flags & SFEF_ATTACHED)
542 && entry->sfe_filter->sf_filter.sf_ioctl) {
543 // Retain the filter entry and release the socket filter lock
544 sflt_entry_retain(entry);
545 lck_rw_unlock_shared(sock_filter_lock);
546
547 // If the socket isn't already unlocked, unlock it
548 if (unlocked == 0) {
549 socket_unlock(so, 0);
550 unlocked = 1;
551 }
552
553 // Call the filter
554 error = entry->sfe_filter->sf_filter.
555 sf_ioctl(entry->sfe_cookie, so, cmd, data);
556
557 // Take the socket filter lock again and release the entry
558 lck_rw_lock_shared(sock_filter_lock);
559 sflt_entry_release(entry);
560 }
561 }
562 lck_rw_unlock_shared(sock_filter_lock);
563
564 if (unlocked) {
565 socket_lock(so, 0);
566 }
567
568 return error;
569 }
570
571 __private_extern__ int
572 sflt_bind(
573 struct socket *so,
574 const struct sockaddr *nam)
575 {
576 if (so->so_filt == NULL) return 0;
577
578 struct socket_filter_entry *entry;
579 int unlocked = 0;
580 int error = 0;
581
582 lck_rw_lock_shared(sock_filter_lock);
583 for (entry = so->so_filt; entry && error == 0;
584 entry = entry->sfe_next_onsocket) {
585 if ((entry->sfe_flags & SFEF_ATTACHED)
586 && entry->sfe_filter->sf_filter.sf_bind) {
587 // Retain the filter entry and release the socket filter lock
588 sflt_entry_retain(entry);
589 lck_rw_unlock_shared(sock_filter_lock);
590
591 // If the socket isn't already unlocked, unlock it
592 if (unlocked == 0) {
593 socket_unlock(so, 0);
594 unlocked = 1;
595 }
596
597 // Call the filter
598 error = entry->sfe_filter->sf_filter.
599 sf_bind(entry->sfe_cookie, so, nam);
600
601 // Take the socket filter lock again and release the entry
602 lck_rw_lock_shared(sock_filter_lock);
603 sflt_entry_release(entry);
604 }
605 }
606 lck_rw_unlock_shared(sock_filter_lock);
607
608 if (unlocked) {
609 socket_lock(so, 0);
610 }
611
612 return error;
613 }
614
615 __private_extern__ int
616 sflt_listen(
617 struct socket *so)
618 {
619 if (so->so_filt == NULL) return 0;
620
621 struct socket_filter_entry *entry;
622 int unlocked = 0;
623 int error = 0;
624
625 lck_rw_lock_shared(sock_filter_lock);
626 for (entry = so->so_filt; entry && error == 0;
627 entry = entry->sfe_next_onsocket) {
628 if ((entry->sfe_flags & SFEF_ATTACHED)
629 && entry->sfe_filter->sf_filter.sf_listen) {
630 // Retain the filter entry and release the socket filter lock
631 sflt_entry_retain(entry);
632 lck_rw_unlock_shared(sock_filter_lock);
633
634 // If the socket isn't already unlocked, unlock it
635 if (unlocked == 0) {
636 socket_unlock(so, 0);
637 unlocked = 1;
638 }
639
640 // Call the filter
641 error = entry->sfe_filter->sf_filter.
642 sf_listen(entry->sfe_cookie, so);
643
644 // Take the socket filter lock again and release the entry
645 lck_rw_lock_shared(sock_filter_lock);
646 sflt_entry_release(entry);
647 }
648 }
649 lck_rw_unlock_shared(sock_filter_lock);
650
651 if (unlocked) {
652 socket_lock(so, 0);
653 }
654
655 return error;
656 }
657
658 __private_extern__ int
659 sflt_accept(
660 struct socket *head,
661 struct socket *so,
662 const struct sockaddr *local,
663 const struct sockaddr *remote)
664 {
665 if (so->so_filt == NULL) return 0;
666
667 struct socket_filter_entry *entry;
668 int unlocked = 0;
669 int error = 0;
670
671 lck_rw_lock_shared(sock_filter_lock);
672 for (entry = so->so_filt; entry && error == 0;
673 entry = entry->sfe_next_onsocket) {
674 if ((entry->sfe_flags & SFEF_ATTACHED)
675 && entry->sfe_filter->sf_filter.sf_accept) {
676 // Retain the filter entry and release the socket filter lock
677 sflt_entry_retain(entry);
678 lck_rw_unlock_shared(sock_filter_lock);
679
680 // If the socket isn't already unlocked, unlock it
681 if (unlocked == 0) {
682 socket_unlock(so, 0);
683 unlocked = 1;
684 }
685
686 // Call the filter
687 error = entry->sfe_filter->sf_filter.
688 sf_accept(entry->sfe_cookie, head, so, local, remote);
689
690 // Take the socket filter lock again and release the entry
691 lck_rw_lock_shared(sock_filter_lock);
692 sflt_entry_release(entry);
693 }
694 }
695 lck_rw_unlock_shared(sock_filter_lock);
696
697 if (unlocked) {
698 socket_lock(so, 0);
699 }
700
701 return error;
702 }
703
704 __private_extern__ int
705 sflt_getsockname(
706 struct socket *so,
707 struct sockaddr **local)
708 {
709 if (so->so_filt == NULL) return 0;
710
711 struct socket_filter_entry *entry;
712 int unlocked = 0;
713 int error = 0;
714
715 lck_rw_lock_shared(sock_filter_lock);
716 for (entry = so->so_filt; entry && error == 0;
717 entry = entry->sfe_next_onsocket) {
718 if ((entry->sfe_flags & SFEF_ATTACHED)
719 && entry->sfe_filter->sf_filter.sf_getsockname) {
720 // Retain the filter entry and release the socket filter lock
721 sflt_entry_retain(entry);
722 lck_rw_unlock_shared(sock_filter_lock);
723
724 // If the socket isn't already unlocked, unlock it
725 if (unlocked == 0) {
726 socket_unlock(so, 0);
727 unlocked = 1;
728 }
729
730 // Call the filter
731 error = entry->sfe_filter->sf_filter.
732 sf_getsockname(entry->sfe_cookie, so, local);
733
734 // Take the socket filter lock again and release the entry
735 lck_rw_lock_shared(sock_filter_lock);
736 sflt_entry_release(entry);
737 }
738 }
739 lck_rw_unlock_shared(sock_filter_lock);
740
741 if (unlocked) {
742 socket_lock(so, 0);
743 }
744
745 return error;
746 }
747
748 __private_extern__ int
749 sflt_getpeername(
750 struct socket *so,
751 struct sockaddr **remote)
752 {
753 if (so->so_filt == NULL) return 0;
754
755 struct socket_filter_entry *entry;
756 int unlocked = 0;
757 int error = 0;
758
759 lck_rw_lock_shared(sock_filter_lock);
760 for (entry = so->so_filt; entry && error == 0;
761 entry = entry->sfe_next_onsocket) {
762 if ((entry->sfe_flags & SFEF_ATTACHED)
763 && entry->sfe_filter->sf_filter.sf_getpeername) {
764 // Retain the filter entry and release the socket filter lock
765 sflt_entry_retain(entry);
766 lck_rw_unlock_shared(sock_filter_lock);
767
768 // If the socket isn't already unlocked, unlock it
769 if (unlocked == 0) {
770 socket_unlock(so, 0);
771 unlocked = 1;
772 }
773
774 // Call the filter
775 error = entry->sfe_filter->sf_filter.
776 sf_getpeername(entry->sfe_cookie, so, remote);
777
778 // Take the socket filter lock again and release the entry
779 lck_rw_lock_shared(sock_filter_lock);
780 sflt_entry_release(entry);
781 }
782 }
783 lck_rw_unlock_shared(sock_filter_lock);
784
785 if (unlocked) {
786 socket_lock(so, 0);
787 }
788
789 return error;
790 }
791
792 __private_extern__ int
793 sflt_connectin(
794 struct socket *so,
795 const struct sockaddr *remote)
796 {
797 if (so->so_filt == NULL) return 0;
798
799 struct socket_filter_entry *entry;
800 int unlocked = 0;
801 int error = 0;
802
803 lck_rw_lock_shared(sock_filter_lock);
804 for (entry = so->so_filt; entry && error == 0;
805 entry = entry->sfe_next_onsocket) {
806 if ((entry->sfe_flags & SFEF_ATTACHED)
807 && entry->sfe_filter->sf_filter.sf_connect_in) {
808 // Retain the filter entry and release the socket filter lock
809 sflt_entry_retain(entry);
810 lck_rw_unlock_shared(sock_filter_lock);
811
812 // If the socket isn't already unlocked, unlock it
813 if (unlocked == 0) {
814 socket_unlock(so, 0);
815 unlocked = 1;
816 }
817
818 // Call the filter
819 error = entry->sfe_filter->sf_filter.
820 sf_connect_in(entry->sfe_cookie, so, remote);
821
822 // Take the socket filter lock again and release the entry
823 lck_rw_lock_shared(sock_filter_lock);
824 sflt_entry_release(entry);
825 }
826 }
827 lck_rw_unlock_shared(sock_filter_lock);
828
829 if (unlocked) {
830 socket_lock(so, 0);
831 }
832
833 return error;
834 }
835
836 __private_extern__ int
837 sflt_connectout(
838 struct socket *so,
839 const struct sockaddr *nam)
840 {
841 if (so->so_filt == NULL) return 0;
842
843 struct socket_filter_entry *entry;
844 int unlocked = 0;
845 int error = 0;
846
847 lck_rw_lock_shared(sock_filter_lock);
848 for (entry = so->so_filt; entry && error == 0;
849 entry = entry->sfe_next_onsocket) {
850 if ((entry->sfe_flags & SFEF_ATTACHED)
851 && entry->sfe_filter->sf_filter.sf_connect_out) {
852 // Retain the filter entry and release the socket filter lock
853 sflt_entry_retain(entry);
854 lck_rw_unlock_shared(sock_filter_lock);
855
856 // If the socket isn't already unlocked, unlock it
857 if (unlocked == 0) {
858 socket_unlock(so, 0);
859 unlocked = 1;
860 }
861
862 // Call the filter
863 error = entry->sfe_filter->sf_filter.
864 sf_connect_out(entry->sfe_cookie, so, nam);
865
866 // Take the socket filter lock again and release the entry
867 lck_rw_lock_shared(sock_filter_lock);
868 sflt_entry_release(entry);
869 }
870 }
871 lck_rw_unlock_shared(sock_filter_lock);
872
873 if (unlocked) {
874 socket_lock(so, 0);
875 }
876
877 return error;
878 }
879
880 __private_extern__ int
881 sflt_setsockopt(
882 struct socket *so,
883 struct sockopt *sopt)
884 {
885 if (so->so_filt == NULL) return 0;
886
887 struct socket_filter_entry *entry;
888 int unlocked = 0;
889 int error = 0;
890
891 lck_rw_lock_shared(sock_filter_lock);
892 for (entry = so->so_filt; entry && error == 0;
893 entry = entry->sfe_next_onsocket) {
894 if ((entry->sfe_flags & SFEF_ATTACHED)
895 && entry->sfe_filter->sf_filter.sf_setoption) {
896 // Retain the filter entry and release the socket filter lock
897 sflt_entry_retain(entry);
898 lck_rw_unlock_shared(sock_filter_lock);
899
900 // If the socket isn't already unlocked, unlock it
901 if (unlocked == 0) {
902 socket_unlock(so, 0);
903 unlocked = 1;
904 }
905
906 // Call the filter
907 error = entry->sfe_filter->sf_filter.
908 sf_setoption(entry->sfe_cookie, so, sopt);
909
910 // Take the socket filter lock again and release the entry
911 lck_rw_lock_shared(sock_filter_lock);
912 sflt_entry_release(entry);
913 }
914 }
915 lck_rw_unlock_shared(sock_filter_lock);
916
917 if (unlocked) {
918 socket_lock(so, 0);
919 }
920
921 return error;
922 }
923
924 __private_extern__ int
925 sflt_getsockopt(
926 struct socket *so,
927 struct sockopt *sopt)
928 {
929 if (so->so_filt == NULL) return 0;
930
931 struct socket_filter_entry *entry;
932 int unlocked = 0;
933 int error = 0;
934
935 lck_rw_lock_shared(sock_filter_lock);
936 for (entry = so->so_filt; entry && error == 0;
937 entry = entry->sfe_next_onsocket) {
938 if ((entry->sfe_flags & SFEF_ATTACHED)
939 && entry->sfe_filter->sf_filter.sf_getoption) {
940 // Retain the filter entry and release the socket filter lock
941 sflt_entry_retain(entry);
942 lck_rw_unlock_shared(sock_filter_lock);
943
944 // If the socket isn't already unlocked, unlock it
945 if (unlocked == 0) {
946 socket_unlock(so, 0);
947 unlocked = 1;
948 }
949
950 // Call the filter
951 error = entry->sfe_filter->sf_filter.
952 sf_getoption(entry->sfe_cookie, so, sopt);
953
954 // Take the socket filter lock again and release the entry
955 lck_rw_lock_shared(sock_filter_lock);
956 sflt_entry_release(entry);
957 }
958 }
959 lck_rw_unlock_shared(sock_filter_lock);
960
961 if (unlocked) {
962 socket_lock(so, 0);
963 }
964
965 return error;
966 }
967
968 __private_extern__ int
969 sflt_data_out(
970 struct socket *so,
971 const struct sockaddr *to,
972 mbuf_t *data,
973 mbuf_t *control,
974 sflt_data_flag_t flags)
975 {
976 if (so->so_filt == NULL) return 0;
977
978 struct socket_filter_entry *entry;
979 int unlocked = 0;
980 int setsendthread = 0;
981 int error = 0;
982
983 lck_rw_lock_shared(sock_filter_lock);
984 for (entry = so->so_filt; entry && error == 0;
985 entry = entry->sfe_next_onsocket) {
986 if ((entry->sfe_flags & SFEF_ATTACHED)
987 && entry->sfe_filter->sf_filter.sf_data_out) {
988 // Retain the filter entry and release the socket filter lock
989 sflt_entry_retain(entry);
990 lck_rw_unlock_shared(sock_filter_lock);
991
992 // If the socket isn't already unlocked, unlock it
993 if (unlocked == 0) {
994 if (so->so_send_filt_thread == NULL) {
995 setsendthread = 1;
996 so->so_send_filt_thread = current_thread();
997 }
998 socket_unlock(so, 0);
999 unlocked = 1;
1000 }
1001
1002 // Call the filter
1003 error = entry->sfe_filter->sf_filter.
1004 sf_data_out(entry->sfe_cookie, so, to, data, control, flags);
1005
1006 // Take the socket filter lock again and release the entry
1007 lck_rw_lock_shared(sock_filter_lock);
1008 sflt_entry_release(entry);
1009 }
1010 }
1011 lck_rw_unlock_shared(sock_filter_lock);
1012
1013 if (unlocked) {
1014 socket_lock(so, 0);
1015 if (setsendthread) so->so_send_filt_thread = NULL;
1016 }
1017
1018 return error;
1019 }
1020
1021 __private_extern__ int
1022 sflt_data_in(
1023 struct socket *so,
1024 const struct sockaddr *from,
1025 mbuf_t *data,
1026 mbuf_t *control,
1027 sflt_data_flag_t flags)
1028 {
1029 if (so->so_filt == NULL) return 0;
1030
1031 struct socket_filter_entry *entry;
1032 int error = 0;
1033 int unlocked = 0;
1034
1035 lck_rw_lock_shared(sock_filter_lock);
1036
1037 for (entry = so->so_filt; entry && (error == 0);
1038 entry = entry->sfe_next_onsocket) {
1039 if ((entry->sfe_flags & SFEF_ATTACHED) &&
1040 entry->sfe_filter->sf_filter.sf_data_in) {
1041 // Retain the filter entry and release the socket filter lock
1042 sflt_entry_retain(entry);
1043 lck_rw_unlock_shared(sock_filter_lock);
1044
1045 // If the socket isn't already unlocked, unlock it
1046 if (unlocked == 0) {
1047 unlocked = 1;
1048 socket_unlock(so, 0);
1049 }
1050
1051 // Call the filter
1052 error = entry->sfe_filter->sf_filter.sf_data_in(
1053 entry->sfe_cookie, so, from, data, control, flags);
1054
1055 // Take the socket filter lock again and release the entry
1056 lck_rw_lock_shared(sock_filter_lock);
1057 sflt_entry_release(entry);
1058 }
1059 }
1060 lck_rw_unlock_shared(sock_filter_lock);
1061
1062 if (unlocked) {
1063 socket_lock(so, 0);
1064 }
1065
1066 return error;
1067 }
1068
1069 #pragma mark -- KPI --
1070
1071 errno_t
1072 sflt_attach(
1073 socket_t socket,
1074 sflt_handle handle)
1075 {
1076 socket_lock(socket, 1);
1077 errno_t result = sflt_attach_internal(socket, handle);
1078 socket_unlock(socket, 1);
1079 return result;
1080 }
1081
1082 errno_t
1083 sflt_detach(
1084 socket_t socket,
1085 sflt_handle handle)
1086 {
1087 struct socket_filter_entry *entry;
1088 errno_t result = 0;
1089
1090 if (socket == NULL || handle == 0)
1091 return EINVAL;
1092
1093 lck_rw_lock_exclusive(sock_filter_lock);
1094 for (entry = socket->so_filt; entry;
1095 entry = entry->sfe_next_onsocket) {
1096 if (entry->sfe_filter->sf_filter.sf_handle == handle &&
1097 (entry->sfe_flags & SFEF_ATTACHED) != 0) {
1098 break;
1099 }
1100 }
1101
1102 if (entry != NULL) {
1103 sflt_detach_locked(entry);
1104 }
1105 lck_rw_unlock_exclusive(sock_filter_lock);
1106
1107 return result;
1108 }
1109
1110 struct solist {
1111 struct solist *next;
1112 struct socket *so;
1113 };
1114
1115 errno_t
1116 sflt_register(
1117 const struct sflt_filter *filter,
1118 int domain,
1119 int type,
1120 int protocol)
1121 {
1122 struct socket_filter *sock_filt = NULL;
1123 struct socket_filter *match = NULL;
1124 int error = 0;
1125 struct protosw *pr = pffindproto(domain, protocol, type);
1126 unsigned int len;
1127 struct socket *so;
1128 struct inpcb *inp;
1129 struct solist *solisthead = NULL, *solist = NULL;
1130
1131 if (pr == NULL)
1132 return ENOENT;
1133
1134 if (filter->sf_attach == NULL || filter->sf_detach == NULL ||
1135 filter->sf_handle == 0 || filter->sf_name == NULL)
1136 return EINVAL;
1137
1138 /* Allocate the socket filter */
1139 MALLOC(sock_filt, struct socket_filter *, sizeof (*sock_filt),
1140 M_IFADDR, M_WAITOK);
1141 if (sock_filt == NULL) {
1142 return ENOBUFS;
1143 }
1144
1145 bzero(sock_filt, sizeof (*sock_filt));
1146
1147 /* Legacy sflt_filter length; current structure minus extended */
1148 len = sizeof (*filter) - sizeof (struct sflt_filter_ext);
1149 /*
1150 * Include extended fields if filter defines SFLT_EXTENDED.
1151 * We've zeroed out our internal sflt_filter placeholder,
1152 * so any unused portion would have been taken care of.
1153 */
1154 if (filter->sf_flags & SFLT_EXTENDED) {
1155 unsigned int ext_len = filter->sf_len;
1156
1157 if (ext_len > sizeof (struct sflt_filter_ext))
1158 ext_len = sizeof (struct sflt_filter_ext);
1159
1160 len += ext_len;
1161 }
1162 bcopy(filter, &sock_filt->sf_filter, len);
1163
1164 lck_rw_lock_exclusive(sock_filter_lock);
1165 /* Look for an existing entry */
1166 TAILQ_FOREACH(match, &sock_filter_head, sf_global_next) {
1167 if (match->sf_filter.sf_handle ==
1168 sock_filt->sf_filter.sf_handle) {
1169 break;
1170 }
1171 }
1172
1173 /* Add the entry only if there was no existing entry */
1174 if (match == NULL) {
1175 TAILQ_INSERT_TAIL(&sock_filter_head, sock_filt, sf_global_next);
1176 if ((sock_filt->sf_filter.sf_flags & SFLT_GLOBAL) != 0) {
1177 TAILQ_INSERT_TAIL(&pr->pr_filter_head, sock_filt,
1178 sf_protosw_next);
1179 sock_filt->sf_proto = pr;
1180 }
1181 sflt_retain_locked(sock_filt);
1182 }
1183 lck_rw_unlock_exclusive(sock_filter_lock);
1184
1185 if (match != NULL) {
1186 FREE(sock_filt, M_IFADDR);
1187 return EEXIST;
1188 }
1189
1190 if (!(filter->sf_flags & SFLT_EXTENDED_REGISTRY))
1191 return error;
1192
1193 /*
1194 * Setup the filter on the TCP and UDP sockets already created.
1195 */
1196 #define SOLIST_ADD(_so) do { \
1197 solist->next = solisthead; \
1198 sock_retain((_so)); \
1199 solist->so = (_so); \
1200 solisthead = solist; \
1201 } while (0)
1202 if (protocol == IPPROTO_TCP) {
1203 lck_rw_lock_shared(tcbinfo.mtx);
1204 LIST_FOREACH(inp, tcbinfo.listhead, inp_list) {
1205 so = inp->inp_socket;
1206 if (so == NULL || so->so_state & SS_DEFUNCT ||
1207 so->so_state & SS_NOFDREF ||
1208 !INP_CHECK_SOCKAF(so, domain) ||
1209 !INP_CHECK_SOCKTYPE(so, type))
1210 continue;
1211 MALLOC(solist, struct solist *, sizeof(*solist),
1212 M_IFADDR, M_NOWAIT);
1213 if (!solist)
1214 continue;
1215 SOLIST_ADD(so);
1216 }
1217 lck_rw_done(tcbinfo.mtx);
1218 } else if (protocol == IPPROTO_UDP) {
1219 lck_rw_lock_shared(udbinfo.mtx);
1220 LIST_FOREACH(inp, udbinfo.listhead, inp_list) {
1221 so = inp->inp_socket;
1222 if (so == NULL || so->so_state & SS_DEFUNCT ||
1223 so->so_state & SS_NOFDREF ||
1224 !INP_CHECK_SOCKAF(so, domain) ||
1225 !INP_CHECK_SOCKTYPE(so, type))
1226 continue;
1227 MALLOC(solist, struct solist *, sizeof(*solist),
1228 M_IFADDR, M_NOWAIT);
1229 if (!solist)
1230 continue;
1231 SOLIST_ADD(so);
1232 }
1233 lck_rw_done(udbinfo.mtx);
1234 }
1235 /* XXX it's possible to walk the raw socket list as well */
1236 #undef SOLIST_ADD
1237
1238 while (solisthead) {
1239 sflt_handle handle = filter->sf_handle;
1240
1241 so = solisthead->so;
1242 sflt_initsock(so);
1243
1244 if (so->so_state & SS_ISCONNECTING)
1245 sflt_notify_after_register(so, sock_evt_connecting,
1246 handle);
1247 else if (so->so_state & SS_ISCONNECTED)
1248 sflt_notify_after_register(so, sock_evt_connected,
1249 handle);
1250 else if ((so->so_state &
1251 (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE)) ==
1252 (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE))
1253 sflt_notify_after_register(so, sock_evt_disconnecting,
1254 handle);
1255 else if ((so->so_state &
1256 (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED)) ==
1257 (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED))
1258 sflt_notify_after_register(so, sock_evt_disconnected,
1259 handle);
1260 else if (so->so_state & SS_CANTSENDMORE)
1261 sflt_notify_after_register(so, sock_evt_cantsendmore,
1262 handle);
1263 else if (so->so_state & SS_CANTRCVMORE)
1264 sflt_notify_after_register(so, sock_evt_cantrecvmore,
1265 handle);
1266 /* XXX no easy way to post the sock_evt_closing event */
1267 sock_release(so);
1268 solist = solisthead;
1269 solisthead = solisthead->next;
1270 FREE(solist, M_IFADDR);
1271 }
1272
1273 return error;
1274 }
1275
1276 errno_t
1277 sflt_unregister(
1278 sflt_handle handle)
1279 {
1280 struct socket_filter *filter;
1281 lck_rw_lock_exclusive(sock_filter_lock);
1282
1283 /* Find the entry by the handle */
1284 TAILQ_FOREACH(filter, &sock_filter_head, sf_global_next) {
1285 if (filter->sf_filter.sf_handle == handle)
1286 break;
1287 }
1288
1289 if (filter) {
1290 // Remove it from the global list
1291 TAILQ_REMOVE(&sock_filter_head, filter, sf_global_next);
1292
1293 // Remove it from the protosw list
1294 if ((filter->sf_filter.sf_flags & SFLT_GLOBAL) != 0) {
1295 TAILQ_REMOVE(&filter->sf_proto->pr_filter_head, filter, sf_protosw_next);
1296 }
1297
1298 // Detach from any sockets
1299 struct socket_filter_entry *entry = NULL;
1300
1301 for (entry = filter->sf_entry_head; entry; entry = entry->sfe_next_onfilter) {
1302 sflt_detach_locked(entry);
1303 }
1304
1305 // Release the filter
1306 sflt_release_locked(filter);
1307 }
1308
1309 lck_rw_unlock_exclusive(sock_filter_lock);
1310
1311 if (filter == NULL)
1312 return ENOENT;
1313
1314 return 0;
1315 }
1316
1317 errno_t
1318 sock_inject_data_in(
1319 socket_t so,
1320 const struct sockaddr* from,
1321 mbuf_t data,
1322 mbuf_t control,
1323 sflt_data_flag_t flags)
1324 {
1325 int error = 0;
1326 if (so == NULL || data == NULL) return EINVAL;
1327
1328 if (flags & sock_data_filt_flag_oob) {
1329 return ENOTSUP;
1330 }
1331
1332 socket_lock(so, 1);
1333
1334 if (from) {
1335 if (sbappendaddr(&so->so_rcv, (struct sockaddr*)(uintptr_t)from, data,
1336 control, NULL))
1337 sorwakeup(so);
1338 goto done;
1339 }
1340
1341 if (control) {
1342 if (sbappendcontrol(&so->so_rcv, data, control, NULL))
1343 sorwakeup(so);
1344 goto done;
1345 }
1346
1347 if (flags & sock_data_filt_flag_record) {
1348 if (control || from) {
1349 error = EINVAL;
1350 goto done;
1351 }
1352 if (sbappendrecord(&so->so_rcv, (struct mbuf*)data))
1353 sorwakeup(so);
1354 goto done;
1355 }
1356
1357 if (sbappend(&so->so_rcv, data))
1358 sorwakeup(so);
1359 done:
1360 socket_unlock(so, 1);
1361 return error;
1362 }
1363
1364 errno_t
1365 sock_inject_data_out(
1366 socket_t so,
1367 const struct sockaddr* to,
1368 mbuf_t data,
1369 mbuf_t control,
1370 sflt_data_flag_t flags)
1371 {
1372 int sosendflags = 0;
1373 if (flags & sock_data_filt_flag_oob) sosendflags = MSG_OOB;
1374 return sosend(so, (struct sockaddr*)(uintptr_t)to, NULL,
1375 data, control, sosendflags);
1376 }
1377
1378 sockopt_dir
1379 sockopt_direction(
1380 sockopt_t sopt)
1381 {
1382 return (sopt->sopt_dir == SOPT_GET) ? sockopt_get : sockopt_set;
1383 }
1384
1385 int
1386 sockopt_level(
1387 sockopt_t sopt)
1388 {
1389 return sopt->sopt_level;
1390 }
1391
1392 int
1393 sockopt_name(
1394 sockopt_t sopt)
1395 {
1396 return sopt->sopt_name;
1397 }
1398
1399 size_t
1400 sockopt_valsize(
1401 sockopt_t sopt)
1402 {
1403 return sopt->sopt_valsize;
1404 }
1405
1406 errno_t
1407 sockopt_copyin(
1408 sockopt_t sopt,
1409 void *data,
1410 size_t len)
1411 {
1412 return sooptcopyin(sopt, data, len, len);
1413 }
1414
1415 errno_t
1416 sockopt_copyout(
1417 sockopt_t sopt,
1418 void *data,
1419 size_t len)
1420 {
1421 return sooptcopyout(sopt, data, len);
1422 }