xref: /openbsd-src/sys/kern/uipc_domain.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: uipc_domain.c,v 1.11 2000/09/12 16:39:14 deraadt 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. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *	@(#)uipc_domain.c	8.2 (Berkeley) 10/18/93
37  */
38 
39 #include <sys/param.h>
40 #include <sys/socket.h>
41 #include <sys/protosw.h>
42 #include <sys/domain.h>
43 #include <sys/mbuf.h>
44 #include <sys/time.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
47 #include <sys/proc.h>
48 #include <vm/vm.h>
49 #include <sys/sysctl.h>
50 #include <sys/timeout.h>
51 
52 void	pffasttimo __P((void *));
53 void	pfslowtimo __P((void *));
54 #if defined (KEY) || defined (IPSEC)
55 int pfkey_init __P((void));
56 #endif /* KEY || IPSEC */
57 
58 #define	ADDDOMAIN(x)	{ \
59 	extern struct domain __CONCAT(x,domain); \
60 	__CONCAT(x,domain.dom_next) = domains; \
61 	domains = &__CONCAT(x,domain); \
62 }
63 
64 void
65 domaininit()
66 {
67 	struct domain *dp;
68 	struct protosw *pr;
69 	static struct timeout pffast_timeout;
70 	static struct timeout pfslow_timeout;
71 
72 #undef unix
73 	/*
74 	 * KAME NOTE: ADDDOMAIN(route) is moved to the last part so that
75 	 * it will be initialized as the *first* element.  confusing!
76 	 */
77 #ifndef lint
78 	ADDDOMAIN(unix);
79 #ifdef INET
80 	ADDDOMAIN(inet);
81 #endif
82 #ifdef INET6
83 	ADDDOMAIN(inet6);
84 #endif /* INET6 */
85 #if defined (KEY) || defined (IPSEC)
86 	pfkey_init();
87 #endif /* KEY || IPSEC */
88 #ifdef IPX
89 	ADDDOMAIN(ipx);
90 #endif
91 #ifdef NETATALK
92 	ADDDOMAIN(atalk);
93 #endif
94 #ifdef NS
95 	ADDDOMAIN(ns);
96 #endif
97 #ifdef ISO
98 	ADDDOMAIN(iso);
99 #endif
100 #ifdef CCITT
101 	ADDDOMAIN(ccitt);
102 #endif
103 #ifdef NATM
104 	ADDDOMAIN(natm);
105 #endif
106 #ifdef notdef /* XXXX */
107 #include "imp.h"
108 #if NIMP > 0
109 	ADDDOMAIN(imp);
110 #endif
111 #endif
112 #ifdef IPSEC
113 #ifdef __KAME__
114 	ADDDOMAIN(key);
115 #endif
116 #endif
117 	ADDDOMAIN(route);
118 #endif
119 
120 	for (dp = domains; dp; dp = dp->dom_next) {
121 		if (dp->dom_init)
122 			(*dp->dom_init)();
123 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
124 			if (pr->pr_init)
125 				(*pr->pr_init)();
126 	}
127 
128 if (max_linkhdr < 16)		/* XXX */
129 max_linkhdr = 16;
130 	max_hdr = max_linkhdr + max_protohdr;
131 	max_datalen = MHLEN - max_hdr;
132 	timeout_set(&pffast_timeout, pffasttimo, &pffast_timeout);
133 	timeout_set(&pfslow_timeout, pfslowtimo, &pfslow_timeout);
134 	timeout_add(&pffast_timeout, 1);
135 	timeout_add(&pfslow_timeout, 1);
136 }
137 
138 struct protosw *
139 pffindtype(family, type)
140 	int family, type;
141 {
142 	register struct domain *dp;
143 	register struct protosw *pr;
144 
145 	for (dp = domains; dp; dp = dp->dom_next)
146 		if (dp->dom_family == family)
147 			goto found;
148 	return (0);
149 found:
150 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
151 		if (pr->pr_type && pr->pr_type == type)
152 			return (pr);
153 	return (0);
154 }
155 
156 struct protosw *
157 pffindproto(family, protocol, type)
158 	int family, protocol, type;
159 {
160 	register struct domain *dp;
161 	register struct protosw *pr;
162 	struct protosw *maybe = 0;
163 
164 	if (family == 0)
165 		return (0);
166 	for (dp = domains; dp; dp = dp->dom_next)
167 		if (dp->dom_family == family)
168 			goto found;
169 	return (0);
170 found:
171 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
172 		if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
173 			return (pr);
174 
175 		if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
176 		    pr->pr_protocol == 0 && maybe == (struct protosw *)0)
177 			maybe = pr;
178 	}
179 	return (maybe);
180 }
181 
182 int
183 net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
184 	int *name;
185 	u_int namelen;
186 	void *oldp;
187 	size_t *oldlenp;
188 	void *newp;
189 	size_t newlen;
190 	struct proc *p;
191 {
192 	register struct domain *dp;
193 	register struct protosw *pr;
194 	int family, protocol;
195 
196 	/*
197 	 * All sysctl names at this level are nonterminal.
198 	 * PF_KEY: next component is protocol family, and then at least one
199 	 *	additional component.
200 	 * usually: next two components are protocol family and protocol
201 	 *	number, then at least one addition component.
202 	 */
203 	if (namelen < 2)
204 		return (EISDIR);		/* overloaded */
205 	family = name[0];
206 
207 	if (family == 0)
208 		return (0);
209 	for (dp = domains; dp; dp = dp->dom_next)
210 		if (dp->dom_family == family)
211 			goto found;
212 	return (ENOPROTOOPT);
213 found:
214 	switch (family) {
215 #ifdef IPSEC
216 #ifdef __KAME__
217 	case PF_KEY:
218 		pr = dp->dom_protosw;
219 		if (pr->pr_sysctl)
220 			return ((*pr->pr_sysctl)(name + 1, namelen - 1,
221 				oldp, oldlenp, newp, newlen));
222 		return (ENOPROTOOPT);
223 #endif
224 #endif
225 	default:
226 		break;
227 	}
228 	if (namelen < 3)
229 		return (EISDIR);		/* overloaded */
230 	protocol = name[1];
231 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
232 		if (pr->pr_protocol == protocol && pr->pr_sysctl)
233 			return ((*pr->pr_sysctl)(name + 2, namelen - 2,
234 			    oldp, oldlenp, newp, newlen));
235 	return (ENOPROTOOPT);
236 }
237 
238 void
239 pfctlinput(cmd, sa)
240 	int cmd;
241 	struct sockaddr *sa;
242 {
243 	register struct domain *dp;
244 	register struct protosw *pr;
245 
246 	for (dp = domains; dp; dp = dp->dom_next)
247 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
248 			if (pr->pr_ctlinput)
249 				(*pr->pr_ctlinput)(cmd, sa, NULL);
250 }
251 
252 void
253 pfslowtimo(arg)
254 	void *arg;
255 {
256 	struct timeout *to = (struct timeout *)arg;
257 	struct domain *dp;
258 	struct protosw *pr;
259 
260 	for (dp = domains; dp; dp = dp->dom_next)
261 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
262 			if (pr->pr_slowtimo)
263 				(*pr->pr_slowtimo)();
264 	timeout_add(to, hz/2);
265 }
266 
267 void
268 pffasttimo(arg)
269 	void *arg;
270 {
271 	struct timeout *to = (struct timeout *)arg;
272 	struct domain *dp;
273 	struct protosw *pr;
274 
275 	for (dp = domains; dp; dp = dp->dom_next)
276 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
277 			if (pr->pr_fasttimo)
278 				(*pr->pr_fasttimo)();
279 	timeout_add(to, hz/5);
280 }
281