⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver_nl80211.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	else if (!(flags & IFF_UP)) {		if (wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP) != 0) {			printf("Could not set interface '%s' UP\n",			       drv->ifname);		}	}	/*	 * Make sure that the driver does not have any obsolete PMKID entries.	 */	wpa_driver_nl80211_flush_pmkid(drv);	if (wpa_driver_nl80211_set_mode(drv, 0) < 0) {		printf("Could not configure driver to use managed mode\n");	}	wpa_driver_nl80211_get_range(drv);	drv->ifindex = if_nametoindex(drv->ifname);	wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);}/** * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init() * * Shut down driver interface and processing of driver events. Free * private data buffer if one was allocated in wpa_driver_nl80211_init(). */static void wpa_driver_nl80211_deinit(void *priv){	struct wpa_driver_nl80211_data *drv = priv;	int flags;#ifdef CONFIG_CLIENT_MLME	if (drv->monitor_sock >= 0) {		eloop_unregister_read_sock(drv->monitor_sock);		close(drv->monitor_sock);	}	if (drv->monitor_ifidx > 0)		nl80211_remove_iface(drv, drv->monitor_ifidx);	if (drv->capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)		wpa_driver_nl80211_set_userspace_mlme(drv, 0);#endif /* CONFIG_CLIENT_MLME */	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);	/*	 * Clear possibly configured driver parameters in order to make it	 * easier to use the driver after wpa_supplicant has been terminated.	 */	(void) wpa_driver_nl80211_set_bssid(drv,					 (u8 *) "\x00\x00\x00\x00\x00\x00");	wpa_driver_nl80211_send_oper_ifla(priv, 0, IF_OPER_UP);	eloop_unregister_read_sock(drv->wext_event_sock);	if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0)		(void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);	close(drv->wext_event_sock);	close(drv->ioctl_sock);	os_free(drv->assoc_req_ies);	os_free(drv->assoc_resp_ies);	eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle));	genl_family_put(drv->nl80211);	nl_cache_free(drv->nl_cache);	nl_handle_destroy(drv->nl_handle);	nl_cb_put(drv->nl_cb);	os_free(drv);}/** * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion * @eloop_ctx: Unused * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init() * * This function can be used as registered timeout when starting a scan to * generate a scan completed event if the driver does not report this. */static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx){	wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");	wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);}/** * wpa_driver_nl80211_scan - Request the driver to initiate scan * @priv: Pointer to private wext data from wpa_driver_nl80211_init() * @ssid: Specific SSID to scan for (ProbeReq) or %NULL to scan for *	all SSIDs (either active scan with broadcast SSID or passive *	scan * @ssid_len: Length of the SSID * Returns: 0 on success, -1 on failure */static int wpa_driver_nl80211_scan(void *priv, const u8 *ssid, size_t ssid_len){	struct wpa_driver_nl80211_data *drv = priv;	int ret = 0, timeout;	struct nl_msg *msg, *ssids;	msg = nlmsg_alloc();	ssids = nlmsg_alloc();	if (!msg || !ssids) {		nlmsg_free(msg);		nlmsg_free(ssids);		return -1;	}	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,		    NL80211_CMD_TRIGGER_SCAN, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);	if (ssid && ssid_len) {		/* Request an active scan for a specific SSID */		NLA_PUT(ssids, 1, ssid_len, ssid);	} else {		/* Request an active scan for wildcard SSID */		NLA_PUT(ssids, 1, 0, "");	}	nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	msg = NULL;	if (ret) {		wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "			   "(%s)", ret, strerror(-ret));		goto nla_put_failure;	}	/* Not all drivers generate "scan completed" wireless event, so try to	 * read results after a timeout. */	timeout = 10;	if (drv->scan_complete_events) {		/*		 * The driver seems to deliver SIOCGIWSCAN events to notify		 * when scan is complete, so use longer timeout to avoid race		 * conditions with scanning and following association request.		 */		timeout = 30;	}	wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "		   "seconds", ret, timeout);	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);	eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,			       drv, drv->ctx);nla_put_failure:	nlmsg_free(ssids);	nlmsg_free(msg);	return ret;}static int bss_info_handler(struct nl_msg *msg, void *arg){	struct nlattr *tb[NL80211_ATTR_MAX + 1];	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));	struct nlattr *bss[NL80211_BSS_MAX + 1];	static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {		[NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },		[NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },		[NL80211_BSS_TSF] = { .type = NLA_U64 },		[NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },		[NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },		[NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },		[NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },		[NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },	};	struct wpa_scan_results *res = arg;	struct wpa_scan_res **tmp;	struct wpa_scan_res *r;	const u8 *ie;	size_t ie_len;	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),		  genlmsg_attrlen(gnlh, 0), NULL);	if (!tb[NL80211_ATTR_BSS])		return NL_SKIP;	if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],			     bss_policy))		return NL_SKIP;	if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {		ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);		ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);	} else {		ie = NULL;		ie_len = 0;	}	r = os_zalloc(sizeof(*r) + ie_len);	if (r == NULL)		return NL_SKIP;	if (bss[NL80211_BSS_BSSID])		os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),			  ETH_ALEN);	if (bss[NL80211_BSS_FREQUENCY])		r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);	if (bss[NL80211_BSS_BEACON_INTERVAL])		r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);	if (bss[NL80211_BSS_CAPABILITY])		r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);	if (bss[NL80211_BSS_SIGNAL_UNSPEC])		r->qual = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);	if (bss[NL80211_BSS_SIGNAL_MBM])		r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);	if (bss[NL80211_BSS_TSF])		r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);	r->ie_len = ie_len;	if (ie)		os_memcpy(r + 1, ie, ie_len);	tmp = os_realloc(res->res,			 (res->num + 1) * sizeof(struct wpa_scan_res *));	if (tmp == NULL) {		os_free(r);		return NL_SKIP;	}	tmp[res->num++] = r;	res->res = tmp;	return NL_SKIP;}/** * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results * @priv: Pointer to private wext data from wpa_driver_nl80211_init() * Returns: Scan results on success, -1 on failure */static struct wpa_scan_results *wpa_driver_nl80211_get_scan_results(void *priv){	struct wpa_driver_nl80211_data *drv = priv;	struct nl_msg *msg;	struct wpa_scan_results *res;	int ret;	res = os_zalloc(sizeof(*res));	if (res == NULL)		return 0;	msg = nlmsg_alloc();	if (!msg)		goto nla_put_failure;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP,		    NL80211_CMD_GET_SCAN, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);	ret = send_and_recv_msgs(drv, msg, bss_info_handler, res);	msg = NULL;	if (ret == 0) {		wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)",			   (unsigned long) res->num);		return res;	}	wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "		   "(%s)", ret, strerror(-ret));nla_put_failure:	nlmsg_free(msg);	wpa_scan_results_free(res);	return NULL;}static int wpa_driver_nl80211_get_range(void *priv){	struct wpa_driver_nl80211_data *drv = priv;	struct iw_range *range;	struct iwreq iwr;	int minlen;	size_t buflen;	/*	 * Use larger buffer than struct iw_range in order to allow the	 * structure to grow in the future.	 */	buflen = sizeof(struct iw_range) + 500;	range = os_zalloc(buflen);	if (range == NULL)		return -1;	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	iwr.u.data.pointer = (caddr_t) range;	iwr.u.data.length = buflen;	minlen = ((char *) &range->enc_capa) - (char *) range +		sizeof(range->enc_capa);	if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {		perror("ioctl[SIOCGIWRANGE]");		os_free(range);		return -1;	} else if (iwr.u.data.length >= minlen &&		   range->we_version_compiled >= 18) {		wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "			   "WE(source)=%d enc_capa=0x%x",			   range->we_version_compiled,			   range->we_version_source,			   range->enc_capa);		drv->has_capability = 1;		drv->we_version_compiled = range->we_version_compiled;		if (range->enc_capa & IW_ENC_CAPA_WPA) {			drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |				WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;		}		if (range->enc_capa & IW_ENC_CAPA_WPA2) {			drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |				WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;		}		drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |			WPA_DRIVER_CAPA_ENC_WEP104;		if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;		if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x",			   drv->capa.key_mgmt, drv->capa.enc);	} else {		wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "			   "assuming WPA is not supported");	}	os_free(range);	return 0;}static int wpa_driver_nl80211_set_wpa(void *priv, int enabled){	struct wpa_driver_nl80211_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	return wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_WPA_ENABLED,					      enabled);}static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg,				      const u8 *addr, int key_idx,				      int set_tx, const u8 *seq,				      size_t seq_len,				      const u8 *key, size_t key_len){	struct wpa_driver_nl80211_data *drv = priv;	int err;	struct nl_msg *msg;	wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "		   "seq_len=%lu key_len=%lu",		   __func__, alg, addr, key_idx, set_tx,		   (unsigned long) seq_len, (unsigned long) key_len);	msg = nlmsg_alloc();	if (msg == NULL)		return -1;	if (alg == WPA_ALG_NONE) {		genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,			    NL80211_CMD_DEL_KEY, 0);	} else {		genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,			    NL80211_CMD_NEW_KEY, 0);		NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);		switch (alg) {		case WPA_ALG_WEP:			if (key_len == 5)				NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,					    0x000FAC01);			else				NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,					    0x000FAC05);			break;		case WPA_ALG_TKIP:			NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02);			break;		case WPA_ALG_CCMP:			NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);			break;		default:			nlmsg_free(msg);			return -1;		}	}	if (addr && os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)	{		wpa_printf(MSG_DEBUG, "   addr=" MACSTR, MAC2STR(addr));		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);	}	NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);	err = send_and_recv_msgs(drv, msg, NULL, NULL);	if (err) {		wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d", err);		return -1;	}	if (set_tx && alg != WPA_ALG_NONE) {		msg = nlmsg_alloc();		if (msg == NULL)			return -1;		genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,			    0, NL80211_CMD_SET_KEY, 0);		NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);		NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);		err = send_and_recv_msgs(drv, msg, NULL, NULL);		if (err) {			wpa_printf(MSG_DEBUG, "nl80211: set default key "				   "failed; err=%d", err);			return -1;		}	}	return 0;nla_put_failure:	return -ENOBUFS;}static int wpa_driver_nl80211_set_countermeasures(void *priv,					       int enabled){	struct wpa_driver_nl80211_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	return wpa_driver_nl80211_set_auth_param(drv,					      IW_AUTH_TKIP_COUNTERMEASURES,					      enabled);}static int wpa_driver_nl80211_set_drop_unencrypted(void *priv,						int enabled){	struct wpa_driver_nl80211_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	drv->use_crypt = enabled;	return wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,					      enabled);}static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,				const u8 *addr, int cmd, int reason_code){	struct iwreq iwr;	struct iw_mlme mlme;	int ret = 0;	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	os_memset(&mlme, 0, sizeof(mlme));	mlme.cmd = cmd;	mlme.reason_code = reason_code;	mlme.addr.sa_family = ARPHRD_ETHER;	os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN);	iwr.u.data.pointer = (caddr_t) &mlme;	iwr.u.data.length = sizeof(mlme);	if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {		perror("ioctl[SIOCSIWMLME]");		ret = -1;	}	return ret;}static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,					  int reason_code){	struct wpa_driver_nl80211_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	return wpa_driver_nl80211_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);}static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,					int reason_code){	struct wpa_driver_nl80211_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	return wpa_driver_nl80211_mlme(drv, addr, IW_MLME_DISASSOC,				    reason_code);}static int wpa_driver_nl80211_set_gen_ie(void *priv, const u8 *ie,				      size_t ie_len){	struct wpa_driver_nl80211_data *drv = priv;	struct iwreq iwr;	int ret = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -