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