static int
bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params)
{
	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);

	if (!params->enabled) {
		/* XXX restore state */
		return set80211param(priv, IEEE80211_IOC_AUTHMODE,
				     IEEE80211_AUTH_AUTO);
	}
	if (!params->wpa && !params->ieee802_1x) {
		wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled",
			   __func__);
		return -1;
	}
	if (params->wpa && bsd_configure_wpa(priv, params) != 0) {
		wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state",
			   __func__);
		return -1;
	}
	if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
		(params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
		wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X",
			   __func__);
		return -1;
	}
	return bsd_ctrl_iface(priv, 1);
}
static void *
bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
{
	struct bsd_driver_data *drv;

	drv = os_zalloc(sizeof(struct bsd_driver_data));
	if (drv == NULL) {
		printf("Could not allocate memory for bsd driver data\n");
		goto bad;
	}

	drv->hapd = hapd;
	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		goto bad;
	}
	os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname));

	drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL,
					handle_read, drv, 0);
	if (drv->sock_xmit == NULL)
		goto bad;
	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
		goto bad;

	/* mark down during setup */
	if (bsd_ctrl_iface(drv, 0) < 0)
		goto bad;

	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
	if (drv->route < 0) {
		perror("socket(PF_ROUTE,SOCK_RAW)");
		goto bad;
	}
	eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv,
				 NULL);

	if (bsd_set_mediaopt(drv, IFM_OMASK, IFM_IEEE80211_HOSTAP) < 0) {
		wpa_printf(MSG_ERROR, "%s: failed to set operation mode",
			   __func__);
		goto bad;
	}

	return drv;
bad:
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	if (drv->sock >= 0)
		close(drv->sock);
	if (drv != NULL)
		os_free(drv);
	return NULL;
}
static void
bsd_deinit(void *priv)
{
	struct bsd_driver_data *drv = priv;

	if (drv->route >= 0) {
		eloop_unregister_read_sock(drv->route);
		close(drv->route);
	}
	bsd_ctrl_iface(drv, 0);
	if (drv->sock >= 0)
		close(drv->sock);
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	os_free(drv);
}
static void
wpa_driver_bsd_deinit(void *priv)
{
	struct bsd_driver_data *drv = priv;

	wpa_driver_bsd_set_wpa(drv, 0);
	eloop_unregister_read_sock(drv->route);

	/* NB: mark interface down */
	bsd_ctrl_iface(drv, 0);

	wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
	if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
		wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
			__func__);

	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	(void) close(drv->route);		/* ioctl socket */
	(void) close(drv->sock);		/* event socket */
	os_free(drv);
}
static void *
wpa_driver_bsd_init(void *ctx, const char *ifname)
{
#define	GETPARAM(drv, param, v) \
	(((v) = get80211param(drv, param)) != -1)
	struct bsd_driver_data *drv;

	drv = os_zalloc(sizeof(*drv));
	if (drv == NULL)
		return NULL;
	/*
	 * NB: We require the interface name be mappable to an index.
	 *     This implies we do not support having wpa_supplicant
	 *     wait for an interface to appear.  This seems ok; that
	 *     doesn't belong here; it's really the job of devd.
	 */
	drv->ifindex = if_nametoindex(ifname);
	if (drv->ifindex == 0) {
		wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
			   __func__, ifname);
		goto fail1;
	}
	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->sock < 0)
		goto fail1;
	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
	if (drv->route < 0)
		goto fail;
	eloop_register_read_sock(drv->route,
		wpa_driver_bsd_event_receive, ctx, drv);

	drv->ctx = ctx;
	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));

	/* Down interface during setup. */
	if (bsd_ctrl_iface(drv, 0) < 0)
		goto fail;

	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
		wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
			__func__, strerror(errno));
		goto fail;
	}
	if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) {
		wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s",
			__func__, strerror(errno));
		goto fail;
	}
	if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) {
		wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s",
			__func__, strerror(errno));
		goto fail;
	}

	if (wpa_driver_bsd_capa(drv))
		goto fail;

	return drv;
fail:
	close(drv->sock);
fail1:
	os_free(drv);
	return NULL;
#undef GETPARAM
}
static int
wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params)
{
	struct bsd_driver_data *drv = priv;
#ifdef IEEE80211_IOC_SCAN_MAX_SSID
	struct ieee80211_scan_req sr;
	int i;
#endif /* IEEE80211_IOC_SCAN_MAX_SSID */

	if (bsd_set_mediaopt(drv, IFM_OMASK, 0 /* STA */) < 0) {
		wpa_printf(MSG_ERROR, "%s: failed to set operation mode",
			   __func__);
		return -1;
	}

	if (set80211param(drv, IEEE80211_IOC_ROAMING,
			  IEEE80211_ROAMING_MANUAL) < 0) {
		wpa_printf(MSG_ERROR, "%s: failed to set "
			   "wpa_supplicant-based roaming: %s", __func__,
			   strerror(errno));
		return -1;
	}

	if (wpa_driver_bsd_set_wpa(drv, 1) < 0) {
		wpa_printf(MSG_ERROR, "%s: failed to set wpa: %s", __func__,
			   strerror(errno));
		return -1;
	}

	/* NB: interface must be marked UP to do a scan */
	if (bsd_ctrl_iface(drv, 1) < 0)
		return -1;

#ifdef IEEE80211_IOC_SCAN_MAX_SSID
	os_memset(&sr, 0, sizeof(sr));
	sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE |
		IEEE80211_IOC_SCAN_NOJOIN;
	sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
	if (params->num_ssids > 0) {
		sr.sr_nssid = params->num_ssids;
#if 0
		/* Boundary check is done by upper layer */
		if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID)
			sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID;
#endif

		/* NB: check scan cache first */
		sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK;
	}
	for (i = 0; i < sr.sr_nssid; i++) {
		sr.sr_ssid[i].len = params->ssids[i].ssid_len;
		os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid,
			  sr.sr_ssid[i].len);
	}

	/* NB: net80211 delivers a scan complete event so no need to poll */
	return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr));
#else /* IEEE80211_IOC_SCAN_MAX_SSID */
	/* set desired ssid before scan */
	if (bsd_set_ssid(drv, params->ssids[0].ssid,
			 params->ssids[0].ssid_len) < 0)
		return -1;

	/* NB: net80211 delivers a scan complete event so no need to poll */
	return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0);
#endif /* IEEE80211_IOC_SCAN_MAX_SSID */
}
Example #7
0
static int
bsd_commit(void *priv)
{
    return bsd_ctrl_iface(priv, 1);
}
Example #8
0
static void *
bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
{
	struct bsd_driver_data *drv;

	drv = os_zalloc(sizeof(struct bsd_driver_data));
	if (drv == NULL) {
		printf("Could not allocate memory for bsd driver data\n");
		goto bad;
	}

	drv->hapd = hapd;
	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		goto bad;
	}
	os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname));
	/*
	 * NB: We require the interface name be mappable to an index.
	 *     This implies we do not support having wpa_supplicant
	 *     wait for an interface to appear.  This seems ok; that
	 *     doesn't belong here; it's really the job of devd.
	 *     XXXSCW: devd is FreeBSD-specific.
	 */
	drv->ifindex = if_nametoindex(drv->ifname);
	if (drv->ifindex == 0) {
		printf("%s: interface %s does not exist", __func__,
		       drv->ifname);
		goto bad;
	}

	drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL,
					handle_read, drv, 0);
	if (drv->sock_xmit == NULL)
		goto bad;
	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
		goto bad;

	/* mark down during setup */
	if (bsd_ctrl_iface(drv, 0) < 0)
		goto bad;

	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
	if (drv->route < 0) {
		perror("socket(PF_ROUTE,SOCK_RAW)");
		goto bad;
	}
	eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv,
				 NULL);

	return drv;
bad:
	if (drv == NULL)
		return NULL;
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	if (drv->sock >= 0)
		close(drv->sock);
	os_free(drv);
	return NULL;
}