1 /* 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93 34 * $Id: uipc_domain.c,v 1.7 1995/08/16 16:13:21 bde Exp $ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 #include <sys/protosw.h> 40 #include <sys/domain.h> 41 #include <sys/mbuf.h> 42 #include <sys/time.h> 43 #include <sys/kernel.h> 44 #include <sys/systm.h> 45 #include <sys/proc.h> 46 #include <vm/vm.h> 47 #include <sys/sysctl.h> 48 49 /* 50 * System initialization 51 * 52 * Note: domain initialization wants to take place on a per domain basis 53 * as a result of traversing a linker set. Most likely, each domain 54 * want to call a registration function rather than being handled here 55 * in domaininit(). Probably this will look like: 56 * 57 * SYSINIT(unique, SI_SUB_PROTO_DOMAI, SI_ORDER_ANY, domain_add, (caddr_t)xxx) 58 * 59 * Where 'xxx' is replaced by the address of a parameter struct to be 60 * passed to the doamin_add() function. 61 */ 62 63 static int x_save_spl; /* used by kludge*/ 64 static void kludge_splimp __P((caddr_t)); 65 static void kludge_splx __P((caddr_t)); 66 static void domaininit __P((caddr_t)); 67 SYSINIT(splimp, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, kludge_splimp, (caddr_t)&x_save_spl) 68 SYSINIT(domain, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, domaininit, NULL) 69 SYSINIT(splx, SI_SUB_PROTO_END, SI_ORDER_FIRST, kludge_splx, (caddr_t)&x_save_spl) 70 71 72 void pffasttimo __P((void *)); 73 void pfslowtimo __P((void *)); 74 75 struct domain *domains; 76 77 #define ADDDOMAIN(x) { \ 78 __CONCAT(x,domain.dom_next) = domains; \ 79 domains = &__CONCAT(x,domain); \ 80 } 81 82 extern struct linker_set domain_set; 83 84 /* ARGSUSED*/ 85 static void 86 domaininit( udata) 87 caddr_t udata; /* not used*/ 88 { 89 register struct domain *dp, **dpp; 90 register struct protosw *pr; 91 92 /* 93 * NB - local domain is always present. 94 */ 95 ADDDOMAIN(local); 96 97 for (dpp = (struct domain **)domain_set.ls_items; *dpp; dpp++) { 98 (**dpp).dom_next = domains; 99 domains = *dpp; 100 } 101 102 /* - not in our sources 103 #ifdef ISDN 104 ADDDOMAIN(isdn); 105 #endif 106 */ 107 108 for (dp = domains; dp; dp = dp->dom_next) { 109 if (dp->dom_init) 110 (*dp->dom_init)(); 111 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 112 if (pr->pr_init) 113 (*pr->pr_init)(); 114 } 115 116 if (max_linkhdr < 16) /* XXX */ 117 max_linkhdr = 16; 118 max_hdr = max_linkhdr + max_protohdr; 119 max_datalen = MHLEN - max_hdr; 120 timeout(pffasttimo, (void *)0, 1); 121 timeout(pfslowtimo, (void *)0, 1); 122 } 123 124 125 /* 126 * The following two operations are kludge code. Most likely, they should 127 * be done as a "domainpreinit()" for the first function and then rolled 128 * in as the last act of "domaininit()" for the second. 129 * 130 * In point of fact, it is questionable why other initialization prior 131 * to this does not also take place at splimp by default. 132 */ 133 static void 134 kludge_splimp( udata) 135 caddr_t udata; 136 { 137 int *savesplp = (int *)udata; 138 139 *savesplp = splimp(); 140 } 141 142 static void 143 kludge_splx( udata) 144 caddr_t udata; 145 { 146 int *savesplp = (int *)udata; 147 148 splx( *savesplp); 149 } 150 151 152 153 struct protosw * 154 pffindtype(family, type) 155 int family, type; 156 { 157 register struct domain *dp; 158 register struct protosw *pr; 159 160 for (dp = domains; dp; dp = dp->dom_next) 161 if (dp->dom_family == family) 162 goto found; 163 return (0); 164 found: 165 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 166 if (pr->pr_type && pr->pr_type == type) 167 return (pr); 168 return (0); 169 } 170 171 struct protosw * 172 pffindproto(family, protocol, type) 173 int family, protocol, type; 174 { 175 register struct domain *dp; 176 register struct protosw *pr; 177 struct protosw *maybe = 0; 178 179 if (family == 0) 180 return (0); 181 for (dp = domains; dp; dp = dp->dom_next) 182 if (dp->dom_family == family) 183 goto found; 184 return (0); 185 found: 186 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { 187 if ((pr->pr_protocol == protocol) && (pr->pr_type == type)) 188 return (pr); 189 190 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW && 191 pr->pr_protocol == 0 && maybe == (struct protosw *)0) 192 maybe = pr; 193 } 194 return (maybe); 195 } 196 197 int 198 net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 199 int *name; 200 u_int namelen; 201 void *oldp; 202 size_t *oldlenp; 203 void *newp; 204 size_t newlen; 205 struct proc *p; 206 { 207 register struct domain *dp; 208 register struct protosw *pr; 209 int family, protocol; 210 211 /* 212 * All sysctl names at this level are nonterminal; 213 * next two components are protocol family and protocol number, 214 * then at least one addition component. 215 */ 216 if (namelen < 3) 217 return (EISDIR); /* overloaded */ 218 family = name[0]; 219 protocol = name[1]; 220 221 if (family == 0) 222 return (0); 223 for (dp = domains; dp; dp = dp->dom_next) 224 if (dp->dom_family == family) 225 goto found; 226 return (ENOPROTOOPT); 227 found: 228 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 229 if (pr->pr_protocol == protocol && pr->pr_sysctl) 230 return ((*pr->pr_sysctl)(name + 2, namelen - 2, 231 oldp, oldlenp, newp, newlen)); 232 return (ENOPROTOOPT); 233 } 234 235 void 236 pfctlinput(cmd, sa) 237 int cmd; 238 struct sockaddr *sa; 239 { 240 register struct domain *dp; 241 register struct protosw *pr; 242 243 for (dp = domains; dp; dp = dp->dom_next) 244 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 245 if (pr->pr_ctlinput) 246 (*pr->pr_ctlinput)(cmd, sa, (caddr_t)0); 247 } 248 249 void 250 pfslowtimo(arg) 251 void *arg; 252 { 253 register struct domain *dp; 254 register struct protosw *pr; 255 256 for (dp = domains; dp; dp = dp->dom_next) 257 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 258 if (pr->pr_slowtimo) 259 (*pr->pr_slowtimo)(); 260 timeout(pfslowtimo, (void *)0, hz/2); 261 } 262 263 void 264 pffasttimo(arg) 265 void *arg; 266 { 267 register struct domain *dp; 268 register struct protosw *pr; 269 270 for (dp = domains; dp; dp = dp->dom_next) 271 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 272 if (pr->pr_fasttimo) 273 (*pr->pr_fasttimo)(); 274 timeout(pffasttimo, (void *)0, hz/5); 275 } 276