uipc_domain.c revision 1.27 1 /* $NetBSD: uipc_domain.c,v 1.27 1999/07/09 22:57:16 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_ipsec.h"
40 #include "opt_atalk.h"
41 #include "opt_ccitt.h"
42 #include "opt_iso.h"
43 #include "opt_ns.h"
44 #include "opt_natm.h"
45
46 #include <sys/param.h>
47 #include <sys/socket.h>
48 #include <sys/protosw.h>
49 #include <sys/domain.h>
50 #include <sys/mbuf.h>
51 #include <sys/time.h>
52 #include <sys/kernel.h>
53 #include <sys/systm.h>
54 #include <sys/proc.h>
55 #include <vm/vm.h>
56 #include <sys/sysctl.h>
57
58 void pffasttimo __P((void *));
59 void pfslowtimo __P((void *));
60
61 /*
62 * Current time values for fast and slow timeouts. We can use u_int
63 * relatively safely. The fast timer will roll over in 27 years and
64 * the slow timer in 68 years.
65 */
66 u_int pfslowtimo_now;
67 u_int pffasttimo_now;
68
69 #define ADDDOMAIN(x) { \
70 extern struct domain __CONCAT(x,domain); \
71 __CONCAT(x,domain.dom_next) = domains; \
72 domains = &__CONCAT(x,domain); \
73 }
74
75 void
76 domaininit()
77 {
78 register struct domain *dp;
79 register struct protosw *pr;
80
81 #undef unix
82 /*
83 * KAME NOTE: ADDDOMAIN(route) is moved to the last part so that
84 * it will be initialized as the *first* element. confusing!
85 */
86 #ifndef lint
87 ADDDOMAIN(unix);
88 #ifdef INET
89 ADDDOMAIN(inet);
90 #endif
91 #ifdef INET6
92 ADDDOMAIN(inet6);
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 NETATALK
107 ADDDOMAIN(atalk);
108 #endif
109 #ifdef IPSEC
110 ADDDOMAIN(key);
111 #endif
112 ADDDOMAIN(route);
113 #endif /* ! lint */
114
115 for (dp = domains; dp; dp = dp->dom_next) {
116 if (dp->dom_init)
117 (*dp->dom_init)();
118 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
119 if (pr->pr_init)
120 (*pr->pr_init)();
121 }
122
123 if (max_linkhdr < 16) /* XXX */
124 max_linkhdr = 16;
125 max_hdr = max_linkhdr + max_protohdr;
126 max_datalen = MHLEN - max_hdr;
127 timeout(pffasttimo, NULL, 1);
128 timeout(pfslowtimo, NULL, 1);
129 }
130
131 struct protosw *
132 pffindtype(family, type)
133 int family, type;
134 {
135 register struct domain *dp;
136 register struct protosw *pr;
137
138 for (dp = domains; dp; dp = dp->dom_next)
139 if (dp->dom_family == family)
140 goto found;
141 return (0);
142 found:
143 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
144 if (pr->pr_type && pr->pr_type == type)
145 return (pr);
146 return (0);
147 }
148
149 struct protosw *
150 pffindproto(family, protocol, type)
151 int family, protocol, type;
152 {
153 register struct domain *dp;
154 register struct protosw *pr;
155 struct protosw *maybe = 0;
156
157 if (family == 0)
158 return (0);
159 for (dp = domains; dp; dp = dp->dom_next)
160 if (dp->dom_family == family)
161 goto found;
162 return (0);
163 found:
164 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
165 if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
166 return (pr);
167
168 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
169 pr->pr_protocol == 0 && maybe == (struct protosw *)0)
170 maybe = pr;
171 }
172 return (maybe);
173 }
174
175 int
176 net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
177 int *name;
178 u_int namelen;
179 void *oldp;
180 size_t *oldlenp;
181 void *newp;
182 size_t newlen;
183 struct proc *p;
184 {
185 register struct domain *dp;
186 register struct protosw *pr;
187 int family, protocol;
188
189 /*
190 * All sysctl names at this level are nonterminal.
191 * PF_KEY: next component is protocol family, and then at least one
192 * additional component.
193 * usually: next two components are protocol family and protocol
194 * number, then at least one addition component.
195 */
196 if (namelen < 2)
197 return (EISDIR); /* overloaded */
198 family = name[0];
199
200 if (family == 0)
201 return (0);
202 for (dp = domains; dp; dp = dp->dom_next)
203 if (dp->dom_family == family)
204 goto found;
205 return (ENOPROTOOPT);
206 found:
207 switch (family) {
208 #ifdef IPSEC
209 case PF_KEY:
210 pr = dp->dom_protosw;
211 if (pr->pr_sysctl)
212 return ((*pr->pr_sysctl)(name + 1, namelen - 1,
213 oldp, oldlenp, newp, newlen));
214 return (ENOPROTOOPT);
215 #endif
216 default:
217 break;
218 }
219 if (namelen < 3)
220 return (EISDIR); /* overloaded */
221 protocol = name[1];
222 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
223 if (pr->pr_protocol == protocol && pr->pr_sysctl)
224 return ((*pr->pr_sysctl)(name + 2, namelen - 2,
225 oldp, oldlenp, newp, newlen));
226 return (ENOPROTOOPT);
227 }
228
229 void
230 pfctlinput(cmd, sa)
231 int cmd;
232 struct sockaddr *sa;
233 {
234 register struct domain *dp;
235 register struct protosw *pr;
236
237 for (dp = domains; dp; dp = dp->dom_next)
238 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
239 if (pr->pr_ctlinput)
240 (*pr->pr_ctlinput)(cmd, sa, NULL);
241 }
242
243 void
244 pfslowtimo(arg)
245 void *arg;
246 {
247 register struct domain *dp;
248 register struct protosw *pr;
249
250 pfslowtimo_now++;
251
252 for (dp = domains; dp; dp = dp->dom_next)
253 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
254 if (pr->pr_slowtimo)
255 (*pr->pr_slowtimo)();
256 timeout(pfslowtimo, NULL, hz/2);
257 }
258
259 void
260 pffasttimo(arg)
261 void *arg;
262 {
263 register struct domain *dp;
264 register struct protosw *pr;
265
266 pffasttimo_now++;
267
268 for (dp = domains; dp; dp = dp->dom_next)
269 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
270 if (pr->pr_fasttimo)
271 (*pr->pr_fasttimo)();
272 timeout(pffasttimo, NULL, hz/5);
273 }
274