1 /* $OpenBSD: uipc_domain.c,v 1.60 2022/08/14 01:58:28 jsg 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/systm.h>
41 #include <sys/sysctl.h>
42 #include <sys/timeout.h>
43
44 #include "bpfilter.h"
45 #include "pflow.h"
46
47 const struct domain *const domains[] = {
48 #ifdef MPLS
49 &mplsdomain,
50 #endif
51 #if defined (IPSEC) || defined (TCP_SIGNATURE)
52 &pfkeydomain,
53 #endif
54 #ifdef INET6
55 &inet6domain,
56 #endif /* INET6 */
57 &inetdomain,
58 &unixdomain,
59 &routedomain,
60 NULL
61 };
62
63 void pffasttimo(void *);
64 void pfslowtimo(void *);
65 const struct domain * pffinddomain(int);
66
67 void
68 domaininit(void)
69 {
70 const struct domain *dp;
71 const struct protosw *pr;
72 static struct timeout pffast_timeout;
73 static struct timeout pfslow_timeout;
74 int i;
75
76 for (i = 0; (dp = domains[i]) != NULL; i++) {
77 if (dp->dom_init)
78 (*dp->dom_init)();
79 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
80 if (pr->pr_init)
81 (*pr->pr_init)();
82 }
83
84 /*
85 * max_linkhdr of 64 was chosen to encompass tunnelling
86 * traffic in IP payloads, eg, by etherip(4) or gif(4),
87 * without needing to prepend an mbuf to fit those
88 * headers.
89 */
90 if (max_linkhdr < 64)
91 max_linkhdr = 64;
92
93 max_hdr = max_linkhdr + max_protohdr;
94 timeout_set_proc(&pffast_timeout, pffasttimo, &pffast_timeout);
95 timeout_set_proc(&pfslow_timeout, pfslowtimo, &pfslow_timeout);
96 timeout_add(&pffast_timeout, 1);
97 timeout_add(&pfslow_timeout, 1);
98 }
99
100 const struct domain *
101 pffinddomain(int family)
102 {
103 const struct domain *dp;
104 int i;
105
106 for (i = 0; (dp = domains[i]) != NULL; i++) {
107 if (dp->dom_family == family)
108 return (dp);
109 }
110 return (NULL);
111 }
112
113 const struct protosw *
114 pffindtype(int family, int type)
115 {
116 const struct domain *dp;
117 const struct protosw *pr;
118
119 dp = pffinddomain(family);
120 if (dp == NULL)
121 return (NULL);
122
123 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
124 if (pr->pr_type && pr->pr_type == type)
125 return (pr);
126 return (NULL);
127 }
128
129 const struct protosw *
130 pffindproto(int family, int protocol, int type)
131 {
132 const struct domain *dp;
133 const struct protosw *pr;
134 const struct protosw *maybe = NULL;
135
136 if (family == PF_UNSPEC)
137 return (NULL);
138
139 dp = pffinddomain(family);
140 if (dp == NULL)
141 return (NULL);
142
143 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
144 if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
145 return (pr);
146
147 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
148 pr->pr_protocol == 0 && maybe == NULL)
149 maybe = pr;
150 }
151 return (maybe);
152 }
153
154 static int
155 net_link_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
156 void *newp, size_t newlen)
157 {
158 int node;
159 int error;
160
161 /*
162 * All sysctl names at this level are nonterminal.
163 */
164 if (namelen < 2)
165 return (EISDIR); /* overloaded */
166 node = name[0];
167
168 namelen--;
169 name++;
170
171 switch (node) {
172 case NET_LINK_IFRXQ:
173 error = net_ifiq_sysctl(name, namelen, oldp, oldlenp,
174 newp, newlen);
175 break;
176
177 default:
178 error = ENOPROTOOPT;
179 break;
180 }
181
182 return (error);
183 }
184
185 int
186 net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
187 size_t newlen, struct proc *p)
188 {
189 const struct domain *dp;
190 const struct protosw *pr;
191 int error, family, protocol;
192
193 /*
194 * All sysctl names at this level are nonterminal.
195 * Usually: next two components are protocol family and protocol
196 * number, then at least one addition component.
197 */
198 if (namelen < 2)
199 return (EISDIR); /* overloaded */
200 family = name[0];
201
202 if (family == PF_UNSPEC)
203 return (0);
204 if (family == PF_LINK)
205 return (net_link_sysctl(name + 1, namelen - 1, oldp, oldlenp,
206 newp, newlen));
207 if (family == PF_UNIX)
208 return (uipc_sysctl(name + 1, namelen - 1, oldp, oldlenp,
209 newp, newlen));
210 #if NBPFILTER > 0
211 if (family == PF_BPF)
212 return (bpf_sysctl(name + 1, namelen - 1, oldp, oldlenp,
213 newp, newlen));
214 #endif
215 #if NPFLOW > 0
216 if (family == PF_PFLOW)
217 return (pflow_sysctl(name + 1, namelen - 1, oldp, oldlenp,
218 newp, newlen));
219 #endif
220 #ifdef PIPEX
221 if (family == PF_PIPEX)
222 return (pipex_sysctl(name + 1, namelen - 1, oldp, oldlenp,
223 newp, newlen));
224 #endif
225 #ifdef MPLS
226 if (family == PF_MPLS)
227 return (mpls_sysctl(name + 1, namelen - 1, oldp, oldlenp,
228 newp, newlen));
229 #endif
230 dp = pffinddomain(family);
231 if (dp == NULL)
232 return (ENOPROTOOPT);
233
234 if (namelen < 3)
235 return (EISDIR); /* overloaded */
236 protocol = name[1];
237 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
238 if (pr->pr_protocol == protocol && pr->pr_sysctl) {
239 error = (*pr->pr_sysctl)(name + 2, namelen - 2,
240 oldp, oldlenp, newp, newlen);
241 return (error);
242 }
243 return (ENOPROTOOPT);
244 }
245
246 void
247 pfctlinput(int cmd, struct sockaddr *sa)
248 {
249 const struct domain *dp;
250 const struct protosw *pr;
251 int i;
252
253 NET_ASSERT_LOCKED();
254
255 for (i = 0; (dp = domains[i]) != NULL; i++) {
256 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
257 if (pr->pr_ctlinput)
258 (*pr->pr_ctlinput)(cmd, sa, 0, NULL);
259 }
260 }
261
262 void
263 pfslowtimo(void *arg)
264 {
265 struct timeout *to = (struct timeout *)arg;
266 const struct domain *dp;
267 const struct protosw *pr;
268 int i;
269
270 for (i = 0; (dp = domains[i]) != NULL; i++) {
271 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
272 if (pr->pr_slowtimo)
273 (*pr->pr_slowtimo)();
274 }
275 timeout_add_msec(to, 500);
276 }
277
278 void
279 pffasttimo(void *arg)
280 {
281 struct timeout *to = (struct timeout *)arg;
282 const struct domain *dp;
283 const struct protosw *pr;
284 int i;
285
286 for (i = 0; (dp = domains[i]) != NULL; i++) {
287 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
288 if (pr->pr_fasttimo)
289 (*pr->pr_fasttimo)();
290 }
291 timeout_add_msec(to, 200);
292 }
Cache object: d8d6dc53099c19295b38917053dfeb3d
|