|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */
23: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
24: /*
25: * Copyright (c) 1982, 1986, 1993
26: * The Regents of the University of California. All rights reserved.
27: *
28: * Redistribution and use in source and binary forms, with or without
29: * modification, are permitted provided that the following conditions
30: * are met:
31: * 1. Redistributions of source code must retain the above copyright
32: * notice, this list of conditions and the following disclaimer.
33: * 2. Redistributions in binary form must reproduce the above copyright
34: * notice, this list of conditions and the following disclaimer in the
35: * documentation and/or other materials provided with the distribution.
36: * 3. All advertising materials mentioning features or use of this software
37: * must display the following acknowledgement:
38: * This product includes software developed by the University of
39: * California, Berkeley and its contributors.
40: * 4. Neither the name of the University nor the names of its contributors
41: * may be used to endorse or promote products derived from this software
42: * without specific prior written permission.
43: *
44: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54: * SUCH DAMAGE.
55: *
56: * @(#)uipc_domain.c 8.3 (Berkeley) 2/14/95
57: */
58:
59: #include <sys/param.h>
60: #include <sys/socket.h>
61: #include <sys/protosw.h>
62: #include <sys/domain.h>
63: #include <sys/mbuf.h>
64: #include <sys/time.h>
65: #include <sys/kernel.h>
66: #include <sys/systm.h>
67: #include <sys/proc.h>
68: #include <sys/sysctl.h>
69: #include <sys/syslog.h>
70: #include <sys/queue.h>
71:
72: void pffasttimo __P((void *));
73: void pfslowtimo __P((void *));
74:
75: /*
76: * Add/delete 'domain': Link structure into system list,
77: * invoke the domain init, and then the proto inits.
78: * To delete, just remove from the list (dom_refs must be zero)
79: */
80:
81:
82: void init_domain(register struct domain *dp)
83: {
84: struct protosw *pr;
85:
86: if (dp->dom_init)
87: (*dp->dom_init)();
88:
89: /* and then init the currently installed protos in this domain */
90:
91: for (pr = dp->dom_protosw; pr; pr = pr->pr_next) {
92: if (pr->pr_usrreqs == 0)
93: panic("domaininit: %ssw[%d] has no usrreqs!",
94: dp->dom_name,
95: (int)(pr - dp->dom_protosw));
96:
97: if (pr->pr_init)
98: (*pr->pr_init)();
99: }
100:
101: /* Recompute for new protocol */
102: if (max_linkhdr < 16) /* XXX - Sheesh; everything's ether? */
103: max_linkhdr = 16;
104: if (dp->dom_protohdrlen > max_protohdr)
105: max_protohdr = dp->dom_protohdrlen;
106: max_hdr = max_linkhdr + max_protohdr;
107: max_datalen = MHLEN - max_hdr;
108: }
109:
110: void concat_domain(struct domain *dp)
111: {
112: dp->dom_next = domains;
113: domains = dp;
114: }
115:
116: void
117: net_add_domain(register struct domain *dp)
118: { register struct protosw *pr;
119: register int s;
120: extern int splhigh(void);
121: extern int splx(int);
122:
123: kprintf("Adding domain %s (family %d)\n", dp->dom_name,
124: dp->dom_family);
125: /* First, link in the domain */
126: s = splhigh();
127:
128: concat_domain(dp);
129:
130: init_domain(dp);
131:
132: splx(s);
133: }
134:
135: int
136: net_del_domain(register struct domain *dp)
137: { register struct domain *dp1, *dp2;
138: register int s, retval = 0;
139: extern int splhigh(void);
140: extern int splx(int);
141:
142: if (dp->dom_refs)
143: return(EBUSY);
144:
145: s = splhigh();
146:
147: for (dp2 = NULL, dp1 = domains; dp1; dp2 = dp1, dp1 = dp1->dom_next)
148: { if (dp == dp1)
149: break;
150: }
151: if (dp1)
152: { if (dp2)
153: dp2->dom_next = dp1->dom_next;
154: else
155: domains = dp1->dom_next;
156: } else
157: retval = EPFNOSUPPORT;
158: splx(s);
159:
160: return(retval);
161: }
162:
163: /*
164: * net_add_proto - link a protosw into a domain's protosw chain
165: */
166: int
167: net_add_proto(register struct protosw *pp,
168: register struct domain *dp)
169: { register struct protosw *pp1, *pp2;
170: register int s;
171: extern int splhigh(void);
172: extern int splx(int);
173:
174: s = splhigh();
175: for (pp2 = NULL, pp1 = dp->dom_protosw; pp1; pp1 = pp1->pr_next)
176: { if (pp1->pr_type == pp->pr_type &&
177: pp1->pr_protocol == pp->pr_protocol)
178: return(EEXIST);
179: pp2 = pp1;
180: }
181: if (pp2 == NULL)
182: dp->dom_protosw = pp;
183: else
184: pp2->pr_next = pp;
185: pp->pr_next = NULL;
186: TAILQ_INIT(&pp->pr_sfilter);
187: if (pp->pr_init)
188: (*pp->pr_init)();
189:
190: /* Make sure pr_init isn't called again!! */
191: pp->pr_init = 0;
192: splx(s);
193: return(0);
194: }
195:
196: /*
197: * net_del_proto - remove a protosw from a domain's protosw chain.
198: * Search the protosw chain for the element with matching data.
199: * Then unlink and return.
200: */
201: int
202: net_del_proto(register int type,
203: register int protocol,
204: register struct domain *dp)
205: { register struct protosw *pp1, *pp2;
206: int s;
207: extern int splhigh(void);
208: extern int splx(int);
209:
210: s = splhigh();
211: for (pp2 = NULL, pp1 = dp->dom_protosw; pp1; pp1 = pp1->pr_next)
212: { if (pp1->pr_type == type &&
213: pp1->pr_protocol == protocol)
214: break;
215: pp2 = pp1;
216: }
217: if (pp1 == NULL)
218: return(ENXIO);
219: if (pp2)
220: pp2->pr_next = pp1->pr_next;
221: else
222: dp->dom_protosw = pp1->pr_next;
223: splx(s);
224: return(0);
225: }
226:
227:
228: void
229: domaininit()
230: { register struct domain *dp;
231: register struct protosw *pr;
232: extern struct domain localdomain, routedomain, ndrvdomain, inetdomain;
233: #if NS
234: extern struct domain nsdomain;
235: #endif
236: #if ISO
237: extern struct domain isodomain;
238: #endif
239: #if CCITT
240: extern struct domain ccittdomain;
241: #endif
242:
243: #if NETAT
244: extern struct domain atalkdomain;
245: #endif
246:
247: /*
248: * Add all the static domains to the domains list
249: */
250:
251: concat_domain(&localdomain);
252: concat_domain(&routedomain);
253: concat_domain(&inetdomain);
254: #if NETAT
255: concat_domain(&atalkdomain);
256: #endif
257:
258: #if NS
259: concat_domain(&nsdomain);
260: #endif
261: #if ISO
262: concat_domain(&isodomain);
263: #endif
264: #if CCITT
265: concat_domain(&ccittdomain);
266: #endif
267: concat_domain(&ndrvdomain);
268:
269: /*
270: * Now ask them all to init (XXX including the routing domain,
271: * see above)
272: */
273: for (dp = domains; dp; dp = dp->dom_next)
274: init_domain(dp);
275:
276: timeout(pffasttimo, NULL, 1);
277: timeout(pfslowtimo, NULL, 1);
278: }
279:
280: struct protosw *
281: pffindtype(family, type)
282: int family, type;
283: {
284: register struct domain *dp;
285: register struct protosw *pr;
286:
287: for (dp = domains; dp; dp = dp->dom_next)
288: if (dp->dom_family == family)
289: goto found;
290: return (0);
291: found:
292: for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
293: if (pr->pr_type && pr->pr_type == type)
294: return (pr);
295: return (0);
296: }
297:
298: struct domain *
299: pffinddomain(int pf)
300: { struct domain *dp;
301:
302: dp = domains;
303: while (dp)
304: { if (dp->dom_family == pf)
305: return(dp);
306: dp = dp->dom_next;
307: }
308: return(NULL);
309: }
310:
311: struct protosw *
312: pffindproto(family, protocol, type)
313: int family, protocol, type;
314: {
315: register struct domain *dp;
316: register struct protosw *pr;
317: struct protosw *maybe = 0;
318:
319: if (family == 0)
320: return (0);
321: for (dp = domains; dp; dp = dp->dom_next)
322: if (dp->dom_family == family)
323: goto found;
324: return (0);
325: found:
326: for (pr = dp->dom_protosw; pr; pr = pr->pr_next) {
327: if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
328: return (pr);
329:
330: if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
331: pr->pr_protocol == 0 && maybe == (struct protosw *)0)
332: maybe = pr;
333: }
334: return (maybe);
335: }
336:
337: int
338: net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
339: int *name;
340: u_int namelen;
341: void *oldp;
342: size_t *oldlenp;
343: void *newp;
344: size_t newlen;
345: struct proc *p;
346: {
347: register struct domain *dp;
348: register struct protosw *pr;
349: int family, protocol;
350:
351: /*
352: * All sysctl names at this level are nonterminal;
353: * next two components are protocol family and protocol number,
354: * then at least one addition component.
355: */
356: if (namelen < 3)
357: return (EISDIR); /* overloaded */
358: family = name[0];
359: protocol = name[1];
360:
361: if (family == 0)
362: return (0);
363: for (dp = domains; dp; dp = dp->dom_next)
364: if (dp->dom_family == family)
365: goto found;
366: return (ENOPROTOOPT);
367: found:
368: for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
369: if (pr->pr_protocol == protocol && pr->pr_sysctl)
370: return ((*pr->pr_sysctl)(name + 2, namelen - 2,
371: oldp, oldlenp, newp, newlen));
372: return (ENOPROTOOPT);
373: }
374:
375: void
376: pfctlinput(cmd, sa)
377: int cmd;
378: struct sockaddr *sa;
379: {
380: register struct domain *dp;
381: register struct protosw *pr;
382:
383: for (dp = domains; dp; dp = dp->dom_next)
384: for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
385: if (pr->pr_ctlinput)
386: (*pr->pr_ctlinput)(cmd, sa, (caddr_t)0);
387: }
388:
389: void
390: pfslowtimo(arg)
391: void *arg;
392: {
393: register struct domain *dp;
394: register struct protosw *pr;
395:
396: for (dp = domains; dp; dp = dp->dom_next)
397: for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
398: if (pr->pr_slowtimo)
399: (*pr->pr_slowtimo)();
400: timeout(pfslowtimo, NULL, hz/2);
401: }
402:
403: void
404: pffasttimo(arg)
405: void *arg;
406: {
407: register struct domain *dp;
408: register struct protosw *pr;
409:
410: for (dp = domains; dp; dp = dp->dom_next)
411: for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
412: if (pr->pr_fasttimo)
413: (*pr->pr_fasttimo)();
414: timeout(pffasttimo, NULL, hz/5);
415: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.