|
|
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.