uipc_domain.c revision 1.25 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