xref: /openbsd-src/sys/kern/uipc_domain.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: uipc_domain.c,v 1.32 2011/07/09 00:47:18 henning Exp $	*/
2 /*	$NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $	*/
3 
4 /*
5  * Copyright (c) 1982, 1986, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	@(#)uipc_domain.c	8.2 (Berkeley) 10/18/93
33  */
34 
35 #include <sys/param.h>
36 #include <sys/socket.h>
37 #include <sys/protosw.h>
38 #include <sys/domain.h>
39 #include <sys/mbuf.h>
40 #include <sys/time.h>
41 #include <sys/kernel.h>
42 #include <sys/systm.h>
43 #include <sys/proc.h>
44 #include <uvm/uvm_extern.h>
45 #include <sys/sysctl.h>
46 #include <sys/timeout.h>
47 
48 #include "bluetooth.h"
49 #include "bpfilter.h"
50 #include "pflow.h"
51 
52 struct	domain *domains;
53 
54 void		pffasttimo(void *);
55 void		pfslowtimo(void *);
56 struct domain *	pffinddomain(int);
57 
58 #if defined (KEY) || defined (IPSEC) || defined (TCP_SIGNATURE)
59 int pfkey_init(void);
60 #endif /* KEY || IPSEC || TCP_SIGNATURE */
61 
62 #define	ADDDOMAIN(x)	{ \
63 	extern struct domain __CONCAT(x,domain); \
64 	__CONCAT(x,domain.dom_next) = domains; \
65 	domains = &__CONCAT(x,domain); \
66 }
67 
68 void
69 domaininit(void)
70 {
71 	struct domain *dp;
72 	struct protosw *pr;
73 	static struct timeout pffast_timeout;
74 	static struct timeout pfslow_timeout;
75 
76 #undef unix
77 	/*
78 	 * KAME NOTE: ADDDOMAIN(route) is moved to the last part so that
79 	 * it will be initialized as the *first* element.  confusing!
80 	 */
81 #ifndef lint
82 	ADDDOMAIN(unix);
83 #ifdef INET
84 	ADDDOMAIN(inet);
85 #endif
86 #ifdef INET6
87 	ADDDOMAIN(inet6);
88 #endif /* INET6 */
89 #if defined (KEY) || defined (IPSEC) || defined (TCP_SIGNATURE)
90 	pfkey_init();
91 #endif /* KEY || IPSEC */
92 #ifdef MPLS
93        ADDDOMAIN(mpls);
94 #endif
95 #ifdef NATM
96 	ADDDOMAIN(natm);
97 #endif
98 #ifdef IPSEC
99 #ifdef __KAME__
100 	ADDDOMAIN(key);
101 #endif
102 #endif
103 #if NBLUETOOTH > 0
104 	ADDDOMAIN(bt);
105 #endif
106 	ADDDOMAIN(route);
107 #endif
108 
109 	for (dp = domains; dp; dp = dp->dom_next) {
110 		if (dp->dom_init)
111 			(*dp->dom_init)();
112 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
113 			if (pr->pr_init)
114 				(*pr->pr_init)();
115 	}
116 
117 	if (max_linkhdr < 16)		/* XXX */
118 		max_linkhdr = 16;
119 	max_hdr = max_linkhdr + max_protohdr;
120 	max_datalen = MHLEN - max_hdr;
121 	timeout_set(&pffast_timeout, pffasttimo, &pffast_timeout);
122 	timeout_set(&pfslow_timeout, pfslowtimo, &pfslow_timeout);
123 	timeout_add(&pffast_timeout, 1);
124 	timeout_add(&pfslow_timeout, 1);
125 }
126 
127 struct domain *
128 pffinddomain(int family)
129 {
130 	struct domain *dp;
131 
132 	for (dp = domains; dp != NULL; dp = dp->dom_next)
133 		if (dp->dom_family == family)
134 			return (dp);
135 	return (NULL);
136 }
137 
138 struct protosw *
139 pffindtype(int family, int type)
140 {
141 	struct domain *dp;
142 	struct protosw *pr;
143 
144 	dp = pffinddomain(family);
145 	if (dp == NULL)
146 		return (NULL);
147 
148 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
149 		if (pr->pr_type && pr->pr_type == type)
150 			return (pr);
151 	return (NULL);
152 }
153 
154 struct protosw *
155 pffindproto(int family, int protocol, int type)
156 {
157 	struct domain *dp;
158 	struct protosw *pr;
159 	struct protosw *maybe = NULL;
160 
161 	if (family == 0)
162 		return (NULL);
163 
164 	dp = pffinddomain(family);
165 	if (dp == NULL)
166 		return (NULL);
167 
168 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
169 		if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
170 			return (pr);
171 
172 		if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
173 		    pr->pr_protocol == 0 && maybe == NULL)
174 			maybe = pr;
175 	}
176 	return (maybe);
177 }
178 
179 int
180 net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
181     size_t newlen, struct proc *p)
182 {
183 	struct domain *dp;
184 	struct protosw *pr;
185 	int family, protocol;
186 
187 	/*
188 	 * All sysctl names at this level are nonterminal.
189 	 * Usually: next two components are protocol family and protocol
190 	 *	number, then at least one addition component.
191 	 */
192 	if (namelen < 2)
193 		return (EISDIR);		/* overloaded */
194 	family = name[0];
195 
196 	if (family == 0)
197 		return (0);
198 #if NBPFILTER > 0
199 	if (family == PF_BPF)
200 		return (bpf_sysctl(name + 1, namelen - 1, oldp, oldlenp,
201 		    newp, newlen));
202 #endif
203 #if NPFLOW > 0
204 	if (family == PF_PFLOW)
205 		return (pflow_sysctl(name + 1, namelen - 1, oldp, oldlenp,
206 		    newp, newlen));
207 #endif
208 #ifdef PIPEX
209 	if (family == PF_PIPEX)
210 		return (pipex_sysctl(name + 1, namelen - 1, oldp, oldlenp,
211 		    newp, newlen));
212 #endif
213 	dp = pffinddomain(family);
214 	if (dp == NULL)
215 		return (ENOPROTOOPT);
216 #ifdef MPLS
217 	/* XXX WARNING: big fat ugly hack */
218 	/* stupid net.mpls is special as it does not have a protocol */
219 	if (family == PF_MPLS)
220 		return (dp->dom_protosw[0].pr_sysctl(name + 1, namelen - 1,
221 		    oldp, oldlenp, newp, newlen));
222 #endif
223 
224 	if (namelen < 3)
225 		return (EISDIR);		/* overloaded */
226 	protocol = name[1];
227 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
228 		if (pr->pr_protocol == protocol && pr->pr_sysctl)
229 			return ((*pr->pr_sysctl)(name + 2, namelen - 2,
230 			    oldp, oldlenp, newp, newlen));
231 	return (ENOPROTOOPT);
232 }
233 
234 void
235 pfctlinput(int cmd, struct sockaddr *sa)
236 {
237 	struct domain *dp;
238 	struct protosw *pr;
239 
240 	for (dp = domains; dp; dp = dp->dom_next)
241 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
242 			if (pr->pr_ctlinput)
243 				(*pr->pr_ctlinput)(cmd, sa, 0, NULL);
244 }
245 
246 void
247 pfslowtimo(void *arg)
248 {
249 	struct timeout *to = (struct timeout *)arg;
250 	struct domain *dp;
251 	struct protosw *pr;
252 
253 	for (dp = domains; dp; dp = dp->dom_next)
254 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
255 			if (pr->pr_slowtimo)
256 				(*pr->pr_slowtimo)();
257 	timeout_add_msec(to, 500);
258 }
259 
260 void
261 pffasttimo(void *arg)
262 {
263 	struct timeout *to = (struct timeout *)arg;
264 	struct domain *dp;
265 	struct protosw *pr;
266 
267 	for (dp = domains; dp; dp = dp->dom_next)
268 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
269 			if (pr->pr_fasttimo)
270 				(*pr->pr_fasttimo)();
271 	timeout_add_msec(to, 200);
272 }
273