|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* Copyright (C) 1999 Apple Computer, Inc. */
23:
24: /*
25: * Support for Network Kernel Extensions: Socket Filters
26: *
27: * Justin C. Walker, 990319
28: */
29:
30: #include <sys/types.h>
31: #include <sys/queue.h>
32: #include <sys/malloc.h>
33: #include <sys/param.h>
34: #include <sys/mbuf.h>
35: #include <sys/domain.h>
36: #include <sys/protosw.h>
37: #include <sys/socket.h>
38: #include <machine/spl.h>
39: #include "kext_net.h"
40:
41: /* List of kernel extensions (networking) known to kernel */
42: struct nf_list nf_list;
43:
44: /*
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.
48: */
49: int
50: register_sockfilter(struct NFDescriptor *nfp, struct NFDescriptor *nfp1,
51: struct protosw *pr, int flags)
52: { int s;
53: static int NF_initted = 0;
54:
55: if (nfp == NULL)
56: return(EINVAL);
57:
58: s = splhigh();
59: if (!NF_initted)
60: { NF_initted = 1;
61: TAILQ_INIT(&nf_list);
62: }
63:
64: /*
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
68: */
69: TAILQ_INSERT_TAIL(&nf_list, nfp, nf_list);
70: if (nfp->nf_flags & NFD_GLOBAL)
71: { if (flags & NFF_BEFORE)
72: { if (nfp1 == NULL)
73: { TAILQ_INSERT_HEAD(&pr->pr_sfilter,
74: nfp, nf_next);
75: } else
76: TAILQ_INSERT_BEFORE(nfp1, nfp, nf_next);
77: } else /* Default: AFTER */
78: { if (nfp1 == NULL)
79: { TAILQ_INSERT_TAIL(&pr->pr_sfilter,
80: nfp, nf_next);
81: } else
82: TAILQ_INSERT_AFTER(&pr->pr_sfilter, nfp1,
83: nfp, nf_next);
84: }
85: }
86: splx(s);
87: return(0);
88: }
89:
90: unregister_sockfilter(struct NFDescriptor *nfp, struct protosw *pr, int flags)
91: { int s;
92:
93: s = splhigh();
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);
98: splx(s);
99: return(0);
100: }
101:
102: struct NFDescriptor *
103: find_nke(int handle)
104: { struct NFDescriptor *nfp;
105:
106: nfp = nf_list.tqh_first;
107: while (nfp)
108: { if (nfp->nf_handle == handle)
109: return(nfp);
110: nfp = nfp->nf_next.tqe_next;
111: }
112: return(NULL);
113: }
114:
115: /*
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.
120: */
121: int
122: nke_insert(struct socket *so, struct so_nke *np)
123: { int s, error;
124: struct kextcb *kp, *kp1;
125: struct NFDescriptor *nf1, *nf2 = NULL;
126:
127: if (np->nke_where != NULL)
128: { if ((nf2 = find_nke(np->nke_where)) == NULL)
129: { /* ??? */
130: return(ENXIO);/* XXX */
131: }
132: }
133:
134: if ((nf1 = find_nke(np->nke_handle)) == NULL)
135: { /* ??? */
136: return(ENXIO);/* XXX */
137: }
138:
139: kp = so->so_ext;
140: kp1 = NULL;
141: if (np->nke_flags & NFF_BEFORE)
142: { if (nf2)
143: { while (kp)
144: { if (kp->e_nfd == nf2)
145: break;
146: kp1 = kp;
147: kp = kp->e_next;
148: }
149: if (kp == NULL)
150: return(ENXIO);/* XXX */
151: }
152: } else
153: { if (nf2)
154: { while (kp)
155: { if (kp->e_nfd == nf2)
156: break;
157: kp1 = kp;
158: kp = kp->e_next;
159: }
160: if (kp == NULL)
161: return(ENXIO);/* XXX */
162: }
163: kp1 = kp;
164: }
165: /*
166: * Here with kp1 pointing to the insertion point.
167: * If null, this is first entry.
168: * Now, create and insert the descriptor.
169: */
170:
171: MALLOC(kp, struct kextcb *, sizeof(*kp), M_TEMP, M_WAITOK);
172: if (kp == NULL)
173: return(ENOBUFS); /* so_free will clean up */
174: bzero(kp, sizeof (*kp));
175: if (kp1 == NULL)
176: so->so_ext = kp;
177: else
178: { kp->e_next = kp1->e_next;
179: kp1->e_next = kp;
180: }
181: kp->e_fcb = NULL;
182: kp->e_nfd = nf1;
183: kp->e_soif = nf1->nf_soif;
184: kp->e_sout = nf1->nf_soutil;
185: /*
186: * Ignore return value for create
187: * Everyone gets a chance at startup
188: */
189: if (kp->e_soif && kp->e_soif->sf_socreate)
190: (*kp->e_soif->sf_socreate)(so, so->so_proto, kp);
191: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.