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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #include <sys/types.h> 28 #include <sys/stat.h> 29 #include <sys/stream.h> 30 #include <sys/ddi.h> 31 #include <sys/sunddi.h> 32 #include <sys/priv_names.h> 33 34 /* 35 * This file contains generic goo needed to hook the STREAMS modules and 36 * drivers that live under uts/common/inet into the DDI. In order to use it, 37 * each module/driver should #define the symbols below (as appropriate) and 38 * then #include this source file; see the other uts/common/inet/<star>ddi.c 39 * files for examples of this in action. 40 * 41 * The symbols that all modules and drivers must define are: 42 * 43 * INET_NAME The name of the module/driver. 44 * 45 * The symbols that all modules must define are: 46 * 47 * INET_MODSTRTAB The name of the `streamtab' structure for this module. 48 * INET_MODDESC The one-line description for this module. 49 * INET_MODMTFLAGS The mt-streams(9F) flags for the module. 50 * 51 * The symbols that all drivers must define are: 52 * 53 * INET_DEVSTRTAB The name of the `streamtab' structure for this driver. 54 * INET_DEVDESC The one-line description for this driver. 55 * INET_DEVMTFLAGS The mt-streams(9F) flags for the driver. 56 * INET_DEVMINOR The minor number of the driver (usually 0). 57 * 58 * Drivers that need to masquerade as IP should set INET_DEVMTFLAGS to 59 * IP_DEVMTFLAGS and set INET_DEVSTRTAB to ipinfo. 60 */ 61 62 #if !defined(INET_NAME) 63 #error inetddi.c: INET_NAME is not defined! 64 #elif !defined(INET_DEVDESC) && !defined(INET_MODDESC) 65 #error inetddi.c: at least one of INET_DEVDESC or INET_MODDESC must be defined! 66 #elif defined(INET_DEVDESC) && !defined(INET_DEVSTRTAB) 67 #error inetddi.c: INET_DEVDESC is defined but INET_DEVSTRTAB is not! 68 #elif defined(INET_DEVDESC) && !defined(INET_DEVMTFLAGS) 69 #error inetddi.c: INET_DEVDESC is defined but INET_DEVMTFLAGS is not! 70 #elif defined(INET_DEVDESC) && !defined(INET_DEVMINOR) 71 #error inetddi.c: INET_DEVDESC is defined but INET_DEVMINOR is not! 72 #elif defined(INET_MODDESC) && !defined(INET_MODSTRTAB) 73 #error inetddi.c: INET_MODDESC is defined but INET_MODSTRTAB is not! 74 #elif defined(INET_MODDESC) && !defined(INET_MODMTFLAGS) 75 #error inetddi.c: INET_MODDESC is defined but INET_MODMTFLAGS is not! 76 #endif 77 78 #ifdef INET_DEVDESC 79 80 extern struct streamtab INET_DEVSTRTAB; 81 82 /* 83 * Drivers that actually want to be IP would set INET_DEVSTRTAB to ipinfo. 84 */ 85 86 static dev_info_t *inet_dev_info; 87 88 #define INET_DEFAULT_PRIV_MODE 0666 89 90 static struct dev_priv { 91 char *driver; 92 int privonly; 93 const char *read_priv; 94 const char *write_priv; 95 } netdev_privs[] = { 96 {"icmp", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS}, 97 {"icmp6", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS}, 98 {"ip", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS}, 99 {"ip6", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS}, 100 {"keysock", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 101 {"ipsecah", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 102 {"ipsecesp", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 103 {"spdsock", PRIVONLY_DEV, PRIV_SYS_IP_CONFIG, PRIV_SYS_IP_CONFIG}, 104 {NULL, 0, NULL, NULL} 105 }; 106 107 static int 108 inet_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 109 { 110 int i, ndevs; 111 112 if (cmd != DDI_ATTACH) 113 return (DDI_FAILURE); 114 115 inet_dev_info = devi; 116 117 ndevs = sizeof (netdev_privs) / sizeof (struct dev_priv); 118 for (i = 0; i < ndevs; i++) { 119 char *drv = netdev_privs[i].driver; 120 if (drv == NULL || strcmp(drv, ddi_driver_name(devi)) == 0) 121 break; 122 } 123 124 return (ddi_create_priv_minor_node(devi, INET_NAME, S_IFCHR, 125 INET_DEVMINOR, DDI_PSEUDO, netdev_privs[i].privonly, 126 netdev_privs[i].read_priv, netdev_privs[i].write_priv, 127 INET_DEFAULT_PRIV_MODE)); 128 } 129 130 static int 131 inet_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 132 { 133 if (cmd != DDI_DETACH) 134 return (DDI_FAILURE); 135 136 ASSERT(devi == inet_dev_info); 137 138 ddi_remove_minor_node(devi, NULL); 139 return (DDI_SUCCESS); 140 } 141 142 143 /* ARGSUSED */ 144 static int 145 inet_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 146 { 147 int error = DDI_FAILURE; 148 149 switch (cmd) { 150 case DDI_INFO_DEVT2DEVINFO: 151 if (inet_dev_info != NULL) { 152 *result = (void *)inet_dev_info; 153 error = DDI_SUCCESS; 154 } 155 break; 156 157 case DDI_INFO_DEVT2INSTANCE: 158 *result = NULL; 159 error = DDI_SUCCESS; 160 break; 161 162 default: 163 break; 164 } 165 166 return (error); 167 } 168 169 DDI_DEFINE_STREAM_OPS(inet_devops, nulldev, nulldev, inet_attach, inet_detach, 170 nulldev, inet_info, INET_DEVMTFLAGS, &INET_DEVSTRTAB, 171 ddi_quiesce_not_supported); 172 173 static struct modldrv modldrv = { 174 &mod_driverops, 175 INET_DEVDESC, 176 &inet_devops 177 }; 178 179 #endif /* INET_DEVDESC */ 180 181 #ifdef INET_MODDESC 182 extern struct streamtab INET_MODSTRTAB; 183 184 static struct fmodsw fsw = { 185 INET_NAME, 186 &INET_MODSTRTAB, 187 INET_MODMTFLAGS 188 }; 189 190 static struct modlstrmod modlstrmod = { 191 &mod_strmodops, 192 INET_MODDESC, 193 &fsw 194 }; 195 #endif /* INET_MODDESC */ 196 197 static struct modlinkage modlinkage = { 198 MODREV_1, 199 #ifdef INET_DEVDESC 200 &modldrv, 201 #endif 202 #ifdef INET_MODDESC 203 &modlstrmod, 204 #endif 205 NULL 206 }; 207