inetddi.c revision 7656:2621e50fdf4a
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 80extern struct streamtab INET_DEVSTRTAB; 81 82/* 83 * Drivers that actually want to be IP would set INET_DEVSTRTAB to ipinfo. 84 */ 85 86static dev_info_t *inet_dev_info; 87 88#define INET_DEFAULT_PRIV_MODE 0666 89 90static 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 107static int 108inet_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 130static int 131inet_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 */ 144static int 145inet_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 169DDI_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 173static struct modldrv modldrv = { 174 &mod_driverops, 175 INET_DEVDESC, 176 &inet_devops 177}; 178 179#endif /* INET_DEVDESC */ 180 181#ifdef INET_MODDESC 182extern struct streamtab INET_MODSTRTAB; 183 184static struct fmodsw fsw = { 185 INET_NAME, 186 &INET_MODSTRTAB, 187 INET_MODMTFLAGS 188}; 189 190static struct modlstrmod modlstrmod = { 191 &mod_strmodops, 192 INET_MODDESC, 193 &fsw 194}; 195#endif /* INET_MODDESC */ 196 197static 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