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
60struct 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
73struct 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
83TAILQ_HEAD(socket_filter_list, socket_filter);
84
85static struct socket_filter_list	sock_filter_head;
86static lck_rw_t						*sock_filter_lock = NULL;
87static lck_mtx_t					*sock_filter_cleanup_lock = NULL;
88static struct socket_filter_entry	*sock_filter_cleanup_entries = NULL;
89static thread_t						sock_filter_cleanup_thread = NULL;
90
91static void sflt_cleanup_thread(void *, wait_result_t);
92static void sflt_detach_locked(struct socket_filter_entry *entry);
93
94#pragma mark -- Internal State Management --
95
96__private_extern__ void
97sflt_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
116static void
117sflt_retain_locked(
118	struct socket_filter	*filter)
119{
120	filter->sf_refcount++;
121}
122
123static void
124sflt_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
142static void
143sflt_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
150static void
151sflt_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
185static void
186sflt_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
260static int
261sflt_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
333errno_t
334sflt_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
359static void
360sflt_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
372sflt_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
420sflt_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
464static void
465sflt_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
509sflt_notify(
510	struct socket	*so,
511	sflt_event_t	event,
512	void		*param)
513{
514	sflt_notify_internal(so, event, param, 0);
515}
516
517static void
518sflt_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
527sflt_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
572sflt_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
616sflt_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
659sflt_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
705sflt_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
749sflt_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
793sflt_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
837sflt_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
881sflt_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
925sflt_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
969sflt_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
1022sflt_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
1071errno_t
1072sflt_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
1082errno_t
1083sflt_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
1110struct solist {
1111	struct solist *next;
1112	struct socket *so;
1113};
1114
1115errno_t
1116sflt_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
1276errno_t
1277sflt_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
1317errno_t
1318sock_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);
1359done:
1360	socket_unlock(so, 1);
1361	return error;
1362}
1363
1364errno_t
1365sock_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
1378sockopt_dir
1379sockopt_direction(
1380	sockopt_t	sopt)
1381{
1382	return (sopt->sopt_dir == SOPT_GET) ? sockopt_get : sockopt_set;
1383}
1384
1385int
1386sockopt_level(
1387	sockopt_t	sopt)
1388{
1389	return sopt->sopt_level;
1390}
1391
1392int
1393sockopt_name(
1394	sockopt_t	sopt)
1395{
1396	return sopt->sopt_name;
1397}
1398
1399size_t
1400sockopt_valsize(
1401	sockopt_t	sopt)
1402{
1403	return sopt->sopt_valsize;
1404}
1405
1406errno_t
1407sockopt_copyin(
1408	sockopt_t	sopt,
1409	void *data,
1410	size_t	len)
1411{
1412	return sooptcopyin(sopt, data, len, len);
1413}
1414
1415errno_t
1416sockopt_copyout(
1417	sockopt_t	sopt,
1418	void *data,
1419	size_t	len)
1420{
1421	return sooptcopyout(sopt, data, len);
1422}
1423