summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/inetddi.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/uts/common/inet/inetddi.c
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/uts/common/inet/inetddi.c')
-rw-r--r--usr/src/uts/common/inet/inetddi.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/usr/src/uts/common/inet/inetddi.c b/usr/src/uts/common/inet/inetddi.c
new file mode 100644
index 0000000000..476de3dd2f
--- /dev/null
+++ b/usr/src/uts/common/inet/inetddi.c
@@ -0,0 +1,204 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/stream.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/priv_names.h>
+
+/*
+ * This file contains generic goo needed to hook the STREAMS modules and
+ * drivers that live under uts/common/inet into the DDI. In order to use it,
+ * each module/driver should #define the symbols below (as appropriate) and
+ * then #include this source file; see the other uts/common/inet/<star>ddi.c
+ * files for examples of this in action.
+ *
+ * The symbols that all modules and drivers must define are:
+ *
+ * INET_NAME The name of the module/driver.
+ * INET_STRTAB The name of the `streamtab' structure.
+ *
+ * The symbols that all modules must define are:
+ *
+ * INET_MODDESC The one-line description for this module.
+ * INET_MODMTFLAGS The mt-streams(9F) flags for the module.
+ *
+ * The symbols that all drivers must define are:
+ *
+ * INET_DEVDESC The one-line description for this driver.
+ * INET_DEVMTFLAGS The mt-streams(9F) flags for the driver.
+ * INET_DEVMINOR The minor number of the driver (usually 0).
+ *
+ * Drivers that need to masquerade as IP should set INET_DEVMTFLAGS to
+ * IP_DEVMTFLAGS and then call INET_BECOME_IP() in their _init(9E) routine.
+ */
+
+#if !defined(INET_STRTAB)
+#error inetddi.c: INET_STRTAB is not defined!
+#elif !defined(INET_NAME)
+#error inetddi.c: INET_NAME is not defined!
+#elif !defined(INET_DEVDESC) && !defined(INET_MODDESC)
+#error inetddi.c: at least one of INET_DEVDESC or INET_MODDESC must be defined!
+#elif defined(INET_DEVDESC) && !defined(INET_DEVMTFLAGS)
+#error inetddi.c: INET_DEVDESC is defined but INET_DEVMTFLAGS is not!
+#elif defined(INET_DEVDESC) && !defined(INET_DEVMINOR)
+#error inetddi.c: INET_DEVDESC is defined but INET_DEVMINOR is not!
+#elif defined(INET_MODDESC) && !defined(INET_MODMTFLAGS)
+#error inetddi.c: INET_MODDESC is defined but INET_MODMTFLAGS is not!
+#endif
+
+extern struct streamtab INET_STRTAB, ipinfo;
+
+#ifdef INET_DEVDESC
+
+/*
+ * This macro is intended to be called from the _init() routine of drivers
+ * that actually want to be IP. Yes, this is a disgusting, vile hack.
+ */
+#define INET_BECOME_IP() (cb_inet_devops.cb_str = &ipinfo)
+
+static dev_info_t *inet_dev_info;
+
+#define INET_DEFAULT_PRIV_MODE 0666
+
+static struct dev_priv {
+ char *driver;
+ int privonly;
+ const char *read_priv;
+ const char *write_priv;
+} netdev_privs[] = {
+ {"icmp", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS},
+ {"icmp6", PRIVONLY_DEV, PRIV_NET_ICMPACCESS, PRIV_NET_ICMPACCESS},
+ {"ip", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS},
+ {"ip6", PRIVONLY_DEV, PRIV_NET_RAWACCESS, PRIV_NET_RAWACCESS},
+ {"keysock", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG, PRIV_SYS_NET_CONFIG},
+ {"ipsecah", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG, PRIV_SYS_NET_CONFIG},
+ {"ipsecesp", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG, PRIV_SYS_NET_CONFIG},
+ {"spdsock", PRIVONLY_DEV, PRIV_SYS_NET_CONFIG, PRIV_SYS_NET_CONFIG},
+ {NULL, 0, NULL, NULL}
+};
+
+static int
+inet_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
+{
+ int i, ndevs;
+
+ if (cmd != DDI_ATTACH)
+ return (DDI_FAILURE);
+
+ inet_dev_info = devi;
+
+ ndevs = sizeof (netdev_privs) / sizeof (struct dev_priv);
+ for (i = 0; i < ndevs; i++) {
+ char *drv = netdev_privs[i].driver;
+ if (drv == NULL || strcmp(drv, ddi_driver_name(devi)) == 0)
+ break;
+ }
+
+ return (ddi_create_priv_minor_node(devi, INET_NAME, S_IFCHR,
+ INET_DEVMINOR, DDI_PSEUDO, netdev_privs[i].privonly,
+ netdev_privs[i].read_priv, netdev_privs[i].write_priv,
+ INET_DEFAULT_PRIV_MODE));
+}
+
+static int
+inet_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
+{
+ if (cmd != DDI_DETACH)
+ return (DDI_FAILURE);
+
+ ASSERT(devi == inet_dev_info);
+
+ ddi_remove_minor_node(devi, NULL);
+ return (DDI_SUCCESS);
+}
+
+
+/* ARGSUSED */
+static int
+inet_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
+{
+ int error = DDI_FAILURE;
+
+ switch (cmd) {
+ case DDI_INFO_DEVT2DEVINFO:
+ if (inet_dev_info != NULL) {
+ *result = (void *)inet_dev_info;
+ error = DDI_SUCCESS;
+ }
+ break;
+
+ case DDI_INFO_DEVT2INSTANCE:
+ *result = NULL;
+ error = DDI_SUCCESS;
+ break;
+
+ default:
+ break;
+ }
+
+ return (error);
+}
+
+DDI_DEFINE_STREAM_OPS(inet_devops, nulldev, nulldev, inet_attach, inet_detach,
+ nulldev, inet_info, INET_DEVMTFLAGS, &INET_STRTAB);
+
+static struct modldrv modldrv = {
+ &mod_driverops,
+ INET_DEVDESC,
+ &inet_devops
+};
+
+#endif /* INET_DEVDESC */
+
+#ifdef INET_MODDESC
+static struct fmodsw fsw = {
+ INET_NAME,
+ &INET_STRTAB,
+ INET_MODMTFLAGS
+};
+
+static struct modlstrmod modlstrmod = {
+ &mod_strmodops,
+ INET_MODDESC,
+ &fsw
+};
+#endif /* INET_MODDESC */
+
+static struct modlinkage modlinkage = {
+ MODREV_1,
+#ifdef INET_DEVDESC
+ &modldrv,
+#endif
+#ifdef INET_MODDESC
+ &modlstrmod,
+#endif
+ NULL
+};