xref: /titanic_51/usr/src/uts/common/inet/inetddi.c (revision 9acbbeaf2a1ffe5c14b244867d427714fab43c5c)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/stream.h>
32 #include <sys/ddi.h>
33 #include <sys/sunddi.h>
34 #include <sys/priv_names.h>
35 
36 /*
37  * This file contains generic goo needed to hook the STREAMS modules and
38  * drivers that live under uts/common/inet into the DDI.  In order to use it,
39  * each module/driver should #define the symbols below (as appropriate) and
40  * then #include this source file; see the other uts/common/inet/<star>ddi.c
41  * files for examples of this in action.
42  *
43  * The symbols that all modules and drivers must define are:
44  *
45  *	INET_NAME	 The name of the module/driver.
46  *	INET_STRTAB	 The name of the `streamtab' structure.
47  *
48  * The symbols that all modules must define are:
49  *
50  *	INET_MODDESC	 The one-line description for this module.
51  *	INET_MODMTFLAGS  The mt-streams(9F) flags for the module.
52  *
53  * The symbols that all drivers must define are:
54  *
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 then call INET_BECOME_IP() in their _init(9E) routine.
61  */
62 
63 #if	!defined(INET_STRTAB)
64 #error inetddi.c: INET_STRTAB is not defined!
65 #elif	!defined(INET_NAME)
66 #error inetddi.c: INET_NAME is not defined!
67 #elif	!defined(INET_DEVDESC) && !defined(INET_MODDESC)
68 #error inetddi.c: at least one of INET_DEVDESC or INET_MODDESC must be defined!
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_MODMTFLAGS)
74 #error inetddi.c: INET_MODDESC is defined but INET_MODMTFLAGS is not!
75 #endif
76 
77 extern struct streamtab INET_STRTAB, ipinfo;
78 
79 #ifdef	INET_DEVDESC
80 
81 /*
82  * This macro is intended to be called from the _init() routine of drivers
83  * that actually want to be IP.  Yes, this is a disgusting, vile hack.
84  */
85 #define	INET_BECOME_IP()	(cb_inet_devops.cb_str = &ipinfo)
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_NET_CONFIG,	PRIV_SYS_NET_CONFIG},
102 	{"ipsecah", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG,	PRIV_SYS_NET_CONFIG},
103 	{"ipsecesp", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG,	PRIV_SYS_NET_CONFIG},
104 	{"spdsock", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG,	PRIV_SYS_NET_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_STRTAB);
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 static struct fmodsw fsw = {
183 	INET_NAME,
184 	&INET_STRTAB,
185 	INET_MODMTFLAGS
186 };
187 
188 static struct modlstrmod modlstrmod = {
189 	&mod_strmodops,
190 	INET_MODDESC,
191 	&fsw
192 };
193 #endif /* INET_MODDESC */
194 
195 static struct modlinkage modlinkage = {
196 	MODREV_1,
197 #ifdef	INET_DEVDESC
198 	&modldrv,
199 #endif
200 #ifdef	INET_MODDESC
201 	&modlstrmod,
202 #endif
203 	NULL
204 };
205