Exemplo n.º 1
0
 int readMacAddress(char *devName, u_char *buf, int bufLen) {
   // we can only call dlpi_open() with root privileges.  So only try to get
   // the MAC address if we are still root.  We could cache the dlpi handle
   // for each interface as another field in the adaptorNIO structure, but in
   // practice it seems unlikely that the MAC address will change without
   // a reboot of the host,  so it's OK to only read it at the start.  If a
   // new interface somehow appears then it will just be instantiated without
   // a MAC.
   if(getuid() != 0) {
     return NO;
   }
   
   int macaddrlen = DLPI_PHYSADDR_MAX;
   int copied = 0;
   char macaddr[DLPI_PHYSADDR_MAX];
   dlpi_handle_t dh;
   if (DLPI_SUCCESS != dlpi_open(devName, &dh, 0)) {
     myLog(LOG_ERR, "device %s dlpi_open failed : %s", devName, strerror(errno));
     return 0;
   }
   // opened OK
   if (DLPI_SUCCESS != dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, macaddr, &macaddrlen)) {
     myLog(LOG_ERR, "device %s dlpi_get_physaddr failed :%s", devName, strerror(errno));
   }
   if(macaddrlen <= bufLen) {
     memcpy(buf, macaddr, macaddrlen);
     copied = macaddrlen;
   }
   dlpi_close(dh);
   return copied;
 }
Exemplo n.º 2
0
/*
 * This is called when we want to start receiving notifications from state
 * changes on a link.
 */
void
nwamd_dlpi_add_link(nwamd_object_t obj)
{
	nwamd_ncu_t *ncu = obj->nwamd_object_data;
	nwamd_link_t *link;
	dlpi_notifyid_t id;
	int rc;

	nlog(LOG_DEBUG, "nwamd_dlpi_add_link: ncu %p (%s) type %d",
	    ncu, obj->nwamd_object_name, ncu != NULL ? ncu->ncu_type : -1);

	assert(ncu != NULL && ncu->ncu_type == NWAM_NCU_TYPE_LINK);

	link = &ncu->ncu_link;

	/* Already running? */
	if (link->nwamd_link_dlpi_thread != 0) {
		nlog(LOG_DEBUG, "nwamd_dlpi_add_link(%s) already running",
		    obj->nwamd_object_name);
		return;
	}

	rc = dlpi_open(ncu->ncu_name, &link->nwamd_link_dhp, 0);
	if (rc != DLPI_SUCCESS) {
		nlog(LOG_ERR, "nwamd_dlpi_add_link: dlpi_open(%s) = %s",
		    ncu->ncu_name, dlpi_strerror(rc));
		return;
	}

	/* Wifi links do not support setting/unsetting these properties */
	if (dladm_wlan_validate(dld_handle, ncu->ncu_link.nwamd_link_id,
	    NULL, NULL) == DLADM_STATUS_OK) {
		nlog(LOG_DEBUG, "nwamd_dlpi_add_link(%s): skipping "
		    "wifi link properties initialization", ncu->ncu_name);
	} else
		nwamd_set_unset_link_properties(ncu, B_TRUE);

	rc = dlpi_enabnotify(link->nwamd_link_dhp,
	    DL_NOTE_LINK_UP | DL_NOTE_LINK_DOWN, nwamd_dlpi_notify,
	    ncu->ncu_name, &id);
	if (rc != DLPI_SUCCESS) {
		nlog(LOG_ERR,
		    "nwamd_dlpi_add_link: dlpi_enabnotify(%s) = %s",
		    obj->nwamd_object_name, dlpi_strerror(rc));
		dlpi_close(link->nwamd_link_dhp);
		return;
	}

	rc = pthread_create(&link->nwamd_link_dlpi_thread, NULL,
	    nwamd_dlpi_thread, &link->nwamd_link_dhp);
	if (rc != 0) {
		nlog(LOG_ERR, "nwamd_dlpi_add_link: couldn't create "
		    "dlpi thread for %s: %s", obj->nwamd_object_name,
		    strerror(rc));
		dlpi_close(link->nwamd_link_dhp);
	}
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
int
main(int argc, char *argv[])
{
	struct wpa_supplicant wpa_s;
	char *link = NULL;
	char *key = NULL;
	dlpi_handle_t dh = NULL;
	datalink_id_t linkid;
	dladm_phys_attr_t dpa;
	int c;
	int exitcode;
	char door_file[WPA_STRSIZE];

	for (;;) {
		c = getopt(argc, argv, "Dk:hi:v");
		if (c < 0)
			break;
		switch (c) {
		case 'D':
			wpa_debug_level = MSG_DEBUG;
			break;
		case 'h':
			usage();
			return (-1);
		case 'i':
			link = optarg;
			break;
		case 'k':
			key = optarg;
			break;
		case 'v':
			(void) printf("%s\n", wpa_supplicant_version);
			return (-1);
		default:
			usage();
			return (-1);
		}
	}

	/*
	 * key name is required to retrieve PSK value through libwdladm APIs.
	 * key is saved by dladm command by keyname
	 * see dladm.
	 */
	if ((link == NULL) || (key == NULL)) {
		wpa_printf(MSG_ERROR, "\nLink & key is required.");
		return (-1);
	}

	if ((strlen(key) >= sizeof (wpa_s.kname)))  {
		wpa_printf(MSG_ERROR, "Too long key name '%s'.", key);
		return (-1);
	}

	if (daemon(0, 0))
		return (-1);

	/*
	 * Hold this link open to prevent a link renaming operation.
	 */
	if (dlpi_open(link, &dh, 0) != DLPI_SUCCESS) {
		wpa_printf(MSG_ERROR, "Failed to open link '%s'.", link);
		return (-1);
	}

	if (dladm_name2info(link, &linkid, NULL, NULL, NULL) !=
	    DLADM_STATUS_OK) {
		wpa_printf(MSG_ERROR, "Invalid link name '%s'.", link);
		dlpi_close(dh);
		return (-1);
	}

	/*
	 * Get the device name of the link, which will be used as the door
	 * file name used to communicate with the driver. Note that different
	 * links use different doors.
	 */
	if (dladm_phys_info(linkid, &dpa, DLADM_OPT_ACTIVE) !=
	    DLADM_STATUS_OK) {
		wpa_printf(MSG_ERROR,
		    "Failed to get device name of link '%s'.", link);
		dlpi_close(dh);
		return (-1);
	}
	(void) snprintf(door_file, WPA_STRSIZE, "%s_%s", WPA_DOOR, dpa.dp_dev);

	(void) memset(&wpa_s, 0, sizeof (wpa_s));
	wpa_s.driver = &wpa_driver_wifi_ops;
	wpa_s.linkid = linkid;
	(void) strlcpy(wpa_s.kname, key, sizeof (wpa_s.kname));
	eloop_init(&wpa_s);

	/*
	 * Setup default WPA/WPA2 configuration
	 * get ESSID and PSK value
	 */
	wpa_s.conf = wpa_config_read(&wpa_s);
	if (wpa_s.conf == NULL || wpa_s.conf->ssid == NULL) {
		wpa_printf(MSG_ERROR, "\nNo networks (SSID) configured.\n");
		exitcode = -1;
		goto cleanup;
	}

	exitcode = 0;

	/*
	 * Setup door file to communicate with driver
	 */
	if (wpa_supplicant_door_setup(&wpa_s, door_file) != 0) {
		wpa_printf(MSG_ERROR, "Failed to setup door(%s)", door_file);
		exitcode = -1;
		goto cleanup;
	}

	wpa_s.renew_snonce = 1;
	if (wpa_supplicant_driver_init(link, &wpa_s) < 0) {
		exitcode = -1;
		goto cleanup;
	}

	/*
	 * This link is hold again in wpa_supplicant_driver_init(), so that
	 * we release the first reference.
	 */
	dlpi_close(dh);
	dh = NULL;

	wpa_printf(MSG_DEBUG, "=> eloop_run");

	(void) eloop_register_signal(SIGINT, wpa_supplicant_terminate, NULL);
	(void) eloop_register_signal(SIGTERM, wpa_supplicant_terminate, NULL);
	(void) eloop_register_signal(SIGKILL, wpa_supplicant_terminate, NULL);

	eloop_run();

	wpa_printf(MSG_DEBUG, "<= eloop_run()");
	wpa_supplicant_disassociate(&wpa_s, REASON_DEAUTH_LEAVING);

	if (wpa_s.driver->set_wpa(wpa_s.linkid, 0) < 0) {
		wpa_printf(MSG_ERROR, "Failed to disable WPA in the driver.\n");
	}

cleanup:
	wpa_supplicant_door_destroy(door_file);
	wpa_supplicant_cleanup(&wpa_s);
	eloop_destroy();

	if (dh != NULL)
		dlpi_close(dh);

	return (exitcode);
}
Exemplo n.º 6
0
static int eth_get(const char *device, u8 ea[ETH_ALEN])
{
#ifdef __sun__
	dlpi_handle_t dh;
	u32 physaddrlen = DLPI_PHYSADDR_MAX;
	u8 physaddr[DLPI_PHYSADDR_MAX];
	int retval;

	retval = dlpi_open(device, &dh, 0);
	if (retval != DLPI_SUCCESS) {
		wpa_printf(MSG_ERROR, "dlpi_open error: %s",
			   dlpi_strerror(retval));
		return -1;
	}

	retval = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, physaddr,
				   &physaddrlen);
	if (retval != DLPI_SUCCESS) {
		wpa_printf(MSG_ERROR, "dlpi_get_physaddr error: %s",
			   dlpi_strerror(retval));
		dlpi_close(dh);
		return -1;
	}
	os_memcpy(ea, physaddr, ETH_ALEN);
	dlpi_close(dh);
#else /* __sun__ */
	struct if_msghdr *ifm;
	struct sockaddr_dl *sdl;
	u_char *p, *buf;
	size_t len;
	int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };

	if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
		return -1;
	if ((buf = os_malloc(len)) == NULL)
		return -1;
	if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
		os_free(buf);
		return -1;
	}
	for (p = buf; p < buf + len; p += ifm->ifm_msglen) {
		ifm = (struct if_msghdr *)p;
		sdl = (struct sockaddr_dl *)(ifm + 1);
		if (ifm->ifm_type != RTM_IFINFO ||
		    (ifm->ifm_addrs & RTA_IFP) == 0)
			continue;
		if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
		    os_memcmp(sdl->sdl_data, device, sdl->sdl_nlen) != 0)
			continue;
		os_memcpy(ea, LLADDR(sdl), sdl->sdl_alen);
		break;
	}
	os_free(buf);

	if (p >= buf + len) {
		errno = ESRCH;
		return -1;
	}
#endif /* __sun__ */
	return 0;
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
0
int
main(int argc, char *argv[])
{
	int c, ret;
	char *eptr;
	unsigned long sap;
	uint_t bind_sap;
	dlpi_handle_t dh;

	dlrecv_prog = basename(argv[0]);

	while ((c = getopt(argc, argv, ":s:")) != -1) {
		switch (c) {
		case 's':
			errno = 0;
			sap = strtoul(optarg, &eptr, 10);
			if (errno != 0 || sap == 0 || sap >= UINT16_MAX ||
			    *eptr != '\0') {
				dlrecv_usage("Invalid value for sap (-s): %s\n",
				    optarg);
				return (2);
			}
			dlrecv_sap = sap;
			break;
		case ':':
			dlrecv_usage("Option -%c requires an operand\n",
			    optopt);
			return (2);
		case '?':
			dlrecv_usage("Unknown option: -%c\n", optopt);
			return (2);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		dlrecv_usage("missing required operands\n");
		return (2);
	}

	if ((ret = dlpi_open(argv[0], &dh, 0)) != DLPI_SUCCESS) {
		warnx("failed to open %s: %s\n", argv[0],
		    dlpi_strerror(ret));
		exit(1);
	}

	if ((ret = dlpi_bind(dh, dlrecv_sap, &bind_sap)) != DLPI_SUCCESS) {
		warnx("failed to bind to sap 0x%x: %s\n", dlrecv_sap,
		    dlpi_strerror(ret));
		exit(1);
	}

	if (bind_sap != dlrecv_sap) {
		warnx("failed to bind to requested sap 0x%x, bound to "
		    "0x%x\n", dlrecv_sap, bind_sap);
		exit(1);
	}

	for (;;) {
		dlpi_recvinfo_t rinfo;
		dlsend_msg_t msg;
		size_t msglen;
		boolean_t invalid = B_FALSE;

		msglen = sizeof (msg);
		ret = dlpi_recv(dh, NULL, NULL, &msg, &msglen, -1, &rinfo);
		if (ret != DLPI_SUCCESS) {
			warnx("failed to receive data: %s\n",
			    dlpi_strerror(ret));
			continue;
		}

		if (msglen != rinfo.dri_totmsglen) {
			warnx("message truncated: expected %ld bytes, "
			    "got %ld\n", sizeof (dlsend_msg_t),
			    rinfo.dri_totmsglen);
			invalid = B_TRUE;
		}

		if (msglen != sizeof (msg)) {
			warnx("message too short: expected %ld bytes, "
			    "got %ld\n", sizeof (dlsend_msg_t),
			    msglen);
			invalid = B_TRUE;
		}

		if (!invalid) {
			invalid = !dlrecv_isvalid(&msg);
		}

		dlrecv_print(&msg, &rinfo, invalid);
	}

	/* LINTED: E_STMT_NOT_REACHED */
	return (0);
}
Exemplo n.º 9
0
int
main(int argc, char **argv)
{
	char cnambuf[DLPI_LINKNAME_MAX], device[DLPI_LINKNAME_MAX];
	struct scc_mode sm;
	struct strioctl sioc;
	int fd, speed;
	int retval;
	char *arg, *cp;
	char loopchange = 0;
	char echochange = 0;
	char clockchange = 0;
	uint_t ppa;
	dlpi_handle_t dh;

	if (argc == 1) {
		usage();
		exit(1);
	}
	argc--;
	argv++;

	if (strlcpy(cnambuf, argv[0], sizeof (cnambuf)) >=
	    sizeof (cnambuf)) {
		(void) fprintf(stderr,
		    "syncinit: invalid device name (too long) %s\n", argv[0]);
		exit(1);
	}

	cp = cnambuf;
	while (*cp)			/* find the end of the name */
		cp++;
	cp--;
	if (!isdigit(*cp)) {
		(void) fprintf(stderr,
		    "syncinit: %s missing minor device number\n", cnambuf);
		exit(1);
	}

	retval = dlpi_open(cnambuf, &dh, DLPI_EXCL|DLPI_SERIAL);
	if (retval != DLPI_SUCCESS) {
		(void) fprintf(stderr, "syncinit: dlpi_open %s: %s\n", cnambuf,
		    dlpi_strerror(retval));
		exit(1);
	}

	(void) dlpi_parselink(cnambuf, device, &ppa);
	(void) printf("device: %s  ppa: %u\n", device, ppa);

	fd = dlpi_fd(dh);

	argc--;
	argv++;
	if (argc) {	/* setting things */
		sioc.ic_cmd = S_IOCGETMODE;
		sioc.ic_timout = -1;
		sioc.ic_len = sizeof (struct scc_mode);
		sioc.ic_dp = (char *)&sm;

		if (ioctl(fd, I_STR, &sioc) < 0) {
			perror("S_IOCGETMODE");
			(void) fprintf(stderr,
				"syncinit: can't get sync mode info for %s\n",
				cnambuf);
			exit(1);
		}
		while (argc-- > 0) {
			arg = *argv++;
			if (sscanf(arg, "%d", &speed) == 1)
				sm.sm_baudrate = speed;
			else if (strchr(arg, '=')) {
				if (prefix(arg, "loop")) {
					if (lookup(yesno, arg))
						sm.sm_config |= CONN_LPBK;
					else
						sm.sm_config &= ~CONN_LPBK;
					loopchange++;
				} else if (prefix(arg, "echo")) {
					if (lookup(yesno, arg))
						sm.sm_config |= CONN_ECHO;
					else
						sm.sm_config &= ~CONN_ECHO;
					echochange++;
				} else if (prefix(arg, "nrzi")) {
					if (lookup(yesno, arg))
						sm.sm_config |= CONN_NRZI;
					else
						sm.sm_config &= ~CONN_NRZI;
				} else if (prefix(arg, "txc")) {
					sm.sm_txclock = lookup(txnames, arg);
					clockchange++;
				} else if (prefix(arg, "rxc")) {
					sm.sm_rxclock = lookup(rxnames, arg);
					clockchange++;
				} else if (prefix(arg, "speed")) {
					arg = strchr(arg, '=') + 1;
					if (sscanf(arg, "%d", &speed) == 1) {
						sm.sm_baudrate = speed;
					} else
						(void) fprintf(stderr,
						    "syncinit: %s %s\n",
						    "bad speed:", arg);
				}
			} else if (equal(arg, "external")) {
				sm.sm_txclock = TXC_IS_TXC;
				sm.sm_rxclock = RXC_IS_RXC;
				sm.sm_config &= ~CONN_LPBK;
			} else if (equal(arg, "sender")) {
				sm.sm_txclock = TXC_IS_BAUD;
				sm.sm_rxclock = RXC_IS_RXC;
				sm.sm_config &= ~CONN_LPBK;
			} else if (equal(arg, "internal")) {
				sm.sm_txclock = TXC_IS_PLL;
				sm.sm_rxclock = RXC_IS_PLL;
				sm.sm_config &= ~CONN_LPBK;
			} else if (equal(arg, "stop")) {
				sm.sm_baudrate = 0;
			} else
				(void) fprintf(stderr, "Bad arg: %s\n", arg);
		}

		/*
		 * If we're going to change the state of loopback, and we
		 * don't have our own plans for clock sources, use defaults.
		 */
		if (loopchange && !clockchange) {
			if (sm.sm_config & CONN_LPBK) {
				sm.sm_txclock = TXC_IS_BAUD;
				sm.sm_rxclock = RXC_IS_BAUD;
			} else {
				sm.sm_txclock = TXC_IS_TXC;
				sm.sm_rxclock = RXC_IS_RXC;
			}
		}
		sioc.ic_cmd = S_IOCSETMODE;
		sioc.ic_timout = -1;
		sioc.ic_len = sizeof (struct scc_mode);
		sioc.ic_dp = (char *)&sm;
		if (ioctl(fd, I_STR, &sioc) < 0) {
			perror("S_IOCSETMODE");
			(void) ioctl(fd, S_IOCGETMODE, &sm);
			(void) fprintf(stderr,
				"syncinit: ioctl failure code = %x\n",
				sm.sm_retval);
			exit(1);
		}
	}

	/* Report State */
	sioc.ic_cmd = S_IOCGETMODE;
	sioc.ic_timout = -1;
	sioc.ic_len = sizeof (struct scc_mode);
	sioc.ic_dp = (char *)&sm;
	if (ioctl(fd, I_STR, &sioc) < 0) {
		perror("S_IOCGETMODE");
		(void) fprintf(stderr,
			"syncinit: can't get sync mode info for %s\n",
			cnambuf);
		exit(1);
	}
	(void) printf(
		"speed=%d, loopback=%s, echo=%s, nrzi=%s, txc=%s, rxc=%s\n",
		sm.sm_baudrate,
		yesno[((int)(sm.sm_config & CONN_LPBK) > 0)],
		yesno[((int)(sm.sm_config & CONN_ECHO) > 0)],
		yesno[((int)(sm.sm_config & CONN_NRZI) > 0)],
		txnames[sm.sm_txclock],
		rxnames[sm.sm_rxclock]);
	return (0);
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
0
boolean_t
port_dlpi_open(const char *portname, struct portdata *port,
    datalink_class_t class)
{
	uchar_t addrbuf[DLPI_PHYSADDR_MAX];
	size_t alen = DLPI_PHYSADDR_MAX;
	int rc;
	char addrstr[ETHERADDRL * 3];

	/*
	 * We use DLPI 'raw' mode so that we get access to the received
	 * Ethernet 802 length field.  libdlpi otherwise eats this value.  Note
	 * that 'raw' mode support is required in order to use snoop, so it's
	 * expected to be common, even if it's not documented.
	 */
	rc = dlpi_open(portname, &port->dlpi, DLPI_RAW);
	if (rc != DLPI_SUCCESS) {
		syslog(LOG_ERR, "can't open %s: %s", portname,
		    dlpi_strerror(rc));
		return (B_FALSE);
	}

	port->phys_status = B_TRUE;
	port->sdu_failed = B_FALSE;
	port->bpdu_protect = B_FALSE;

	/*
	 * Now that the driver is open, we can get at least the initial value
	 * of the interface speed.  We need to do this before establishing the
	 * notify callback, so that it can update us later.
	 */