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