Пример #1
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);
	}
}
Пример #2
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;
 }
Пример #3
0
/*
 * This function is called when we are no longer interested in receiving
 * notification from state changes on a link.
 */
void
nwamd_dlpi_delete_link(nwamd_object_t obj)
{
	nwamd_ncu_t *ncu = obj->nwamd_object_data;

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

	if (ncu->ncu_link.nwamd_link_dlpi_thread != 0) {
		(void) pthread_cancel(
		    ncu->ncu_link.nwamd_link_dlpi_thread);
		(void) pthread_join(ncu->ncu_link.nwamd_link_dlpi_thread, NULL);
		ncu->ncu_link.nwamd_link_dlpi_thread = 0;

		/* Unset properties before closing. 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_delete_link(%s): skipping "
			    "wifi link properties de-initialization",
			    ncu->ncu_name);
		} else
			nwamd_set_unset_link_properties(ncu, B_FALSE);
	}

	dlpi_close(ncu->ncu_link.nwamd_link_dhp);
	ncu->ncu_link.nwamd_link_dhp = NULL;
}
Пример #4
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);
}
Пример #5
0
/*
 * Close dlpi handle.
 */
static void
pcap_cleanup_libdlpi(pcap_t *p)
{
	if (p->dlpi_hd != NULL) {
		dlpi_close(p->dlpi_hd);
		p->dlpi_hd = NULL;
		p->fd = -1;
	}
	pcap_cleanup_live_common(p);
}
Пример #6
0
/*
 * Close dlpi handle.
 */
static void
pcap_cleanup_libdlpi(pcap_t *p)
{
	struct pcap_dlpi *pd = p->priv;

	if (pd->dlpi_hd != NULL) {
		dlpi_close(pd->dlpi_hd);
		pd->dlpi_hd = NULL;
		p->fd = -1;
	}
	pcap_cleanup_live_common(p);
}
Пример #7
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);
}
Пример #8
0
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);
}
Пример #9
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);
}
Пример #10
0
int
dlpi_open(const char *linkname, dlpi_handle_t *dhp, uint_t flags)
{
	int		retval, on = 1;
	ifspec_t	ifsp;
	dlpi_impl_t  	*dip;

	/*
	 * Validate linkname, fail if logical unit number (lun) is specified,
	 * otherwise decompose the contents into ifsp.
	 */
	if (linkname == NULL || (strchr(linkname, ':') != NULL) ||
	    !ifparse_ifspec(linkname, &ifsp))
		return (DLPI_ELINKNAMEINVAL);

	/*
	 * Ensure flags values are sane.
	 */
	if ((flags & (DLPI_DEVIPNET|DLPI_DEVONLY)) ==
	    (DLPI_DEVIPNET|DLPI_DEVONLY))
		return (DLPI_EINVAL);

	/* Allocate a new dlpi_impl_t. */
	if ((dip = calloc(1, sizeof (dlpi_impl_t))) == NULL)
		return (DL_SYSERR);

	/* Fill in known/default libdlpi handle values. */
	dip->dli_timeout = DLPI_DEF_TIMEOUT;
	dip->dli_ppa = ifsp.ifsp_ppa;
	dip->dli_oflags = flags;
	dip->dli_notifylistp = NULL;
	dip->dli_note_processing = B_FALSE;
	if (getenv("DLPI_DEVONLY") != NULL)
		dip->dli_oflags |= DLPI_DEVONLY;

	/* Copy linkname provided to the function. */
	if (strlcpy(dip->dli_linkname, linkname, sizeof (dip->dli_linkname)) >=
	    sizeof (dip->dli_linkname)) {
		free(dip);
		return (DLPI_ELINKNAMEINVAL);
	}

	/* Copy provider name. */
	(void) strlcpy(dip->dli_provider, ifsp.ifsp_devnm,
	    sizeof (dip->dli_provider));

	/*
	 * Special case: DLPI_SERIAL flag is set to indicate a synchronous
	 * serial line interface (see syncinit(1M), syncstat(1M),
	 * syncloop(1M)), which is not a DLPI link.
	 */
	if (dip->dli_oflags & DLPI_SERIAL) {
		if ((retval = i_dlpi_style2_open(dip)) != DLPI_SUCCESS) {
			free(dip);
			return (retval);
		}

		*dhp = (dlpi_handle_t)dip;
		return (retval);
	}

	if ((retval = i_dlpi_style1_open(dip)) != DLPI_SUCCESS) {
		if (retval == DLPI_ENOTSTYLE2) {
			/*
			 * The error code indicates not to continue the
			 * style-2 open. Change the error code back to
			 * DL_SYSERR, so that one would know the cause
			 * of failure from errno.
			 */
			retval = DL_SYSERR;
		} else if (!(dip->dli_oflags & DLPI_DEVIPNET)) {
			retval = i_dlpi_style2_open(dip);
		}
		if (retval != DLPI_SUCCESS) {
			free(dip);
			return (retval);
		}
	}

	if (dip->dli_oflags & DLPI_PASSIVE)
		i_dlpi_passive(dip);

	if ((dip->dli_oflags & DLPI_RAW) &&
	    ioctl(dip->dli_fd, DLIOCRAW, 0) < 0) {
		dlpi_close((dlpi_handle_t)dip);
		return (DLPI_ERAWNOTSUP);
	}

	if ((dip->dli_oflags & DLPI_IPNETINFO) &&
	    ioctl(dip->dli_fd, DLIOCIPNETINFO, &on) < 0) {
		dlpi_close((dlpi_handle_t)dip);
		return (DLPI_EIPNETINFONOTSUP);
	}

	/*
	 * We intentionally do not care if this request fails, as this
	 * indicates the underlying DLPI device does not support Native mode
	 * (pre-GLDV3 device drivers).
	 */
	if (dip->dli_oflags & DLPI_NATIVE) {
		if ((retval = ioctl(dip->dli_fd, DLIOCNATIVE, 0)) > 0)
			dip->dli_mactype = retval;
	}

	*dhp = (dlpi_handle_t)dip;
	return (DLPI_SUCCESS);
}
Пример #11
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;
}