1 /* $NetBSD: uipc_domain.c,v 1.17 1997/04/04 14:22:21 christos 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.2 (Berkeley) 10/18/93 36 */ 37 38 #include <sys/param.h> 39 #include <sys/socket.h> 40 #include <sys/protosw.h> 41 #include <sys/domain.h> 42 #include <sys/mbuf.h> 43 #include <sys/time.h> 44 #include <sys/kernel.h> 45 #include <sys/systm.h> 46 #include <sys/proc.h> 47 #include <vm/vm.h> 48 #include <sys/sysctl.h> 49 50 void pffasttimo __P((void *)); 51 void pfslowtimo __P((void *)); 52 53 #define ADDDOMAIN(x) { \ 54 extern struct domain __CONCAT(x,domain); \ 55 __CONCAT(x,domain.dom_next) = domains; \ 56 domains = &__CONCAT(x,domain); \ 57 } 58 59 void 60 domaininit() 61 { 62 register struct domain *dp; 63 register struct protosw *pr; 64 65 #undef unix 66 #ifndef lint 67 ADDDOMAIN(unix); 68 ADDDOMAIN(route); 69 #ifdef INET 70 ADDDOMAIN(inet); 71 #endif 72 #ifdef NS 73 ADDDOMAIN(ns); 74 #endif 75 #ifdef ISO 76 ADDDOMAIN(iso); 77 #endif 78 #ifdef CCITT 79 ADDDOMAIN(ccitt); 80 #endif 81 #ifdef NATM 82 ADDDOMAIN(natm); 83 #endif 84 #ifdef NETATALK 85 ADDDOMAIN(atalk); 86 #endif 87 #ifdef notdef /* XXXX */ 88 #include "imp.h" 89 #if NIMP > 0 90 ADDDOMAIN(imp); 91 #endif 92 #endif 93 #endif 94 95 for (dp = domains; dp; dp = dp->dom_next) { 96 if (dp->dom_init) 97 (*dp->dom_init)(); 98 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 99 if (pr->pr_init) 100 (*pr->pr_init)(); 101 } 102 103 if (max_linkhdr < 16) /* XXX */ 104 max_linkhdr = 16; 105 max_hdr = max_linkhdr + max_protohdr; 106 max_datalen = MHLEN - max_hdr; 107 timeout(pffasttimo, NULL, 1); 108 timeout(pfslowtimo, NULL, 1); 109 } 110 111 struct protosw * 112 pffindtype(family, type) 113 int family, type; 114 { 115 register struct domain *dp; 116 register struct protosw *pr; 117 118 for (dp = domains; dp; dp = dp->dom_next) 119 if (dp->dom_family == family) 120 goto found; 121 return (0); 122 found: 123 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 124 if (pr->pr_type && pr->pr_type == type) 125 return (pr); 126 return (0); 127 } 128 129 struct protosw * 130 pffindproto(family, protocol, type) 131 int family, protocol, type; 132 { 133 register struct domain *dp; 134 register struct protosw *pr; 135 struct protosw *maybe = 0; 136 137 if (family == 0) 138 return (0); 139 for (dp = domains; dp; dp = dp->dom_next) 140 if (dp->dom_family == family) 141 goto found; 142 return (0); 143 found: 144 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { 145 if ((pr->pr_protocol == protocol) && (pr->pr_type == type)) 146 return (pr); 147 148 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW && 149 pr->pr_protocol == 0 && maybe == (struct protosw *)0) 150 maybe = pr; 151 } 152 return (maybe); 153 } 154 155 int 156 net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 157 int *name; 158 u_int namelen; 159 void *oldp; 160 size_t *oldlenp; 161 void *newp; 162 size_t newlen; 163 struct proc *p; 164 { 165 register struct domain *dp; 166 register struct protosw *pr; 167 int family, protocol; 168 169 /* 170 * All sysctl names at this level are nonterminal; 171 * next two components are protocol family and protocol number, 172 * then at least one addition component. 173 */ 174 if (namelen < 3) 175 return (EISDIR); /* overloaded */ 176 family = name[0]; 177 protocol = name[1]; 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 (ENOPROTOOPT); 185 found: 186 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 187 if (pr->pr_protocol == protocol && pr->pr_sysctl) 188 return ((*pr->pr_sysctl)(name + 2, namelen - 2, 189 oldp, oldlenp, newp, newlen)); 190 return (ENOPROTOOPT); 191 } 192 193 void 194 pfctlinput(cmd, sa) 195 int cmd; 196 struct sockaddr *sa; 197 { 198 register struct domain *dp; 199 register struct protosw *pr; 200 201 for (dp = domains; dp; dp = dp->dom_next) 202 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 203 if (pr->pr_ctlinput) 204 (*pr->pr_ctlinput)(cmd, sa, NULL); 205 } 206 207 void 208 pfslowtimo(arg) 209 void *arg; 210 { 211 register struct domain *dp; 212 register struct protosw *pr; 213 214 for (dp = domains; dp; dp = dp->dom_next) 215 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 216 if (pr->pr_slowtimo) 217 (*pr->pr_slowtimo)(); 218 timeout(pfslowtimo, NULL, hz/2); 219 } 220 221 void 222 pffasttimo(arg) 223 void *arg; 224 { 225 register struct domain *dp; 226 register struct protosw *pr; 227 228 for (dp = domains; dp; dp = dp->dom_next) 229 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) 230 if (pr->pr_fasttimo) 231 (*pr->pr_fasttimo)(); 232 timeout(pffasttimo, NULL, hz/5); 233 } 234