xref: /illumos-gate/usr/src/uts/common/inet/inetddi.c (revision bc37da3a)
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