xref: /netbsd-src/sys/kern/uipc_domain.c (revision bada23909e740596d0a3785a73bd3583a9807fb8)
1 /*	$NetBSD: uipc_domain.c,v 1.25 1999/01/14 01:14:01 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1986, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)uipc_domain.c	8.3 (Berkeley) 2/14/95
36  */
37 
38 #include "opt_inet.h"
39 #include "opt_atalk.h"
40 #include "opt_ccitt.h"
41 #include "opt_iso.h"
42 #include "opt_ns.h"
43 #include "opt_natm.h"
44 
45 #include <sys/param.h>
46 #include <sys/socket.h>
47 #include <sys/protosw.h>
48 #include <sys/domain.h>
49 #include <sys/mbuf.h>
50 #include <sys/time.h>
51 #include <sys/kernel.h>
52 #include <sys/systm.h>
53 #include <sys/proc.h>
54 #include <vm/vm.h>
55 #include <sys/sysctl.h>
56 
57 void	pffasttimo __P((void *));
58 void	pfslowtimo __P((void *));
59 
60 /*
61  * Current time values for fast and slow timeouts.  We can use u_int
62  * relatively safely.  The fast timer will roll over in 27 years and
63  * the slow timer in 68 years.
64  */
65 u_int	pfslowtimo_now;
66 u_int	pffasttimo_now;
67 
68 #define	ADDDOMAIN(x)	{ \
69 	extern struct domain __CONCAT(x,domain); \
70 	__CONCAT(x,domain.dom_next) = domains; \
71 	domains = &__CONCAT(x,domain); \
72 }
73 
74 void
75 domaininit()
76 {
77 	register struct domain *dp;
78 	register struct protosw *pr;
79 
80 #undef unix
81 #ifndef lint
82 	ADDDOMAIN(unix);
83 	ADDDOMAIN(route);
84 #ifdef INET
85 	ADDDOMAIN(inet);
86 #endif
87 #ifdef NS
88 	ADDDOMAIN(ns);
89 #endif
90 #ifdef ISO
91 	ADDDOMAIN(iso);
92 #endif
93 #ifdef CCITT
94 	ADDDOMAIN(ccitt);
95 #endif
96 #ifdef NATM
97 	ADDDOMAIN(natm);
98 #endif
99 #ifdef NETATALK
100 	ADDDOMAIN(atalk);
101 #endif
102 #endif /* ! lint */
103 
104 	for (dp = domains; dp; dp = dp->dom_next) {
105 		if (dp->dom_init)
106 			(*dp->dom_init)();
107 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
108 			if (pr->pr_init)
109 				(*pr->pr_init)();
110 	}
111 
112 	if (max_linkhdr < 16)		/* XXX */
113 		max_linkhdr = 16;
114 	max_hdr = max_linkhdr + max_protohdr;
115 	max_datalen = MHLEN - max_hdr;
116 	timeout(pffasttimo, NULL, 1);
117 	timeout(pfslowtimo, NULL, 1);
118 }
119 
120 struct protosw *
121 pffindtype(family, type)
122 	int family, type;
123 {
124 	register struct domain *dp;
125 	register struct protosw *pr;
126 
127 	for (dp = domains; dp; dp = dp->dom_next)
128 		if (dp->dom_family == family)
129 			goto found;
130 	return (0);
131 found:
132 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
133 		if (pr->pr_type && pr->pr_type == type)
134 			return (pr);
135 	return (0);
136 }
137 
138 struct protosw *
139 pffindproto(family, protocol, type)
140 	int family, protocol, type;
141 {
142 	register struct domain *dp;
143 	register struct protosw *pr;
144 	struct protosw *maybe = 0;
145 
146 	if (family == 0)
147 		return (0);
148 	for (dp = domains; dp; dp = dp->dom_next)
149 		if (dp->dom_family == family)
150 			goto found;
151 	return (0);
152 found:
153 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
154 		if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
155 			return (pr);
156 
157 		if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
158 		    pr->pr_protocol == 0 && maybe == (struct protosw *)0)
159 			maybe = pr;
160 	}
161 	return (maybe);
162 }
163 
164 int
165 net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
166 	int *name;
167 	u_int namelen;
168 	void *oldp;
169 	size_t *oldlenp;
170 	void *newp;
171 	size_t newlen;
172 	struct proc *p;
173 {
174 	register struct domain *dp;
175 	register struct protosw *pr;
176 	int family, protocol;
177 
178 	/*
179 	 * All sysctl names at this level are nonterminal;
180 	 * next two components are protocol family and protocol number,
181 	 * then at least one addition component.
182 	 */
183 	if (namelen < 3)
184 		return (EISDIR);		/* overloaded */
185 	family = name[0];
186 	protocol = name[1];
187 
188 	if (family == 0)
189 		return (0);
190 	for (dp = domains; dp; dp = dp->dom_next)
191 		if (dp->dom_family == family)
192 			goto found;
193 	return (ENOPROTOOPT);
194 found:
195 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
196 		if (pr->pr_protocol == protocol && pr->pr_sysctl)
197 			return ((*pr->pr_sysctl)(name + 2, namelen - 2,
198 			    oldp, oldlenp, newp, newlen));
199 	return (ENOPROTOOPT);
200 }
201 
202 void
203 pfctlinput(cmd, sa)
204 	int cmd;
205 	struct sockaddr *sa;
206 {
207 	register struct domain *dp;
208 	register struct protosw *pr;
209 
210 	for (dp = domains; dp; dp = dp->dom_next)
211 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
212 			if (pr->pr_ctlinput)
213 				(*pr->pr_ctlinput)(cmd, sa, NULL);
214 }
215 
216 void
217 pfslowtimo(arg)
218 	void *arg;
219 {
220 	register struct domain *dp;
221 	register struct protosw *pr;
222 
223 	pfslowtimo_now++;
224 
225 	for (dp = domains; dp; dp = dp->dom_next)
226 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
227 			if (pr->pr_slowtimo)
228 				(*pr->pr_slowtimo)();
229 	timeout(pfslowtimo, NULL, hz/2);
230 }
231 
232 void
233 pffasttimo(arg)
234 	void *arg;
235 {
236 	register struct domain *dp;
237 	register struct protosw *pr;
238 
239 	pffasttimo_now++;
240 
241 	for (dp = domains; dp; dp = dp->dom_next)
242 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
243 			if (pr->pr_fasttimo)
244 				(*pr->pr_fasttimo)();
245 	timeout(pffasttimo, NULL, hz/5);
246 }
247