4045d94132614e1de2073685a6cdd4fbd86bec33sowmini/*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * CDDL HEADER START
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * The contents of this file are subject to the terms of the
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * Common Development and Distribution License (the "License").
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * You may not use this file except in compliance with the License.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * or http://www.opensolaris.org/os/licensing.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * See the License for the specific language governing permissions
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * and limitations under the License.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * When distributing Covered Code, include this CDDL HEADER in each
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * If applicable, add the following below this CDDL HEADER, with the
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * fields enclosed by brackets "[]" replaced with your own identifying
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * information: Portions Copyright [yyyy] [name of copyright owner]
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * CDDL HEADER END
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini/*
aa71ed9349acc5954237c132b9d246f93d204a54Prakash Jalan * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini/*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * functions to handle legacy ndd ioctls
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini#include <sys/types.h>
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini#include <sys/mac.h>
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini#include <sys/mac_impl.h>
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer#include <sys/mac_client_priv.h>
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini#include <inet/nd.h>
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini#include <sys/mac_ether.h>
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini#include <sys/policy.h>
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini#include <sys/strsun.h>
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic int mac_ndd_set_ioctl(mac_impl_t *, mblk_t *, int, int *);
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic int mac_ndd_get_ioctl(mac_impl_t *, mblk_t *, int, int *);
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic int mac_ndd_get_names(mac_impl_t *, mblk_t *);
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic boolean_t mac_add_name(mblk_t *, char *, int);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini/*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * add "<name> (<rwtag>) " into the mblk, allocating more memory if needed.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic boolean_t
4045d94132614e1de2073685a6cdd4fbd86bec33sowminimac_add_name(mblk_t *mp, char *name, int ndd_flags)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini{
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini char *cp, *rwtag;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini int len, flags;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini flags = (ndd_flags & (MAC_PROP_PERM_WRITE|MAC_PROP_PERM_READ));
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini switch (flags) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 0:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini rwtag = "no read or write";
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case MAC_PROP_PERM_WRITE:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini rwtag = "write only";
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case MAC_PROP_PERM_READ:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini rwtag = "read only";
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini default:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini rwtag = "read and write";
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini while (mp->b_cont != NULL)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp = mp->b_cont;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * allocate space for name, <space>, '(', rwtag, ')', and
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * two terminating null chars.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini len = strlen(name) + strlen(rwtag) + 6;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (mp->b_wptr + len >= mp->b_datap->db_lim) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp->b_cont = allocb(len, BPRI_HI);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp = mp->b_cont;
aa71ed9349acc5954237c132b9d246f93d204a54Prakash Jalan if (mp == NULL)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (B_FALSE);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini cp = (char *)mp->b_wptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini (void) snprintf(cp, len, "%s (%s)", name, rwtag);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp->b_wptr += strnlen(cp, len);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp->b_wptr++; /* skip past the terminating \0 */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (B_TRUE);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini}
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini/*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * handle a query for "ndd -get \?". The result is put into mp, and
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * more memory is allocated if needed. The resulting size of the data
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * is returned.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic int
4045d94132614e1de2073685a6cdd4fbd86bec33sowminimac_ndd_get_names(mac_impl_t *mip, mblk_t *mp)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini{
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini int size_out, i;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mblk_t *tmp;
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems uint_t permflags;
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems int status;
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems uint64_t value;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer char *prop_name;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (!mac_add_name(mp, "?", MAC_PROP_PERM_READ))
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (-1);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /* first the known ndd mappings */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini for (i = 0; i < mip->mi_type->mt_mappingcount; i++) {
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems if ((mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_MAP_KSTAT)
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems != 0)
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems permflags = MAC_PROP_PERM_READ;
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems else {
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems status = mip->mi_callbacks->mc_getprop(mip->mi_driver,
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems mip->mi_type->mt_mapping[i].mp_name,
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems mip->mi_type->mt_mapping[i].mp_prop_id,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mip->mi_type->mt_mapping[i].mp_valsize, &value);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (status != 0)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer continue;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer status = mac_prop_info((mac_handle_t)mip,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mip->mi_type->mt_mapping[i].mp_prop_id,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mip->mi_type->mt_mapping[i].mp_name, NULL, 0,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer NULL, &permflags);
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems if (status != 0)
646b4e2aeb6f1c0aa68b7c90784b7ab3fd1d3cc2Vasumathi Sundaram - Sun Microsystems continue;
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (!mac_add_name(mp, mip->mi_type->mt_mapping[i].mp_name,
afdda45f890ee5dfc86e5131a30b11b354d51633Vasumathi Sundaram - Sun Microsystems permflags))
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (-1);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /* now the driver's ndd variables */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini for (i = 0; i < mip->mi_priv_prop_count; i++) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer prop_name = mip->mi_priv_prop[i];
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (mac_prop_info((mac_handle_t)mip, MAC_PROP_PRIVATE,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer prop_name, NULL, 0, NULL, &permflags) != 0)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer return (-1);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /* skip over the "_" */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (!mac_add_name(mp, &prop_name[1], permflags))
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (-1);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini tmp = mp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini while (tmp->b_cont != NULL)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini tmp = tmp->b_cont;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *tmp->b_wptr++ = '\0';
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini size_out = msgdsize(mp);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (size_out);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini}
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini/*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * Handle legacy ndd ioctls for ND_GET and ND_SET.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowminivoid
4045d94132614e1de2073685a6cdd4fbd86bec33sowminimac_ndd_ioctl(mac_impl_t *mip, queue_t *wq, mblk_t *mp)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini{
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini IOCP iocp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini int cmd, err, rval;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini iocp = (IOCP)mp->b_rptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (iocp->ioc_count == 0 || mp->b_cont == NULL) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini err = EINVAL;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto done;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini cmd = iocp->ioc_cmd;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (cmd == ND_SET) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini err = mac_ndd_set_ioctl(mip, mp, iocp->ioc_count, &rval);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini } else if (cmd == ND_GET) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini err = mac_ndd_get_ioctl(mip, mp, iocp->ioc_count, &rval);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowminidone:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (err == 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini miocack(wq, mp, msgdsize(mp->b_cont), rval);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini else
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini miocnak(wq, mp, 0, err);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini}
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic int
4045d94132614e1de2073685a6cdd4fbd86bec33sowminimac_ndd_get_ioctl(mac_impl_t *mip, mblk_t *mp, int avail, int *rval)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini{
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mblk_t *mp1;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini char *valp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uchar_t *value;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint32_t new_value;
aa71ed9349acc5954237c132b9d246f93d204a54Prakash Jalan int size_out = 0, i;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini int status = EINVAL;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini char *name, priv_name[MAXLINKPROPNAME];
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint8_t u8;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint16_t u16;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint32_t u32;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint64_t u64;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (mp->b_cont == NULL || avail < 2)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (EINVAL);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini valp = (char *)mp->b_cont->b_rptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp1 = allocb(avail, BPRI_HI); /* the returned buffer */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (mp1 == NULL)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (ENOMEM);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (strcmp(valp, "?") == 0) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * handle "ndd -get <..> \?" queries.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini size_out = mac_ndd_get_names(mip, mp1);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (size_out < 0) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = ENOMEM;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto get_done;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (size_out > avail) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini int excess;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini char *cp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * need more user buffer space. Return as many
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * mblks as will fit and return the needed
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * buffer size in ioc_rval.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini excess = size_out - avail;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *rval = size_out; /* what's needed */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini size_out -= excess;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini (void) adjmsg(mp1, -(excess + 1));
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini cp = (char *)mp1->b_wptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *cp = '\0';
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = 0;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto get_done;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini ASSERT(mip->mi_callbacks->mc_callbacks & MC_GETPROP);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini name = valp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini valp = (char *)mp1->b_rptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp1->b_wptr = mp1->b_rptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /* first lookup ndd <-> public property mapping */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini for (i = 0; i < mip->mi_type->mt_mappingcount; i++) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (strcmp(name, mip->mi_type->mt_mapping[i].mp_name) != 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini continue;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini switch (mip->mi_type->mt_mapping[i].mp_valsize) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 1:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini value = (uchar_t *)&u8;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 2:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini value = (uchar_t *)&u16;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 4:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini value = (uchar_t *)&u32;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini default:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini value = (uchar_t *)&u64;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if ((mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_MAP_KSTAT)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini != 0) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini u64 = mac_stat_get((mac_handle_t)mip,
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mip->mi_type->mt_mapping[i].mp_kstat);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = 0;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * ether_stats are all always KSTAT_DATA_UINT32
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini new_value = u32 = (long)u64;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini } else {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = mip->mi_callbacks->mc_getprop(mip->mi_driver,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer name, mip->mi_type->mt_mapping[i].mp_prop_id,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mip->mi_type->mt_mapping[i].mp_valsize, value);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini switch (mip->mi_type->mt_mapping[i].mp_valsize) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 1:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini new_value = u8;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 2:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini new_value = u16;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 4:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini new_value = u32;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 8:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * The only uint64_t is for speed, which is
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * converted to Mbps in ndd reports.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini new_value = (u64/1000000);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (status != 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto get_done;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini (void) snprintf(valp, avail, "%d", new_value);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto update_reply;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /*
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * could not find a public property. try the private prop route
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini * where all string processing will be done by the driver.
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini (void) snprintf(priv_name, sizeof (priv_name), "_%s", name);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = mip->mi_callbacks->mc_getprop(mip->mi_driver, priv_name,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer MAC_PROP_PRIVATE, avail - 2, mp1->b_rptr);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (status != 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto get_done;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowminiupdate_reply:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini size_out += strnlen((const char *)mp1->b_rptr, avail);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini valp += size_out;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *valp++ = '\0'; /* need \0\0 */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *valp++ = '\0';
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp1->b_wptr = (uchar_t *)valp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *rval = 0;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowminiget_done:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini freemsg(mp->b_cont);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (status == 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp->b_cont = mp1;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini else {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini freemsg(mp1);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp->b_cont = NULL;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (status);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini}
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowministatic int
4045d94132614e1de2073685a6cdd4fbd86bec33sowminimac_ndd_set_ioctl(mac_impl_t *mip, mblk_t *mp, int avail, int *rval)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini{
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mblk_t *mp1;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini char *valp, *name, *new_valuep;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uchar_t *vp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini long new_value;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini int status, i;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint8_t u8;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint16_t u16;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini uint32_t u32;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini IOCP iocp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini char priv_name[MAXLINKPROPNAME];
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (avail == 0 || !(mp1 = mp->b_cont))
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (EINVAL);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (mp1->b_cont) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini freemsg(mp1->b_cont);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp1->b_cont = NULL;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp1->b_datap->db_lim[-1] = '\0';
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini valp = (char *)mp1->b_rptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini name = valp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini *rval = 0;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini while (*valp++)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini ;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (valp >= (char *)mp1->b_wptr)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini valp = NULL;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini new_valuep = valp;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (ddi_strtol(valp, NULL, 0, &new_value) != 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto priv_prop;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini iocp = (IOCP)mp->b_rptr;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (valp != NULL &&
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini ((iocp->ioc_cr == NULL) ||
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini ((status = secpolicy_net_config(iocp->ioc_cr, B_FALSE)) != 0)))
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (status);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = EINVAL;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini /* first lookup ndd <-> public property mapping */
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini for (i = 0; i < mip->mi_type->mt_mappingcount; i++) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (strcmp(name, mip->mi_type->mt_mapping[i].mp_name) != 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini continue;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_MAP_KSTAT)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (EINVAL);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini if (new_value > mip->mi_type->mt_mapping[i].mp_maxval ||
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini new_value < mip->mi_type->mt_mapping[i].mp_minval ||
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini (mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_PERM_WRITE)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini == 0)
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (EINVAL);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini switch (mip->mi_type->mt_mapping[i].mp_valsize) {
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 1:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini u8 = (uint8_t)new_value;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini vp = (uchar_t *)&u8;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 2:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini u16 = (uint16_t)new_value;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini vp = (uchar_t *)&u16;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 4:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini u32 = (uint32_t)new_value;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini vp = (uchar_t *)&u32;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini case 8:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini vp = (uchar_t *)&new_value;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini break;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini default:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (ENOTSUP);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = mip->mi_callbacks->mc_setprop(mip->mi_driver,
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini name, mip->mi_type->mt_mapping[i].mp_prop_id,
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mip->mi_type->mt_mapping[i].mp_valsize, (const void *)vp);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini goto done;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini }
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini
4045d94132614e1de2073685a6cdd4fbd86bec33sowminipriv_prop:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini (void) snprintf(priv_name, sizeof (priv_name), "_%s", name);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini status = mip->mi_callbacks->mc_setprop(mip->mi_driver, priv_name,
3fd94f8c011031b38162a1db3b554de4371c167fam MAC_PROP_PRIVATE, strlen(new_valuep), new_valuep);
4045d94132614e1de2073685a6cdd4fbd86bec33sowminidone:
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini freemsg(mp1);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini mp->b_cont = NULL;
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini return (status);
4045d94132614e1de2073685a6cdd4fbd86bec33sowmini}