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

📄 driver_wext.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd){	return drv->we_version_compiled > 18 &&		(cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE ||		 cmd == IWEVGENIE || cmd == IWEVCUSTOM);}static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res,					   struct wext_scan_data *data){	struct wpa_scan_res **tmp;	struct wpa_scan_res *r;	size_t extra_len;	u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL;	/* Figure out whether we need to fake any IEs */	pos = data->ie;	end = pos + data->ie_len;	while (pos && pos + 1 < end) {		if (pos + 2 + pos[1] > end)			break;		if (pos[0] == WLAN_EID_SSID)			ssid_ie = pos;		else if (pos[0] == WLAN_EID_SUPP_RATES)			rate_ie = pos;		else if (pos[0] == WLAN_EID_EXT_SUPP_RATES)			rate_ie = pos;		pos += 2 + pos[1];	}	extra_len = 0;	if (ssid_ie == NULL)		extra_len += 2 + data->ssid_len;	if (rate_ie == NULL && data->maxrate)		extra_len += 3;	r = os_zalloc(sizeof(*r) + extra_len + data->ie_len);	if (r == NULL)		return;	os_memcpy(r, &data->res, sizeof(*r));	r->ie_len = extra_len + data->ie_len;	pos = (u8 *) (r + 1);	if (ssid_ie == NULL) {		/*		 * Generate a fake SSID IE since the driver did not report		 * a full IE list.		 */		*pos++ = WLAN_EID_SSID;		*pos++ = data->ssid_len;		os_memcpy(pos, data->ssid, data->ssid_len);		pos += data->ssid_len;	}	if (rate_ie == NULL && data->maxrate) {		/*		 * Generate a fake Supported Rates IE since the driver did not		 * report a full IE list.		 */		*pos++ = WLAN_EID_SUPP_RATES;		*pos++ = 1;		*pos++ = data->maxrate;	}	if (data->ie)		os_memcpy(pos, data->ie, data->ie_len);	tmp = os_realloc(res->res,			 (res->num + 1) * sizeof(struct wpa_scan_res *));	if (tmp == NULL) {		os_free(r);		return;	}	tmp[res->num++] = r;	res->res = tmp;}				      /** * wpa_driver_wext_get_scan_results - Fetch the latest scan results * @priv: Pointer to private wext data from wpa_driver_wext_init() * Returns: Scan results on success, -1 on failure */struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv){	struct wpa_driver_wext_data *drv = priv;	size_t ap_num = 0, len;	int first;	u8 *res_buf;	struct iw_event iwe_buf, *iwe = &iwe_buf;	char *pos, *end, *custom;	struct wpa_scan_results *res;	struct wext_scan_data data;	res_buf = wpa_driver_wext_giwscan(drv, &len);	if (res_buf == NULL)		return NULL;	ap_num = 0;	first = 1;	res = os_zalloc(sizeof(*res));	if (res == NULL) {		os_free(res_buf);		return NULL;	}	pos = (char *) res_buf;	end = (char *) res_buf + len;	os_memset(&data, 0, sizeof(data));	while (pos + IW_EV_LCP_LEN <= end) {		/* Event data may be unaligned, so make a local, aligned copy		 * before processing. */		os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);		if (iwe->len <= IW_EV_LCP_LEN)			break;		custom = pos + IW_EV_POINT_LEN;		if (wext_19_iw_point(drv, iwe->cmd)) {			/* WE-19 removed the pointer from struct iw_point */			char *dpos = (char *) &iwe_buf.u.data.length;			int dlen = dpos - (char *) &iwe_buf;			os_memcpy(dpos, pos + IW_EV_LCP_LEN,				  sizeof(struct iw_event) - dlen);		} else {			os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));			custom += IW_EV_POINT_OFF;		}		switch (iwe->cmd) {		case SIOCGIWAP:			if (!first)				wpa_driver_wext_add_scan_entry(res, &data);			first = 0;			os_free(data.ie);			os_memset(&data, 0, sizeof(data));			os_memcpy(data.res.bssid,				  iwe->u.ap_addr.sa_data, ETH_ALEN);			break;		case SIOCGIWMODE:			wext_get_scan_mode(iwe, &data);			break;		case SIOCGIWESSID:			wext_get_scan_ssid(iwe, &data, custom, end);			break;		case SIOCGIWFREQ:			wext_get_scan_freq(iwe, &data);			break;		case IWEVQUAL:			wext_get_scan_qual(iwe, &data);			break;		case SIOCGIWENCODE:			wext_get_scan_encode(iwe, &data);			break;		case SIOCGIWRATE:			wext_get_scan_rate(iwe, &data, pos, end);			break;		case IWEVGENIE:			wext_get_scan_iwevgenie(iwe, &data, custom, end);			break;		case IWEVCUSTOM:			wext_get_scan_custom(iwe, &data, custom, end);			break;		}		pos += iwe->len;	}	os_free(res_buf);	res_buf = NULL;	if (!first)		wpa_driver_wext_add_scan_entry(res, &data);	os_free(data.ie);	wpa_printf(MSG_DEBUG, "Received %lu bytes of scan results (%lu BSSes)",		   (unsigned long) len, (unsigned long) res->num);	return res;}static int wpa_driver_wext_get_range(void *priv){	struct wpa_driver_wext_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;		if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)			drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "			   "flags 0x%x",			   drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);	} else {		wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "			   "assuming WPA is not supported");	}	os_free(range);	return 0;}static int wpa_driver_wext_set_wpa(void *priv, int enabled){	struct wpa_driver_wext_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	return wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED,					      enabled);}static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,				   const u8 *psk){	struct iw_encode_ext *ext;	struct iwreq iwr;	int ret;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))		return 0;	if (!psk)		return 0;	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	ext = os_zalloc(sizeof(*ext) + PMK_LEN);	if (ext == NULL)		return -1;	iwr.u.encoding.pointer = (caddr_t) ext;	iwr.u.encoding.length = sizeof(*ext) + PMK_LEN;	ext->key_len = PMK_LEN;	os_memcpy(&ext->key, psk, ext->key_len);	ext->alg = IW_ENCODE_ALG_PMK;	ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr);	if (ret < 0)		perror("ioctl[SIOCSIWENCODEEXT] PMK");	os_free(ext);	return ret;}static int wpa_driver_wext_set_key_ext(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_wext_data *drv = priv;	struct iwreq iwr;	int ret = 0;	struct iw_encode_ext *ext;	if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) {		wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu",			   __FUNCTION__, (unsigned long) seq_len);		return -1;	}	ext = os_zalloc(sizeof(*ext) + key_len);	if (ext == NULL)		return -1;	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	iwr.u.encoding.flags = key_idx + 1;	if (alg == WPA_ALG_NONE)		iwr.u.encoding.flags |= IW_ENCODE_DISABLED;	iwr.u.encoding.pointer = (caddr_t) ext;	iwr.u.encoding.length = sizeof(*ext) + key_len;	if (addr == NULL ||	    os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)		ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY;	if (set_tx)		ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY;	ext->addr.sa_family = ARPHRD_ETHER;	if (addr)		os_memcpy(ext->addr.sa_data, addr, ETH_ALEN);	else		os_memset(ext->addr.sa_data, 0xff, ETH_ALEN);	if (key && key_len) {		os_memcpy(ext + 1, key, key_len);		ext->key_len = key_len;	}	switch (alg) {	case WPA_ALG_NONE:		ext->alg = IW_ENCODE_ALG_NONE;		break;	case WPA_ALG_WEP:		ext->alg = IW_ENCODE_ALG_WEP;		break;	case WPA_ALG_TKIP:		ext->alg = IW_ENCODE_ALG_TKIP;		break;	case WPA_ALG_CCMP:		ext->alg = IW_ENCODE_ALG_CCMP;		break;	case WPA_ALG_PMK:		ext->alg = IW_ENCODE_ALG_PMK;		break;#ifdef WEXT_MFP_PENDING#ifdef CONFIG_IEEE80211W	case WPA_ALG_IGTK:		ext->alg = IW_ENCODE_ALG_AES_CMAC;		break;#endif /* CONFIG_IEEE80211W */#endif /* WEXT_MFP_PENDING */	default:		wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",			   __FUNCTION__, alg);		os_free(ext);		return -1;	}	if (seq && seq_len) {		ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID;		os_memcpy(ext->rx_seq, seq, seq_len);	}	if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) {		ret = errno == EOPNOTSUPP ? -2 : -1;		if (errno == ENODEV) {			/*			 * ndiswrapper seems to be returning incorrect error			 * code.. */			ret = -2;		}		perror("ioctl[SIOCSIWENCODEEXT]");	}	os_free(ext);	return ret;}/** * wpa_driver_wext_set_key - Configure encryption key * @priv: Pointer to private wext data from wpa_driver_wext_init() * @priv: Private driver interface data * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, *	%WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key. * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for *	broadcast/default keys * @key_idx: key index (0..3), usually 0 for unicast keys * @set_tx: Configure this key as the default Tx key (only used when *	driver does not support separate unicast/individual key * @seq: Sequence number/packet number, seq_len octets, the next *	packet number to be used for in replay protection; configured *	for Rx keys (in most cases, this is only used with broadcast *	keys and set to zero for unicast keys) * @seq_len: Length of the seq, depends on the algorithm: *	TKIP: 6 octets, CCMP: 6 octets * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, *	8-byte Rx Mic Key * @key_len: Length of the key buffer in octets (WEP: 5 or 13, *	TKIP: 32, CCMP: 16) * Returns: 0 on success, -1 on failure * * This function uses SIOCSIWENCODEEXT by default, but tries to use * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key. */int wpa_driver_wext_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_wext_data *drv = priv;	struct iwreq iwr;	int ret = 0;	wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "		   "key_len=%lu",		   __FUNCTION__, alg, key_idx, set_tx,		   (unsigned long) seq_len, (unsigned long) key_len);	ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx,					  seq, seq_len, key, key_len);	if (ret == 0)		return 0;	if (ret == -2 &&	    (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) {		wpa_printf(MSG_DEBUG, "Driver did not support "			   "SIOCSIWENCODEEXT, trying SIOCSIWENCODE");		ret = 0;	} else {		wpa_printf(MSG_DEBUG, "Driver did not support "			   "SIOCSIWENCODEEXT");		return ret;	}	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	iwr.u.encoding.flags = key_idx + 1;	if (alg == WPA_ALG_NONE)		iwr.u.encoding.flags |= IW_ENCODE_DISABLED;	iwr.u.encoding.pointer = (caddr_t) key;	iwr.u.encoding.length = key_len;	if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {		perror("ioctl[SIOCSIWENCODE]");		ret = -1;	}	if (set_tx && alg != WPA_ALG_NONE) {		os_memset(&iwr, 0, sizeof(iwr));		os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);		iwr.u.encoding.flags = key_idx + 1;		iwr.u.encoding.pointer = (caddr_t) NULL;		iwr.u.encoding.length = 0;		if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {			perror("ioctl[SIOCSIWENCODE] (set_tx)");			ret = -1;		}	}	return ret;}static int wpa_driver_wext_set_countermeasures(void *priv,					       int enabled){	struct wpa_driver_wext_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	return wpa_driver_wext_set_auth_param(drv,					      IW_AUTH_TKIP_COUNTERMEASURES,					      enabled);}static int wpa_driver_wext_set_drop_unencrypted(void *priv,						int enabled){	struct wpa_driver_wext_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	drv->use_crypt = enabled;	return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,					      enabled);}static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv,				const u8 *addr, int cmd, int reason_code){	struct iwreq iwr;	struct iw_mlme mlme;	int ret = 0;

⌨️ 快捷键说明

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