1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #include <sys/stream.h> 28 #include <sys/ddi.h> 29 #include <sys/sunddi.h> 30 #include <sys/priv_names.h> 31 32 /* 33 * This file contains generic goo needed to hook the STREAMS modules and 34 * drivers that live under uts/common/inet into the DDI. In order to use it, 35 * each module/driver should #define the symbols below (as appropriate) and 36 * then #include this source file; see the other uts/common/inet/<star>ddi.c 37 * files for examples of this in action. 38 * 39 * The symbols that all modules and drivers must define are: 40 * 41 * INET_NAME The name of the module/driver. 42 * 43 * The symbols that all modules must define are: 44 * 45 * INET_MODSTRTAB The name of the `streamtab' structure for this module. 46 * INET_MODDESC The one-line description for this module. 47 * INET_MODMTFLAGS The mt-streams(9F) flags for the module. 48 * 49 * The symbols that all drivers must define are: 50 * 51 * INET_DEVSTRTAB The name of the `streamtab' structure for this driver. 52 * INET_DEVDESC The one-line description for this driver. 53 * INET_DEVMTFLAGS The mt-streams(9F) flags for the driver. 54 * INET_DEVMINOR The minor number of the driver (usually 0). 55 * 56 * Drivers that need to masquerade as IP should set INET_DEVMTFLAGS to 57 * IP_DEVMTFLAGS and set INET_DEVSTRTAB to ipinfo. 58 * 59 * The symbols that all socket modules must define are: 60 * 61 * INET_SOCKDESC The one-line description for this socket module 62 * INET_SOCK_PROTO_CREATE_FUNC The function used to create PCBs 63 * 64 * In addition, socket modules that can be converted to TPI must define: 65 * 66 * INET_SOCK_PROTO_FB_FUNC The function used to fallback to TPI 67 */ 68 69 #if !defined(INET_NAME) 70 #error inetddi.c: INET_NAME is not defined! 71 #elif !defined(INET_DEVDESC) && !defined(INET_MODDESC) && \ 72 !defined(INET_SOCKDESC) 73 #error inetddi.c: at least one of INET_DEVDESC or INET_MODDESC or \ 74 INET_SOCKDESC must be defined! 75 #elif defined(INET_DEVDESC) && !defined(INET_DEVSTRTAB) 76 #error inetddi.c: INET_DEVDESC is defined but INET_DEVSTRTAB is not! 77 #elif defined(INET_DEVDESC) && !defined(INET_DEVMTFLAGS) 78 #error inetddi.c: INET_DEVDESC is defined but INET_DEVMTFLAGS is not! 79 #elif defined(INET_DEVDESC) && !defined(INET_DEVMINOR) 80 #error inetddi.c: INET_DEVDESC is defined but INET_DEVMINOR is not! 81 #elif defined(INET_MODDESC) && !defined(INET_MODSTRTAB) 82 #error inetddi.c: INET_MODDESC is defined but INET_MODSTRTAB is not! 83 #elif defined(INET_MODDESC) && !defined(INET_MODMTFLAGS) 84 #error inetddi.c: INET_MODDESC is defined but INET_MODMTFLAGS is not! 85 #elif defined(INET_SOCKDESC) && !defined(SOCKMOD_VERSION) 86 #error inetddi.c: INET_SOCKDESC is defined but SOCKMOD_VERSION is not! 87 #elif defined(INET_SOCKDESC) && !defined(INET_SOCK_PROTO_CREATE_FUNC) 88 #error inetddi.c: INET_SOCKDESC is defined but INET_SOCK_PROTO_CREATE_FUNC \ 89 is not! 90 #elif defined(INET_SOCK_PROTO_FB_FUNC) && !defined(INET_SOCK_FALLBACK_DEV_V4) 91 #error inetddi.c: INET_SOCK_PROTO_FB_FUNC is defined but \ 92 INET_SOCK_FALLBACK_DEV_V4 is not! 93 #elif defined(INET_SOCK_PROTO_FB_FUNC) && !defined(INET_SOCK_FALLBACK_DEV_V6) 94 #error inetddi.c: INET_SOCK_PROTO_FB_FUNC is defined but \ 95 INET_SOCK_FALLBACK_DEV_V6 is not! 96 #endif 97 98 #ifdef INET_DEVDESC 99 100 extern struct streamtab INET_DEVSTRTAB; 101 102 /* 103 * Drivers that actually want to be IP would set INET_DEVSTRTAB to ipinfo. 104 */ 105 106 static dev_info_t *inet_dev_info; 107 108 #define INET_DEFAULT_PRIV_MODE 0666 109 110 static struct dev_priv { 111 char *driver; 112 int privonly; 113 const char *read_priv; 114 const char *write_priv; 115 } netdev_privs[] = { 116 {"icmp", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS}, 117 {"icmp6", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS}, 118 {"ip", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS}, 119 {"ip6", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS}, 120 {"keysock", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 121 {"ipsecah", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 122 {"ipsecesp", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 123 {"spdsock", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 124 {NULL, 0, NULL, NULL} 125 }; 126 127 static int 128 inet_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 129 { 130 size_t i, ndevs; 131 132 if (cmd != DDI_ATTACH) 133 return (DDI_FAILURE); 134 135 inet_dev_info = devi; 136 137 ndevs = sizeof (netdev_privs) / sizeof (struct dev_priv); 138 for (i = 0; i < ndevs; i++) { 139 char *drv = netdev_privs[i].driver; 140 if (drv == NULL || strcmp(drv, ddi_driver_name(devi)) == 0) 141 break; 142 } 143 144 /* smatch has no idea what VERIFY does. */ 145 if (i == ndevs) { 146 VERIFY(i < ndevs); 147 return (DDI_FAILURE); 148 } 149 150 return (ddi_create_priv_minor_node(devi, INET_NAME, S_IFCHR, 151 INET_DEVMINOR, DDI_PSEUDO, netdev_privs[i].privonly, 152 netdev_privs[i].read_priv, netdev_privs[i].write_priv, 153 INET_DEFAULT_PRIV_MODE)); 154 } 155 156 static int 157 inet_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 158 { 159 if (cmd != DDI_DETACH) 160 return (DDI_FAILURE); 161 162 ASSERT(devi == inet_dev_info); 163 164 ddi_remove_minor_node(devi, NULL); 165 return (DDI_SUCCESS); 166 } 167 168 169 /* ARGSUSED */ 170 static int 171 inet_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 172 { 173 int error = DDI_FAILURE; 174 175 switch (cmd) { 176 case DDI_INFO_DEVT2DEVINFO: 177 if (inet_dev_info != NULL) { 178 *result = (void *)inet_dev_info; 179 error = DDI_SUCCESS; 180 } 181 break; 182 183 case DDI_INFO_DEVT2INSTANCE: 184 *result = NULL; 185 error = DDI_SUCCESS; 186 break; 187 188 default: 189 break; 190 } 191 192 return (error); 193 } 194 195 DDI_DEFINE_STREAM_OPS(inet_devops, nulldev, nulldev, inet_attach, inet_detach, 196 nulldev, inet_info, INET_DEVMTFLAGS, &INET_DEVSTRTAB, 197 ddi_quiesce_not_supported); 198 199 static struct modldrv modldrv = { 200 &mod_driverops, 201 INET_DEVDESC, 202 &inet_devops 203 }; 204 205 #endif /* INET_DEVDESC */ 206 207 #ifdef INET_MODDESC 208 extern struct streamtab INET_MODSTRTAB; 209 210 static struct fmodsw fsw = { 211 INET_NAME, 212 &INET_MODSTRTAB, 213 INET_MODMTFLAGS 214 }; 215 216 static struct modlstrmod modlstrmod = { 217 &mod_strmodops, 218 INET_MODDESC, 219 &fsw 220 }; 221 222 #endif /* INET_MODDESC */ 223 224 #ifdef INET_SOCKDESC 225 226 #ifdef INET_SOCK_PROTO_FB_FUNC 227 static __smod_priv_t smodpriv = { 228 NULL, 229 NULL, 230 INET_SOCK_PROTO_FB_FUNC, 231 INET_SOCK_FALLBACK_DEV_V4, 232 INET_SOCK_FALLBACK_DEV_V6 233 }; 234 #endif /* INET_SOCK_PROTO_FB_FUNC */ 235 236 static struct smod_reg_s smodreg = { 237 SOCKMOD_VERSION, 238 INET_NAME, 239 SOCK_UC_VERSION, 240 SOCK_DC_VERSION, 241 INET_SOCK_PROTO_CREATE_FUNC, 242 #ifdef INET_SOCK_PROTO_FB_FUNC 243 &smodpriv 244 #else 245 NULL 246 #endif /* INET_SOCK_PROTO_FB_FUNC */ 247 }; 248 249 static struct modlsockmod modlsockmod = { 250 &mod_sockmodops, 251 INET_SOCKDESC, 252 &smodreg 253 }; 254 #endif /* INET_SOCKDESC */ 255 256 static struct modlinkage modlinkage = { 257 MODREV_1, 258 #ifdef INET_DEVDESC 259 &modldrv, 260 #endif 261 #ifdef INET_MODDESC 262 &modlstrmod, 263 #endif 264 #ifdef INET_SOCKDESC 265 &modlsockmod, 266 #endif 267 NULL 268 }; 269