示例#1
0
int
dlpi_enabnotify(dlpi_handle_t dh, uint_t notes, dlpi_notifyfunc_t *funcp,
    void *arg, dlpi_notifyid_t *id)
{
	int			retval;
	dlpi_msg_t		req, ack;
	dl_notify_req_t		*notifyreqp;
	dlpi_impl_t		*dip = (dlpi_impl_t *)dh;
	dlpi_notifyent_t	*newnotifp;
	dlpi_info_t 		dlinfo;

	if (dip == NULL)
		return (DLPI_EINHANDLE);

	retval = dlpi_info((dlpi_handle_t)dip, &dlinfo, 0);
	if (retval != DLPI_SUCCESS)
		return (retval);

	if (dip->dli_note_processing)
		return (DLPI_FAILURE);

	if (funcp == NULL || id == NULL)
		return (DLPI_EINVAL);

	if ((~DLPI_NOTIFICATION_TYPES & notes) ||
	    !(notes & DLPI_NOTIFICATION_TYPES))
		return (DLPI_ENOTEINVAL);

	DLPI_MSG_CREATE(req, DL_NOTIFY_REQ);
	DLPI_MSG_CREATE(ack, DL_NOTIFY_ACK);

	notifyreqp = &(req.dlm_msg->notify_req);
	notifyreqp->dl_notifications = notes;
	notifyreqp->dl_timelimit = 0;

	retval = i_dlpi_msg_common(dip, &req, &ack, DL_NOTIFY_ACK_SIZE, 0);
	if (retval == DL_NOTSUPPORTED)
		return (DLPI_ENOTENOTSUP);

	if (retval != DLPI_SUCCESS)
		return (retval);

	if ((newnotifp = calloc(1, sizeof (dlpi_notifyent_t))) == NULL)
		return (DL_SYSERR);

	/* Register notification information. */
	newnotifp->dln_fnp = funcp;
	newnotifp->dln_notes = notes;
	newnotifp->arg = arg;
	newnotifp->dln_rm = B_FALSE;

	/* Insert notification node at head */
	newnotifp->dln_next = dip->dli_notifylistp;
	dip->dli_notifylistp = newnotifp;

	*id = (dlpi_notifyid_t)newnotifp;
	return (DLPI_SUCCESS);
}
示例#2
0
/*
 * Verify with DLPI that the link is the expected DLPI 'style' device,
 * dlpi_info sets the DLPI style in the DLPI handle.
 */
static int
i_dlpi_checkstyle(dlpi_impl_t *dip, t_uscalar_t style)
{
	int retval;
	dlpi_info_t dlinfo;

	retval = dlpi_info((dlpi_handle_t)dip, &dlinfo, 0);
	if (retval == DLPI_SUCCESS && dip->dli_style != style)
		retval = DLPI_EBADLINK;

	return (retval);
}
示例#3
0
文件: lldd.c 项目: jasonbking/lldp
static boolean_t
dlpi_walk_cb(const char *name, void *arg)
{
	NOTE(ARGUNUSED(arg))

	dlpi_handle_t dlh;
	link_t *link;
	int rc;
	dlpi_info_t info;
	boolean_t keep;
	size_t len;

	rc = dlpi_open(name, &dlh, DLPI_PASSIVE|DLPI_NATIVE);
	if (rc != DLPI_SUCCESS) {
		DMSG(D_NET, "dlpi_open(%s) failed: %s; skipping.",
		    name, dlpi_strerror(rc));
		return (B_TRUE);
	}

	rc = dlpi_info(dlh, &info, 0);
	if (rc != DLPI_SUCCESS) {
		DMSG(D_NET, "dlpi_info(%s) failed: %s; skipping.",
		    name, dlpi_strerror(rc));
		dlpi_close(dlh);
		return (B_TRUE);
	}

	keep = !!(info.di_mactype == DL_ETHER);
	DMSG(D_NET, "found link %s, mactype = %s (%d)%s.", name,
	    dlpi_mactype(info.di_mactype), info.di_mactype,
	    (keep) ? "" : "; discarding");

	dlpi_close(dlh);

	if (!keep)
		return (B_TRUE);

	VERIFY((link = link_alloc(name)) != NULL);
	list_insert_tail(&links, (void *)link);
	num_links++;
	if ((len = strlen(name)) > link_max_len)
		link_max_len = len;

	return (B_TRUE);
}
示例#4
0
文件: sigar.c 项目: couchbase/sigar
static void hwaddr_libdlpi_lookup(sigar_t *sigar, sigar_net_interface_config_t *ifconfig)
{
    dlpi_handle_t handle;
    dlpi_info_t linkinfo;
    uchar_t addr[DLPI_PHYSADDR_MAX];
    uint_t alen = sizeof(addr);

    if (dlpi_open(ifconfig->name, &handle, 0) != DLPI_SUCCESS) {
        return;
    }

    if (dlpi_get_physaddr(handle, DL_CURR_PHYS_ADDR, addr, &alen) == DLPI_SUCCESS &&
        dlpi_info(handle, &linkinfo, 0) == DLPI_SUCCESS) {
        if (alen < sizeof(ifconfig->hwaddr.addr.mac)) {
            sigar_net_address_mac_set(ifconfig->hwaddr, addr, alen);
            SIGAR_SSTRCPY(ifconfig->type, dlpi_mactype(linkinfo.di_mactype));
        }
    }

    dlpi_close(handle);
}
示例#5
0
文件: dladm.c 项目: andreiw/polaris
static int
get_if_info(const char *name, dladm_attr_t *dlattrp, boolean_t *legacy)
{
	int	err;

	if ((err = dladm_info(name, dlattrp)) == 0) {
		*legacy = B_FALSE;
	} else if (err < 0 && errno == ENODEV) {
		int		fd;
		dlpi_if_attr_t	dia;
		dl_info_ack_t	dlia;

		/*
		 * A return value of ENODEV means that the specified
		 * device is not gldv3.
		 */
		if ((fd = dlpi_if_open(name, &dia, B_FALSE)) != -1 &&
		    dlpi_info(fd, -1, &dlia, NULL, NULL, NULL, NULL,
		    NULL, NULL) != -1) {
			(void) dlpi_close(fd);

			*legacy = B_TRUE;
			bzero(dlattrp, sizeof (*dlattrp));
			dlattrp->da_max_sdu = (uint_t)dlia.dl_max_sdu;
		} else {
			errno = ENOENT;
			return (-1);
		}
	} else {
		/*
		 * If the return value is not ENODEV, this means that
		 * user is either passing in a bogus interface name
		 * or a vlan interface name that doesn't exist yet.
		 */
		errno = ENOENT;
		return (-1);
	}
	return (0);
}
示例#6
0
static int
pcap_activate_libdlpi(pcap_t *p)
{
	struct pcap_dlpi *pd = p->priv;
	int retv;
	dlpi_handle_t dh;
	dlpi_info_t dlinfo;
	int err = PCAP_ERROR;

	/*
	 * Enable Solaris raw and passive DLPI extensions;
	 * dlpi_open() will not fail if the underlying link does not support
	 * passive mode. See dlpi(7P) for details.
	 */
	retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
	if (retv != DLPI_SUCCESS) {
		if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
			err = PCAP_ERROR_NO_SUCH_DEVICE;
		else if (retv == DL_SYSERR &&
		    (errno == EPERM || errno == EACCES))
			err = PCAP_ERROR_PERM_DENIED;
		pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
		    p->errbuf);
		return (err);
	}
	pd->dlpi_hd = dh;

	if (p->opt.rfmon) {
		/*
		 * This device exists, but we don't support monitor mode
		 * any platforms that support DLPI.
		 */
		err = PCAP_ERROR_RFMON_NOTSUP;
		goto bad;
	}

	/* Bind with DLPI_ANY_SAP. */
	if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
		pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
		goto bad;
	}

	/* Enable promiscuous mode. */
	if (p->opt.promisc) {
		err = dlpromiscon(p, DL_PROMISC_PHYS);
		if (err < 0) {
			/*
			 * "You don't have permission to capture on
			 * this device" and "you don't have permission
			 * to capture in promiscuous mode on this
			 * device" are different; let the user know,
			 * so if they can't get permission to
			 * capture in promiscuous mode, they can at
			 * least try to capture in non-promiscuous
			 * mode.
			 *
			 * XXX - you might have to capture in
			 * promiscuous mode to see outgoing packets.
			 */
			if (err == PCAP_ERROR_PERM_DENIED)
				err = PCAP_ERROR_PROMISC_PERM_DENIED;
			goto bad;
		}
	} else {
		/* Try to enable multicast. */
		err = dlpromiscon(p, DL_PROMISC_MULTI);
		if (err < 0)
			goto bad;
	}

	/* Try to enable SAP promiscuity. */
	err = dlpromiscon(p, DL_PROMISC_SAP);
	if (err < 0) {
		/*
		 * Not fatal, since the DL_PROMISC_PHYS mode worked.
		 * Report it as a warning, however.
		 */
		if (p->opt.promisc)
			err = PCAP_WARNING;
		else
			goto bad;
	}

	/* Determine link type.  */
	if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
		pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
		goto bad;
	}

	if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
		goto bad;

	p->fd = dlpi_fd(pd->dlpi_hd);

	/* Push and configure bufmod. */
	if (pcap_conf_bufmod(p, p->snapshot) != 0)
		goto bad;

	/*
	 * Flush the read side.
	 */
	if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
		    pcap_strerror(errno));
		goto bad;
	}

	/* Allocate data buffer. */
	if (pcap_alloc_databuf(p) != 0)
		goto bad;

	/*
	 * "p->fd" is a FD for a STREAMS device, so "select()" and
	 * "poll()" should work on it.
	 */
	p->selectable_fd = p->fd;

	p->read_op = pcap_read_libdlpi;
	p->inject_op = pcap_inject_libdlpi;
	p->setfilter_op = install_bpf_program;	/* No kernel filtering */
	p->setdirection_op = NULL;	/* Not implemented */
	p->set_datalink_op = NULL;	/* Can't change data link type */
	p->getnonblock_op = pcap_getnonblock_fd;
	p->setnonblock_op = pcap_setnonblock_fd;
	p->stats_op = pcap_stats_dlpi;
	p->cleanup_op = pcap_cleanup_libdlpi;

	return (0);
bad:
	pcap_cleanup_libdlpi(p);
	return (err);
}
示例#7
0
static int
pcap_activate_libdlpi(pcap_t *p)
{
	int retv;
	dlpi_handle_t dh;
	dlpi_info_t dlinfo;
	int err = PCAP_ERROR;

	/*
	 * Enable Solaris raw and passive DLPI extensions;
	 * dlpi_open() will not fail if the underlying link does not support
	 * passive mode. See dlpi(7P) for details.
	 */
	retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
	if (retv != DLPI_SUCCESS) {
		if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
			err = PCAP_ERROR_NO_SUCH_DEVICE;
		else if (retv == DL_SYSERR && errno == EACCES)
			err = PCAP_ERROR_PERM_DENIED;
		pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
		    p->errbuf);
		return (err);
	}
	p->dlpi_hd = dh;

	if (p->opt.rfmon) {
		/*
		 * This device exists, but we don't support monitor mode
		 * any platforms that support DLPI.
		 */
		err = PCAP_ERROR_RFMON_NOTSUP;
		goto bad;
	}

	/* Bind with DLPI_ANY_SAP. */
	if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
		pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
		goto bad;
	}

	/* Enable promiscuous mode. */
	if (p->opt.promisc) {
		retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
		if (retv != DLPI_SUCCESS) {
			pcap_libdlpi_err(p->opt.source,
			    "dlpi_promisc(PHYSICAL)", retv, p->errbuf);
			goto bad;
		}
	} else {
		/* Try to enable multicast. */
		retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
		if (retv != DLPI_SUCCESS) {
			pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
			    retv, p->errbuf);
			goto bad;
		}
	}

	/* Try to enable SAP promiscuity. */
	retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP);
	if (retv != DLPI_SUCCESS) {
		if (p->opt.promisc) {
			pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
			    retv, p->errbuf);
			goto bad;
		}

		/* Not fatal, since the DL_PROMISC_PHYS mode worked. */
		fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
		    " %s:(%s)\n", p->opt.source, dlpi_strerror(retv));
	}

	/* Determine link type.  */
	if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
		pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
		goto bad;
	}

	if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
		goto bad;

	p->fd = dlpi_fd(p->dlpi_hd);

	/* Push and configure bufmod. */
	if (pcap_conf_bufmod(p, p->snapshot, p->md.timeout) != 0)
		goto bad;

	/*
	 * Flush the read side.
	 */
	if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
		    pcap_strerror(errno));
		goto bad;
	}

	/* Allocate data buffer. */
	if (pcap_alloc_databuf(p) != 0)
		goto bad;

	/*
	 * "p->fd" is a FD for a STREAMS device, so "select()" and
	 * "poll()" should work on it.
	 */
	p->selectable_fd = p->fd;

	p->read_op = pcap_read_libdlpi;
	p->inject_op = pcap_inject_libdlpi;
	p->setfilter_op = install_bpf_program;	/* No kernel filtering */
	p->setdirection_op = NULL;	/* Not implemented */
	p->set_datalink_op = NULL;	/* Can't change data link type */
	p->getnonblock_op = pcap_getnonblock_fd;
	p->setnonblock_op = pcap_setnonblock_fd;
	p->stats_op = pcap_stats_dlpi;
	p->cleanup_op = pcap_cleanup_libdlpi;

	return (0);
bad:
	pcap_cleanup_libdlpi(p);
	return (err);
}