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

📄 driver_nl80211.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	iwr.u.data.pointer = (caddr_t) ie;	iwr.u.data.length = ie_len;	if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {		perror("ioctl[SIOCSIWGENIE]");		ret = -1;	}	return ret;}static int wpa_driver_nl80211_cipher2wext(int cipher){	switch (cipher) {	case CIPHER_NONE:		return IW_AUTH_CIPHER_NONE;	case CIPHER_WEP40:		return IW_AUTH_CIPHER_WEP40;	case CIPHER_TKIP:		return IW_AUTH_CIPHER_TKIP;	case CIPHER_CCMP:		return IW_AUTH_CIPHER_CCMP;	case CIPHER_WEP104:		return IW_AUTH_CIPHER_WEP104;	default:		return 0;	}}static int wpa_driver_nl80211_keymgmt2wext(int keymgmt){	switch (keymgmt) {	case KEY_MGMT_802_1X:	case KEY_MGMT_802_1X_NO_WPA:		return IW_AUTH_KEY_MGMT_802_1X;	case KEY_MGMT_PSK:		return IW_AUTH_KEY_MGMT_PSK;	default:		return 0;	}}static intwpa_driver_nl80211_auth_alg_fallback(struct wpa_driver_nl80211_data *drv,				  struct wpa_driver_associate_params *params){	struct iwreq iwr;	int ret = 0;	wpa_printf(MSG_DEBUG, "WEXT: Driver did not support "		   "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE");	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	/* Just changing mode, not actual keys */	iwr.u.encoding.flags = 0;	iwr.u.encoding.pointer = (caddr_t) NULL;	iwr.u.encoding.length = 0;	/*	 * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two	 * different things. Here they are used to indicate Open System vs.	 * Shared Key authentication algorithm. However, some drivers may use	 * them to select between open/restricted WEP encrypted (open = allow	 * both unencrypted and encrypted frames; restricted = only allow	 * encrypted frames).	 */	if (!drv->use_crypt) {		iwr.u.encoding.flags |= IW_ENCODE_DISABLED;	} else {		if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)			iwr.u.encoding.flags |= IW_ENCODE_OPEN;		if (params->auth_alg & AUTH_ALG_SHARED_KEY)			iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED;	}	if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {		perror("ioctl[SIOCSIWENCODE]");		ret = -1;	}	return ret;}static int wpa_driver_nl80211_associate(	void *priv, struct wpa_driver_associate_params *params){	struct wpa_driver_nl80211_data *drv = priv;	int ret = 0;	int allow_unencrypted_eapol;	int value;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	/*	 * If the driver did not support SIOCSIWAUTH, fallback to	 * SIOCSIWENCODE here.	 */	if (drv->auth_alg_fallback &&	    wpa_driver_nl80211_auth_alg_fallback(drv, params) < 0)		ret = -1;	if (!params->bssid &&	    wpa_driver_nl80211_set_bssid(drv, NULL) < 0)		ret = -1;	/* TODO: should consider getting wpa version and cipher/key_mgmt suites	 * from configuration, not from here, where only the selected suite is	 * available */	if (wpa_driver_nl80211_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len)	    < 0)		ret = -1;	if (params->wpa_ie == NULL || params->wpa_ie_len == 0)		value = IW_AUTH_WPA_VERSION_DISABLED;	else if (params->wpa_ie[0] == WLAN_EID_RSN)		value = IW_AUTH_WPA_VERSION_WPA2;	else		value = IW_AUTH_WPA_VERSION_WPA;	if (wpa_driver_nl80211_set_auth_param(drv,					   IW_AUTH_WPA_VERSION, value) < 0)		ret = -1;	value = wpa_driver_nl80211_cipher2wext(params->pairwise_suite);	if (wpa_driver_nl80211_set_auth_param(drv,					   IW_AUTH_CIPHER_PAIRWISE, value) < 0)		ret = -1;	value = wpa_driver_nl80211_cipher2wext(params->group_suite);	if (wpa_driver_nl80211_set_auth_param(drv,					   IW_AUTH_CIPHER_GROUP, value) < 0)		ret = -1;	value = wpa_driver_nl80211_keymgmt2wext(params->key_mgmt_suite);	if (wpa_driver_nl80211_set_auth_param(drv,					   IW_AUTH_KEY_MGMT, value) < 0)		ret = -1;	value = params->key_mgmt_suite != KEY_MGMT_NONE ||		params->pairwise_suite != CIPHER_NONE ||		params->group_suite != CIPHER_NONE ||		params->wpa_ie_len;	if (wpa_driver_nl80211_set_auth_param(drv,					   IW_AUTH_PRIVACY_INVOKED, value) < 0)		ret = -1;	/* Allow unencrypted EAPOL messages even if pairwise keys are set when	 * not using WPA. IEEE 802.1X specifies that these frames are not	 * encrypted, but WPA encrypts them when pairwise keys are in use. */	if (params->key_mgmt_suite == KEY_MGMT_802_1X ||	    params->key_mgmt_suite == KEY_MGMT_PSK)		allow_unencrypted_eapol = 0;	else		allow_unencrypted_eapol = 1;		if (wpa_driver_nl80211_set_auth_param(drv,					   IW_AUTH_RX_UNENCRYPTED_EAPOL,					   allow_unencrypted_eapol) < 0)		ret = -1;	if (params->freq && wpa_driver_nl80211_set_freq(drv, params->freq) < 0)		ret = -1;	if (wpa_driver_nl80211_set_ssid(drv, params->ssid, params->ssid_len) < 0)		ret = -1;	if (params->bssid &&	    wpa_driver_nl80211_set_bssid(drv, params->bssid) < 0)		ret = -1;	return ret;}static int wpa_driver_nl80211_set_auth_alg(void *priv, int auth_alg){	struct wpa_driver_nl80211_data *drv = priv;	int algs = 0, res;	if (auth_alg & AUTH_ALG_OPEN_SYSTEM)		algs |= IW_AUTH_ALG_OPEN_SYSTEM;	if (auth_alg & AUTH_ALG_SHARED_KEY)		algs |= IW_AUTH_ALG_SHARED_KEY;	if (auth_alg & AUTH_ALG_LEAP)		algs |= IW_AUTH_ALG_LEAP;	if (algs == 0) {		/* at least one algorithm should be set */		algs = IW_AUTH_ALG_OPEN_SYSTEM;	}	res = wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG,					     algs);	drv->auth_alg_fallback = res == -2;	return res;}/** * wpa_driver_nl80211_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE * @priv: Pointer to private wext data from wpa_driver_nl80211_init() * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS * Returns: 0 on success, -1 on failure */static int wpa_driver_nl80211_set_mode(void *priv, int mode){	struct wpa_driver_nl80211_data *drv = priv;	int ret = -1, flags;	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!msg)		return -1;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_SET_INTERFACE, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE,		    mode ? NL80211_IFTYPE_ADHOC : NL80211_IFTYPE_STATION);	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	if (!ret)		return 0;	else		goto try_again;nla_put_failure:	wpa_printf(MSG_ERROR, "nl80211: Failed to set interface mode");	return -1;try_again:	/* mac80211 doesn't allow mode changes while the device is up, so	 * take the device down, try to set the mode again, and bring the	 * device back up.	 */	if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0) {		(void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);		/* Try to set the mode again while the interface is down */		msg = nlmsg_alloc();		if (!msg)			return -1;		genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,			    0, NL80211_CMD_SET_INTERFACE, 0);		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);		NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE,			    mode ? NL80211_IFTYPE_ADHOC :			    NL80211_IFTYPE_STATION);		ret = send_and_recv_msgs(drv, msg, NULL, NULL);		if (ret) {			wpa_printf(MSG_ERROR, "Failed to set interface %s "				   "mode", drv->ifname);		}		/* Ignore return value of get_ifflags to ensure that the device		 * is always up like it was before this function was called.		 */		(void) wpa_driver_nl80211_get_ifflags(drv, &flags);		(void) wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP);	}	return ret;}static int wpa_driver_nl80211_pmksa(struct wpa_driver_nl80211_data *drv,				 u32 cmd, const u8 *bssid, const u8 *pmkid){	struct iwreq iwr;	struct iw_pmksa pmksa;	int ret = 0;	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	os_memset(&pmksa, 0, sizeof(pmksa));	pmksa.cmd = cmd;	pmksa.bssid.sa_family = ARPHRD_ETHER;	if (bssid)		os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN);	if (pmkid)		os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN);	iwr.u.data.pointer = (caddr_t) &pmksa;	iwr.u.data.length = sizeof(pmksa);	if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {		if (errno != EOPNOTSUPP)			perror("ioctl[SIOCSIWPMKSA]");		ret = -1;	}	return ret;}static int wpa_driver_nl80211_add_pmkid(void *priv, const u8 *bssid,				     const u8 *pmkid){	struct wpa_driver_nl80211_data *drv = priv;	return wpa_driver_nl80211_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);}static int wpa_driver_nl80211_remove_pmkid(void *priv, const u8 *bssid,		 			const u8 *pmkid){	struct wpa_driver_nl80211_data *drv = priv;	return wpa_driver_nl80211_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);}static int wpa_driver_nl80211_flush_pmkid(void *priv){	struct wpa_driver_nl80211_data *drv = priv;	return wpa_driver_nl80211_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL);}static int wpa_driver_nl80211_get_capa(void *priv,				       struct wpa_driver_capa *capa){	struct wpa_driver_nl80211_data *drv = priv;	if (!drv->has_capability)		return -1;	os_memcpy(capa, &drv->capa, sizeof(*capa));	return 0;}static int wpa_driver_nl80211_set_operstate(void *priv, int state){	struct wpa_driver_nl80211_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",		   __func__, drv->operstate, state, state ? "UP" : "DORMANT");	drv->operstate = state;	return wpa_driver_nl80211_send_oper_ifla(		drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT);}#ifdef CONFIG_CLIENT_MLMEstatic int wpa_driver_nl80211_open_mlme(struct wpa_driver_nl80211_data *drv){	if (wpa_driver_nl80211_set_userspace_mlme(drv, 1) < 0) {		wpa_printf(MSG_ERROR, "nl80211: Failed to enable userspace "			   "MLME");		return -1;	}	if (wpa_driver_nl80211_create_monitor_interface(drv)) {		wpa_printf(MSG_ERROR, "nl80211: Failed to create monitor "			   "interface");		return -1;	}	return 0;}#endif /* CONFIG_CLIENT_MLME */static int wpa_driver_nl80211_set_param(void *priv, const char *param){#ifdef CONFIG_CLIENT_MLME	struct wpa_driver_nl80211_data *drv = priv;	if (param == NULL)		return 0;	wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);	if (os_strstr(param, "use_mlme=1")) {		wpa_printf(MSG_DEBUG, "nl80211: Using user space MLME");		drv->capa.flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;		if (wpa_driver_nl80211_open_mlme(drv))			return -1;	}#endif /* CONFIG_CLIENT_MLME */	return 0;}#ifdef CONFIG_CLIENT_MLMEstruct phy_info_arg {	u16 *num_modes;	struct wpa_hw_modes *modes;};static int phy_info_handler(struct nl_msg *msg, void *arg){	struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));	struct phy_info_arg *phy_info = arg;	struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];	struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];	static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1]		= {		[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },		[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },		[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },		[NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },		[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },	};	struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];	static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {		[NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },		[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =		{ .type = NLA_FLAG },	};	struct nlattr *nl_band;	struct nlattr *nl_freq;	struct nlattr *nl_rate;	int rem_band, rem_freq, rem_rate;	struct wpa_hw_modes *mode;	int idx, mode_is_set;	nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),		  genlmsg_attrlen(gnlh, 0), NULL);	if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])		return NL_SKIP;	nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS],			    rem_band) {		mode = os_realloc(phy_info->modes,				  (*phy_info->num_modes + 1) * sizeof(*mode));		if (!mode)			return NL_SKIP;		phy_info->modes = mode;		mode_is_set = 0;		mode = &phy_info->modes[*(phy_info->num_modes)];		os_memset(mode, 0, sizeof(*mode));		*(phy_info->num_modes) += 1;		nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),			  nla_len(nl_band), NULL);		nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS],				    rem_freq) {			nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,				  nla_data(nl_freq), nla_len(nl_freq),				  freq_policy);			if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])				continue;			mode->num_channels++;		}		mode->channels = os_zalloc(mode->num_channels *					   sizeof(struct wpa_channel_data));		if (!mode->channels)			return NL_SKIP;		idx = 0;		nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS],				    rem_freq) {			nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,				  nla_data(nl_freq), nla_len(nl_freq),				  freq_policy);			if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])				continue;			mode->channels[idx].freq = nla_get_u32(				tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);			mode->channels[idx].flag |= WPA_CHAN_W_SCAN |				WPA_CHAN_W_ACTIVE_SCAN |				WPA_CHAN_W_IBSS;			if (!mode_is_set) {				/* crude heuristic */				if (mode->channels[idx].freq < 4000)					mode->mode = WPA_MODE_IEEE80211B;				else					mode->mode = WPA_MODE_IEEE80211A;				mode_is_set = 1;			}			/* crude heuristic */			if (mode->channels[idx].freq < 4000) {				if (mode->channels[idx].freq == 2848)					mode->channels[idx].chan = 14;				else					mode->channels[idx].chan =						(mode->channels[idx].freq -						 2407) / 5;			} else				mode->channels[idx].chan =					mode->channels[idx].freq / 5 - 1000;			if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])				mode->channels[idx].flag &= ~WPA_CHAN_W_SCAN;			if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])				mode->channels[idx].flag &=					~WPA_CHAN_W_ACTIVE_SCAN;			if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])				mode->channels[idx].flag &= ~WP

⌨️ 快捷键说明

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