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

📄 driver_madwifi.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct madwifi_driver_data *drv = priv;	struct hostapd_data *hapd = drv->hapd;	struct ieee80211req_key wk;	u_int8_t cipher;	if (strcmp(alg, "none") == 0)		return madwifi_del_key(priv, addr, key_idx);	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,		"%s: alg=%s addr=%s key_idx=%d\n",		__func__, alg, ether_sprintf(addr), key_idx);	if (strcmp(alg, "WEP") == 0)		cipher = IEEE80211_CIPHER_WEP;	else if (strcmp(alg, "TKIP") == 0)		cipher = IEEE80211_CIPHER_TKIP;	else if (strcmp(alg, "CCMP") == 0)		cipher = IEEE80211_CIPHER_AES_CCM;	else {		printf("%s: unknown/unsupported algorithm %s\n",			__func__, alg);		return -1;	}	if (key_len > sizeof(wk.ik_keydata)) {		printf("%s: key length %lu too big\n", __func__,		       (unsigned long) key_len);		return -3;	}	memset(&wk, 0, sizeof(wk));	wk.ik_type = cipher;	wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;	if (addr == NULL) {		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);		wk.ik_keyix = key_idx;		wk.ik_flags |= IEEE80211_KEY_DEFAULT;	} else {		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);		wk.ik_keyix = IEEE80211_KEYIX_NONE;	}	wk.ik_keylen = key_len;	memcpy(wk.ik_keydata, key, key_len);	return set80211priv(priv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));}static intmadwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,		   u8 *seq){	struct madwifi_driver_data *drv = priv;	struct hostapd_data *hapd = drv->hapd;	struct ieee80211req_key wk;	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,		"%s: addr=%s idx=%d\n", __func__, ether_sprintf(addr), idx);	memset(&wk, 0, sizeof(wk));	if (addr == NULL)		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);	else		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);	wk.ik_keyix = idx;	if (set80211priv(priv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) {		printf("Failed to get encryption.\n");		return -1;	}#ifdef WORDS_BIGENDIAN	{		/*		 * wk.ik_keytsc is in host byte order (big endian), need to		 * swap it to match with the byte order used in WPA.		 */		int i;		u8 tmp[WPA_KEY_RSC_LEN];		memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));		for (i = 0; i < WPA_KEY_RSC_LEN; i++) {			seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];		}	}#else /* WORDS_BIGENDIAN */	memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));#endif /* WORDS_BIGENDIAN */	return 0;}static int madwifi_flush(void *priv){#ifdef MADWIFI_BSD	u8 allsta[IEEE80211_ADDR_LEN];	memset(allsta, 0xff, IEEE80211_ADDR_LEN);	return madwifi_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE);#else /* MADWIFI_BSD */	return 0;		/* XXX */#endif /* MADWIFI_BSD */}static intmadwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,			     const u8 *addr){	struct madwifi_driver_data *drv = priv;#ifdef MADWIFI_BSD	struct ieee80211req_sta_stats stats;	memset(data, 0, sizeof(*data));	/*	 * Fetch statistics for station from the system.	 */	memset(&stats, 0, sizeof(stats));	memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);	if (set80211priv(drv,#ifdef MADWIFI_NG			 IEEE80211_IOCTL_STA_STATS,#else /* MADWIFI_NG */			 IEEE80211_IOCTL_GETSTASTATS,#endif /* MADWIFI_NG */			 &stats, sizeof(stats))) {		if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {			memcpy(data, &drv->acct_data, sizeof(*data));			return 0;		}		printf("Failed to get station stats information element.\n");		return -1;	}	data->rx_packets = stats.is_stats.ns_rx_data;	data->rx_bytes = stats.is_stats.ns_rx_bytes;	data->tx_packets = stats.is_stats.ns_tx_data;	data->tx_bytes = stats.is_stats.ns_tx_bytes;	return 0;#else /* MADWIFI_BSD */	char buf[1024], line[128], *pos;	FILE *f;	unsigned long val;	memset(data, 0, sizeof(*data));	snprintf(buf, sizeof(buf), "/proc/net/madwifi/%s/" MACSTR,		 drv->iface, MAC2STR(addr));	f = fopen(buf, "r");	if (!f) {		if (memcmp(addr, drv->acct_mac, ETH_ALEN) != 0)			return -1;		memcpy(data, &drv->acct_data, sizeof(*data));		return 0;	}	/* Need to read proc file with in one piece, so use large enough	 * buffer. */	setbuffer(f, buf, sizeof(buf));	while (fgets(line, sizeof(line), f)) {		pos = strchr(line, '=');		if (!pos)			continue;		*pos++ = '\0';		val = strtoul(pos, NULL, 10);		if (strcmp(line, "rx_packets") == 0)			data->rx_packets = val;		else if (strcmp(line, "tx_packets") == 0)			data->tx_packets = val;		else if (strcmp(line, "rx_bytes") == 0)			data->rx_bytes = val;		else if (strcmp(line, "tx_bytes") == 0)			data->tx_bytes = val;	}	fclose(f);	return 0;#endif /* MADWIFI_BSD */}static intmadwifi_sta_clear_stats(void *priv, const u8 *addr){#if defined(MADWIFI_BSD) && defined(IEEE80211_MLME_CLEAR_STATS)	struct madwifi_driver_data *drv = priv;	struct hostapd_data *hapd = drv->hapd;	struct ieee80211req_mlme mlme;		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: addr=%s\n",		      __func__, ether_sprintf(addr));	mlme.im_op = IEEE80211_MLME_CLEAR_STATS;	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);	return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme,			    sizeof(mlme));#else /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */	return 0; /* FIX */#endif /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */}static intmadwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len){	/*	 * Do nothing; we setup parameters at startup that define the	 * contents of the beacon information element.	 */	return 0;}static intmadwifi_sta_deauth(void *priv, const u8 *addr, int reason_code){	struct madwifi_driver_data *drv = priv;	struct hostapd_data *hapd = drv->hapd;	struct ieee80211req_mlme mlme;	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,		"%s: addr=%s reason_code=%d\n",		__func__, ether_sprintf(addr), reason_code);	mlme.im_op = IEEE80211_MLME_DEAUTH;	mlme.im_reason = reason_code;	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);	return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));}static intmadwifi_sta_disassoc(void *priv, const u8 *addr, int reason_code){	struct madwifi_driver_data *drv = priv;	struct hostapd_data *hapd = drv->hapd;	struct ieee80211req_mlme mlme;	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,		"%s: addr=%s reason_code=%d\n",		__func__, ether_sprintf(addr), reason_code);	mlme.im_reason = reason_code;	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);	return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));}static intmadwifi_del_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]){	struct hostapd_data *hapd = drv->hapd;	struct sta_info *sta;	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,		HOSTAPD_LEVEL_INFO, "disassociated");	sta = ap_get_sta(hapd, addr);	if (sta != NULL) {		sta->flags &= ~WLAN_STA_ASSOC;		wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);		sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;		ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);		ap_free_sta(hapd, sta);	}	return 0;}static intmadwifi_process_wpa_ie(struct madwifi_driver_data *drv, struct sta_info *sta){	struct hostapd_data *hapd = drv->hapd;	struct ieee80211req_wpaie ie;	int ielen, res;	u8 *iebuf;	/*	 * Fetch negotiated WPA/RSN parameters from the system.	 */	memset(&ie, 0, sizeof(ie));	memcpy(ie.wpa_macaddr, sta->addr, IEEE80211_ADDR_LEN);	if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {		printf("Failed to get WPA/RSN information element.\n");		return -1;		/* XXX not right */	}	iebuf = ie.wpa_ie;#ifdef MADWIFI_NG	if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {		/* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not		 * set. This is needed for WPA2. */		iebuf = ie.rsn_ie;	}#endif /* MADWIFI_NG */	ielen = iebuf[1];	if (ielen == 0) {		printf("No WPA/RSN information element for station!?\n");		return -1;		/* XXX not right */	}	ielen += 2;	if (sta->wpa_sm == NULL)		sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr);	if (sta->wpa_sm == NULL) {		printf("Failed to initialize WPA state machine\n");		return -1;	}	res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,				  iebuf, ielen);	if (res != WPA_IE_OK) {		printf("WPA/RSN information element rejected? (res %u)\n", res);		return -1;	}	return 0;}static intmadwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]){	struct hostapd_data *hapd = drv->hapd;	struct sta_info *sta;	int new_assoc;	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,		HOSTAPD_LEVEL_INFO, "associated");	sta = ap_get_sta(hapd, addr);	if (sta) {		accounting_sta_stop(hapd, sta);	} else {		sta = ap_sta_add(hapd, addr);		if (sta == NULL)			return -1;	}	if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {		/* Cached accounting data is not valid anymore. */		memset(drv->acct_mac, 0, ETH_ALEN);		memset(&drv->acct_data, 0, sizeof(drv->acct_data));	}	accounting_sta_get_id(hapd, sta);	if (hapd->conf->wpa) {		if (madwifi_process_wpa_ie(drv, sta))			return -1;	}	/*	 * Now that the internal station state is setup	 * kick the authenticator into action.	 */	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;	sta->flags |= WLAN_STA_ASSOC;	wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);	hostapd_new_assoc_sta(hapd, sta, !new_assoc);	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);	return 0;}static voidmadwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,				       char *custom){	struct hostapd_data *hapd = drv->hapd;	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Custom wireless event: '%s'\n",		      custom);	if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {		char *pos;		u8 addr[ETH_ALEN];		pos = strstr(custom, "addr=");		if (pos == NULL) {			HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,				      "MLME-MICHAELMICFAILURE.indication "				      "without sender address ignored\n");			return;		}		pos += 5;		if (hwaddr_aton(pos, addr) == 0) {			ieee80211_michael_mic_failure(drv->hapd, addr, 1);		} else {			HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,				      "MLME-MICHAELMICFAILURE.indication "				      "with invalid MAC address");		}	} else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) {		char *key, *value;		u32 val;		key = custom;		while ((key = strchr(key, '\n')) != NULL) {			key++;			value = strchr(key, '=');			if (value == NULL)				continue;			*value++ = '\0';			val = strtoul(value, NULL, 10);			if (strcmp(key, "mac") == 0)				hwaddr_aton(value, drv->acct_mac);			else if (strcmp(key, "rx_packets") == 0)				drv->acct_data.rx_packets = val;			else if (strcmp(key, "tx_packets") == 0)				drv->acct_data.tx_packets = val;			else if (strcmp(key, "rx_bytes") == 0)				drv->acct_data.rx_bytes = val;			else if (strcmp(key, "tx_bytes") == 0)				drv->acct_data.tx_bytes = val;			key = value;		}	}}static voidmadwifi_wireless_event_wireless(struct madwifi_driver_data *drv,					    char *data, int len){	struct hostapd_data *hapd = drv->hapd;	struct iw_event iwe_buf, *iwe = &iwe_buf;	char *pos, *end, *custom, *buf;	pos = data;	end = data + len;	while (pos + IW_EV_LCP_LEN <= end) {		/* Event data may be unaligned, so make a local, aligned copy		 * before processing. */		memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);		HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, "Wireless event: "			      "cmd=0x%x len=%d\n", iwe->cmd, iwe->len);		if (iwe->len <= IW_EV_LCP_LEN)			return;		custom = pos + IW_EV_POINT_LEN;		if (drv->we_version > 18 &&		    (iwe->cmd == IWEVMICHAELMICFAILURE ||		     iwe->cmd == IWEVCUSTOM)) {			/* WE-19 removed the pointer from struct iw_point */			char *dpos = (char *) &iwe_buf.u.data.length;			int dlen = dpos - (char *) &iwe_buf;

⌨️ 快捷键说明

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