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