]>
git.saurik.com Git - apple/xnu.git/blob - bsd/net/kext_net.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (C) 1999 Apple Computer, Inc. */
25 * Support for Network Kernel Extensions: Socket Filters
27 * Justin C. Walker, 990319
30 #include <sys/types.h>
31 #include <sys/queue.h>
32 #include <sys/malloc.h>
33 #include <sys/param.h>
35 #include <sys/domain.h>
36 #include <sys/protosw.h>
37 #include <sys/socket.h>
38 #include <machine/spl.h>
41 /* List of kernel extensions (networking) known to kernel */
42 struct nf_list nf_list
;
45 * Register a global filter for the specified protocol
46 * Make a few checks and then insert the new descriptor in the
47 * filter list and, if global, in its protosw's chain.
50 register_sockfilter(struct NFDescriptor
*nfp
, struct NFDescriptor
*nfp1
,
51 struct protosw
*pr
, int flags
)
53 static int NF_initted
= 0;
65 * Install the extension:
66 * First, put it in the global list of all filters
67 * Then, if global, install in the protosw's list
69 TAILQ_INSERT_TAIL(&nf_list
, nfp
, nf_list
);
70 if (nfp
->nf_flags
& NFD_GLOBAL
)
71 { if (flags
& NFF_BEFORE
)
73 { TAILQ_INSERT_HEAD(&pr
->pr_sfilter
,
76 TAILQ_INSERT_BEFORE(nfp1
, nfp
, nf_next
);
77 } else /* Default: AFTER */
79 { TAILQ_INSERT_TAIL(&pr
->pr_sfilter
,
82 TAILQ_INSERT_AFTER(&pr
->pr_sfilter
, nfp1
,
90 unregister_sockfilter(struct NFDescriptor
*nfp
, struct protosw
*pr
, int flags
)
94 TAILQ_REMOVE(&nf_list
, nfp
, nf_list
);
95 /* Only globals are attached to the protosw entry */
96 if (nfp
->nf_flags
& NFD_GLOBAL
)
97 TAILQ_REMOVE(&pr
->pr_sfilter
, nfp
, nf_next
);
102 struct NFDescriptor
*
103 find_nke(unsigned int handle
)
104 { struct NFDescriptor
*nfp
;
106 nfp
= nf_list
.tqh_first
;
108 { if (nfp
->nf_handle
== handle
)
110 nfp
= nfp
->nf_list
.tqe_next
;
116 * Insert a previously registered, non-global, NKE into the list of
117 * active NKEs for this socket. Then invoke its "attach/create" entry.
118 * Assumed called with protection in place (spl/mutex/whatever)
119 * XXX: How to which extension is not found, on error.
122 nke_insert(struct socket
*so
, struct so_nke
*np
)
124 struct kextcb
*kp
, *kp1
;
125 struct NFDescriptor
*nf1
, *nf2
= NULL
;
127 if (np
->nke_where
!= NULL
)
128 { if ((nf2
= find_nke(np
->nke_where
)) == NULL
)
130 return(ENXIO
);/* XXX */
134 if ((nf1
= find_nke(np
->nke_handle
)) == NULL
)
136 return(ENXIO
);/* XXX */
141 if (np
->nke_flags
& NFF_BEFORE
)
144 { if (kp
->e_nfd
== nf2
)
150 return(ENXIO
);/* XXX */
155 { if (kp
->e_nfd
== nf2
)
161 return(ENXIO
);/* XXX */
166 * Here with kp1 pointing to the insertion point.
167 * If null, this is first entry.
168 * Now, create and insert the descriptor.
171 MALLOC(kp
, struct kextcb
*, sizeof(*kp
), M_TEMP
, M_WAITOK
);
173 return(ENOBUFS
); /* so_free will clean up */
174 bzero(kp
, sizeof (*kp
));
176 { kp
->e_next
= so
->so_ext
;
179 { kp
->e_next
= kp1
->e_next
;
184 kp
->e_soif
= nf1
->nf_soif
;
185 kp
->e_sout
= nf1
->nf_soutil
;
187 * Ignore return value for create
188 * Everyone gets a chance at startup
190 if (kp
->e_soif
&& kp
->e_soif
->sf_socreate
)
191 (*kp
->e_soif
->sf_socreate
)(so
, so
->so_proto
, kp
);