xref: /titanic_50/usr/src/uts/common/inet/inetddi.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
30*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
31*7c478bd9Sstevel@tonic-gate #include <sys/stream.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/priv_names.h>
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate /*
37*7c478bd9Sstevel@tonic-gate  * This file contains generic goo needed to hook the STREAMS modules and
38*7c478bd9Sstevel@tonic-gate  * drivers that live under uts/common/inet into the DDI.  In order to use it,
39*7c478bd9Sstevel@tonic-gate  * each module/driver should #define the symbols below (as appropriate) and
40*7c478bd9Sstevel@tonic-gate  * then #include this source file; see the other uts/common/inet/<star>ddi.c
41*7c478bd9Sstevel@tonic-gate  * files for examples of this in action.
42*7c478bd9Sstevel@tonic-gate  *
43*7c478bd9Sstevel@tonic-gate  * The symbols that all modules and drivers must define are:
44*7c478bd9Sstevel@tonic-gate  *
45*7c478bd9Sstevel@tonic-gate  *	INET_NAME	 The name of the module/driver.
46*7c478bd9Sstevel@tonic-gate  *	INET_STRTAB	 The name of the `streamtab' structure.
47*7c478bd9Sstevel@tonic-gate  *
48*7c478bd9Sstevel@tonic-gate  * The symbols that all modules must define are:
49*7c478bd9Sstevel@tonic-gate  *
50*7c478bd9Sstevel@tonic-gate  *	INET_MODDESC	 The one-line description for this module.
51*7c478bd9Sstevel@tonic-gate  *	INET_MODMTFLAGS  The mt-streams(9F) flags for the module.
52*7c478bd9Sstevel@tonic-gate  *
53*7c478bd9Sstevel@tonic-gate  * The symbols that all drivers must define are:
54*7c478bd9Sstevel@tonic-gate  *
55*7c478bd9Sstevel@tonic-gate  *	INET_DEVDESC	 The one-line description for this driver.
56*7c478bd9Sstevel@tonic-gate  *	INET_DEVMTFLAGS  The mt-streams(9F) flags for the driver.
57*7c478bd9Sstevel@tonic-gate  *	INET_DEVMINOR	 The minor number of the driver (usually 0).
58*7c478bd9Sstevel@tonic-gate  *
59*7c478bd9Sstevel@tonic-gate  * Drivers that need to masquerade as IP should set INET_DEVMTFLAGS to
60*7c478bd9Sstevel@tonic-gate  * IP_DEVMTFLAGS and then call INET_BECOME_IP() in their _init(9E) routine.
61*7c478bd9Sstevel@tonic-gate  */
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate #if	!defined(INET_STRTAB)
64*7c478bd9Sstevel@tonic-gate #error inetddi.c: INET_STRTAB is not defined!
65*7c478bd9Sstevel@tonic-gate #elif	!defined(INET_NAME)
66*7c478bd9Sstevel@tonic-gate #error inetddi.c: INET_NAME is not defined!
67*7c478bd9Sstevel@tonic-gate #elif	!defined(INET_DEVDESC) && !defined(INET_MODDESC)
68*7c478bd9Sstevel@tonic-gate #error inetddi.c: at least one of INET_DEVDESC or INET_MODDESC must be defined!
69*7c478bd9Sstevel@tonic-gate #elif	defined(INET_DEVDESC) && !defined(INET_DEVMTFLAGS)
70*7c478bd9Sstevel@tonic-gate #error inetddi.c: INET_DEVDESC is defined but INET_DEVMTFLAGS is not!
71*7c478bd9Sstevel@tonic-gate #elif	defined(INET_DEVDESC) && !defined(INET_DEVMINOR)
72*7c478bd9Sstevel@tonic-gate #error inetddi.c: INET_DEVDESC is defined but INET_DEVMINOR is not!
73*7c478bd9Sstevel@tonic-gate #elif	defined(INET_MODDESC) && !defined(INET_MODMTFLAGS)
74*7c478bd9Sstevel@tonic-gate #error inetddi.c: INET_MODDESC is defined but INET_MODMTFLAGS is not!
75*7c478bd9Sstevel@tonic-gate #endif
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate extern struct streamtab INET_STRTAB, ipinfo;
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate #ifdef	INET_DEVDESC
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate /*
82*7c478bd9Sstevel@tonic-gate  * This macro is intended to be called from the _init() routine of drivers
83*7c478bd9Sstevel@tonic-gate  * that actually want to be IP.  Yes, this is a disgusting, vile hack.
84*7c478bd9Sstevel@tonic-gate  */
85*7c478bd9Sstevel@tonic-gate #define	INET_BECOME_IP()	(cb_inet_devops.cb_str = &ipinfo)
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate static dev_info_t *inet_dev_info;
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate #define	INET_DEFAULT_PRIV_MODE	0666
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate static struct dev_priv {
92*7c478bd9Sstevel@tonic-gate 	char *driver;
93*7c478bd9Sstevel@tonic-gate 	int privonly;
94*7c478bd9Sstevel@tonic-gate 	const char *read_priv;
95*7c478bd9Sstevel@tonic-gate 	const char *write_priv;
96*7c478bd9Sstevel@tonic-gate } netdev_privs[] = {
97*7c478bd9Sstevel@tonic-gate 	{"icmp", PRIVONLY_DEV,	PRIV_NET_ICMPACCESS,	PRIV_NET_ICMPACCESS},
98*7c478bd9Sstevel@tonic-gate 	{"icmp6", PRIVONLY_DEV,	PRIV_NET_ICMPACCESS,	PRIV_NET_ICMPACCESS},
99*7c478bd9Sstevel@tonic-gate 	{"ip", PRIVONLY_DEV,	PRIV_NET_RAWACCESS,	PRIV_NET_RAWACCESS},
100*7c478bd9Sstevel@tonic-gate 	{"ip6", PRIVONLY_DEV,	PRIV_NET_RAWACCESS,	PRIV_NET_RAWACCESS},
101*7c478bd9Sstevel@tonic-gate 	{"keysock", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG,	PRIV_SYS_NET_CONFIG},
102*7c478bd9Sstevel@tonic-gate 	{"ipsecah", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG,	PRIV_SYS_NET_CONFIG},
103*7c478bd9Sstevel@tonic-gate 	{"ipsecesp", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG,	PRIV_SYS_NET_CONFIG},
104*7c478bd9Sstevel@tonic-gate 	{"spdsock", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG,	PRIV_SYS_NET_CONFIG},
105*7c478bd9Sstevel@tonic-gate 	{NULL,	0,		NULL,			NULL}
106*7c478bd9Sstevel@tonic-gate };
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate static int
109*7c478bd9Sstevel@tonic-gate inet_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
110*7c478bd9Sstevel@tonic-gate {
111*7c478bd9Sstevel@tonic-gate 	int i, ndevs;
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	if (cmd != DDI_ATTACH)
114*7c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	inet_dev_info = devi;
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 	ndevs = sizeof (netdev_privs) / sizeof (struct dev_priv);
119*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < ndevs; i++) {
120*7c478bd9Sstevel@tonic-gate 		char *drv = netdev_privs[i].driver;
121*7c478bd9Sstevel@tonic-gate 		if (drv == NULL || strcmp(drv, ddi_driver_name(devi)) == 0)
122*7c478bd9Sstevel@tonic-gate 			break;
123*7c478bd9Sstevel@tonic-gate 	}
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 	return (ddi_create_priv_minor_node(devi, INET_NAME, S_IFCHR,
126*7c478bd9Sstevel@tonic-gate 	    INET_DEVMINOR, DDI_PSEUDO, netdev_privs[i].privonly,
127*7c478bd9Sstevel@tonic-gate 	    netdev_privs[i].read_priv, netdev_privs[i].write_priv,
128*7c478bd9Sstevel@tonic-gate 	    INET_DEFAULT_PRIV_MODE));
129*7c478bd9Sstevel@tonic-gate }
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate static int
132*7c478bd9Sstevel@tonic-gate inet_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
133*7c478bd9Sstevel@tonic-gate {
134*7c478bd9Sstevel@tonic-gate 	if (cmd != DDI_DETACH)
135*7c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	ASSERT(devi == inet_dev_info);
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 	ddi_remove_minor_node(devi, NULL);
140*7c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
141*7c478bd9Sstevel@tonic-gate }
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
145*7c478bd9Sstevel@tonic-gate static int
146*7c478bd9Sstevel@tonic-gate inet_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
147*7c478bd9Sstevel@tonic-gate {
148*7c478bd9Sstevel@tonic-gate 	int error = DDI_FAILURE;
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 	switch (cmd) {
151*7c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
152*7c478bd9Sstevel@tonic-gate 		if (inet_dev_info != NULL) {
153*7c478bd9Sstevel@tonic-gate 			*result = (void *)inet_dev_info;
154*7c478bd9Sstevel@tonic-gate 			error = DDI_SUCCESS;
155*7c478bd9Sstevel@tonic-gate 		}
156*7c478bd9Sstevel@tonic-gate 		break;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
159*7c478bd9Sstevel@tonic-gate 		*result = NULL;
160*7c478bd9Sstevel@tonic-gate 		error = DDI_SUCCESS;
161*7c478bd9Sstevel@tonic-gate 		break;
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 	default:
164*7c478bd9Sstevel@tonic-gate 		break;
165*7c478bd9Sstevel@tonic-gate 	}
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 	return (error);
168*7c478bd9Sstevel@tonic-gate }
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate DDI_DEFINE_STREAM_OPS(inet_devops, nulldev, nulldev, inet_attach, inet_detach,
171*7c478bd9Sstevel@tonic-gate     nulldev, inet_info, INET_DEVMTFLAGS, &INET_STRTAB);
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate static struct modldrv modldrv = {
174*7c478bd9Sstevel@tonic-gate 	&mod_driverops,
175*7c478bd9Sstevel@tonic-gate 	INET_DEVDESC,
176*7c478bd9Sstevel@tonic-gate 	&inet_devops
177*7c478bd9Sstevel@tonic-gate };
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate #endif /* INET_DEVDESC */
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate #ifdef	INET_MODDESC
182*7c478bd9Sstevel@tonic-gate static struct fmodsw fsw = {
183*7c478bd9Sstevel@tonic-gate 	INET_NAME,
184*7c478bd9Sstevel@tonic-gate 	&INET_STRTAB,
185*7c478bd9Sstevel@tonic-gate 	INET_MODMTFLAGS
186*7c478bd9Sstevel@tonic-gate };
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate static struct modlstrmod modlstrmod = {
189*7c478bd9Sstevel@tonic-gate 	&mod_strmodops,
190*7c478bd9Sstevel@tonic-gate 	INET_MODDESC,
191*7c478bd9Sstevel@tonic-gate 	&fsw
192*7c478bd9Sstevel@tonic-gate };
193*7c478bd9Sstevel@tonic-gate #endif /* INET_MODDESC */
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
196*7c478bd9Sstevel@tonic-gate 	MODREV_1,
197*7c478bd9Sstevel@tonic-gate #ifdef	INET_DEVDESC
198*7c478bd9Sstevel@tonic-gate 	&modldrv,
199*7c478bd9Sstevel@tonic-gate #endif
200*7c478bd9Sstevel@tonic-gate #ifdef	INET_MODDESC
201*7c478bd9Sstevel@tonic-gate 	&modlstrmod,
202*7c478bd9Sstevel@tonic-gate #endif
203*7c478bd9Sstevel@tonic-gate 	NULL
204*7c478bd9Sstevel@tonic-gate };
205