nl80211: Replace hostapd WEXT events with nl80211 events
This shares the nl80211 event processing with wpa_supplicant and removes the old WEXT code from driver_nl80211.c.
This commit is contained in:
		
							parent
							
								
									35583f3fa6
								
							
						
					
					
						commit
						5b7b85f669
					
				
					 1 changed files with 46 additions and 266 deletions
				
			
		|  | @ -119,7 +119,6 @@ struct wpa_driver_nl80211_data { | ||||||
| #ifdef HOSTAPD | #ifdef HOSTAPD | ||||||
| 	struct hostapd_data *hapd; | 	struct hostapd_data *hapd; | ||||||
| 
 | 
 | ||||||
| 	int wext_sock; /* socket for wireless events */ |  | ||||||
| 	int eapol_sock; /* socket for EAPOL frames */ | 	int eapol_sock; /* socket for EAPOL frames */ | ||||||
| 	int monitor_sock; /* socket for monitor */ | 	int monitor_sock; /* socket for monitor */ | ||||||
| 	int monitor_ifidx; | 	int monitor_ifidx; | ||||||
|  | @ -128,7 +127,6 @@ struct wpa_driver_nl80211_data { | ||||||
| 	int *if_indices; | 	int *if_indices; | ||||||
| 	int num_if_indices; | 	int num_if_indices; | ||||||
| 
 | 
 | ||||||
| 	int we_version; |  | ||||||
| 	int beacon_int; | 	int beacon_int; | ||||||
| 	struct i802_bss bss; | 	struct i802_bss bss; | ||||||
| 	unsigned int ht_40mhz_scan:1; | 	unsigned int ht_40mhz_scan:1; | ||||||
|  | @ -154,10 +152,6 @@ static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, | ||||||
| #endif /* CONFIG_AP */ | #endif /* CONFIG_AP */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifdef HOSTAPD |  | ||||||
| #define wpa_supplicant_event(c, e, d) do { } while (0) |  | ||||||
| #endif /* HOSTAPD */ |  | ||||||
| 
 |  | ||||||
| /* nl80211 code */ | /* nl80211 code */ | ||||||
| static int ack_handler(struct nl_msg *msg, void *arg) | static int ack_handler(struct nl_msg *msg, void *arg) | ||||||
| { | { | ||||||
|  | @ -181,6 +175,13 @@ static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, | ||||||
| 	return NL_SKIP; | 	return NL_SKIP; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | static int no_seq_check(struct nl_msg *msg, void *arg) | ||||||
|  | { | ||||||
|  | 	return NL_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, | static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, | ||||||
| 			      struct nl_msg *msg, | 			      struct nl_msg *msg, | ||||||
| 			      int (*valid_handler)(struct nl_msg *, void *), | 			      int (*valid_handler)(struct nl_msg *, void *), | ||||||
|  | @ -382,6 +383,7 @@ static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #ifndef HOSTAPD | ||||||
| static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv, | static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv, | ||||||
| 					  void *ctx, char *buf, size_t len, | 					  void *ctx, char *buf, size_t len, | ||||||
| 					  int del) | 					  int del) | ||||||
|  | @ -621,12 +623,6 @@ try_again: | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static int no_seq_check(struct nl_msg *msg, void *arg) |  | ||||||
| { |  | ||||||
| 	return NL_OK; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static void mlme_event_auth(struct wpa_driver_nl80211_data *drv, | static void mlme_event_auth(struct wpa_driver_nl80211_data *drv, | ||||||
| 			    const u8 *frame, size_t len) | 			    const u8 *frame, size_t len) | ||||||
| { | { | ||||||
|  | @ -729,10 +725,17 @@ static void mlme_event(struct wpa_driver_nl80211_data *drv, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #endif /* HOSTAPD */ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv, | static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv, | ||||||
| 					   struct nlattr *tb[]) | 					   struct nlattr *tb[]) | ||||||
| { | { | ||||||
|  | #ifdef HOSTAPD | ||||||
|  | 	if (tb[NL80211_ATTR_MAC]) | ||||||
|  | 		hostapd_michael_mic_failure(drv->hapd, | ||||||
|  | 					    nla_data(tb[NL80211_ATTR_MAC])); | ||||||
|  | #else /* HOSTAPD */ | ||||||
| 	union wpa_event_data data; | 	union wpa_event_data data; | ||||||
| 
 | 
 | ||||||
| 	wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure"); | 	wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure"); | ||||||
|  | @ -762,6 +765,7 @@ static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data); | 	wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data); | ||||||
|  | #endif /* HOSTAPD */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -785,6 +789,7 @@ static int process_event(struct nl_msg *msg, void *arg) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	switch (gnlh->cmd) { | 	switch (gnlh->cmd) { | ||||||
|  | #ifndef HOSTAPD | ||||||
| 	case NL80211_CMD_NEW_SCAN_RESULTS: | 	case NL80211_CMD_NEW_SCAN_RESULTS: | ||||||
| 		wpa_printf(MSG_DEBUG, "nl80211: New scan results available"); | 		wpa_printf(MSG_DEBUG, "nl80211: New scan results available"); | ||||||
| 		drv->scan_complete_events = 1; | 		drv->scan_complete_events = 1; | ||||||
|  | @ -808,6 +813,7 @@ static int process_event(struct nl_msg *msg, void *arg) | ||||||
| 	case NL80211_CMD_DISASSOCIATE: | 	case NL80211_CMD_DISASSOCIATE: | ||||||
| 		mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]); | 		mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]); | ||||||
| 		break; | 		break; | ||||||
|  | #endif /* HOSTAPD */ | ||||||
| 	case NL80211_CMD_MICHAEL_MIC_FAILURE: | 	case NL80211_CMD_MICHAEL_MIC_FAILURE: | ||||||
| 		mlme_event_michael_mic_failure(drv, tb); | 		mlme_event_michael_mic_failure(drv, tb); | ||||||
| 		break; | 		break; | ||||||
|  | @ -1116,8 +1122,10 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname) | ||||||
| 		goto err6; | 		goto err6; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | #ifndef HOSTAPD | ||||||
| 	eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_link, drv, | 	eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_link, drv, | ||||||
| 				 ctx); | 				 ctx); | ||||||
|  | #endif /* HOSTAPD */ | ||||||
| 	drv->link_event_sock = s; | 	drv->link_event_sock = s; | ||||||
| 
 | 
 | ||||||
| 	if (wpa_driver_nl80211_finish_drv_init(drv)) | 	if (wpa_driver_nl80211_finish_drv_init(drv)) | ||||||
|  | @ -1234,7 +1242,9 @@ static void wpa_driver_nl80211_deinit(void *priv) | ||||||
| static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx) | static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx) | ||||||
| { | { | ||||||
| 	wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); | 	wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); | ||||||
|  | #ifndef HOSTAPD | ||||||
| 	wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); | 	wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); | ||||||
|  | #endif /* HOSTAPD */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -4757,6 +4767,7 @@ static int i802_ht_scan(struct wpa_driver_nl80211_data *drv) | ||||||
| static int i802_init_sockets(struct wpa_driver_nl80211_data *drv, const u8 *bssid) | static int i802_init_sockets(struct wpa_driver_nl80211_data *drv, const u8 *bssid) | ||||||
| { | { | ||||||
| 	struct ifreq ifr; | 	struct ifreq ifr; | ||||||
|  | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); | 	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); | ||||||
| 	if (drv->ioctl_sock < 0) { | 	if (drv->ioctl_sock < 0) { | ||||||
|  | @ -4820,6 +4831,28 @@ static int i802_init_sockets(struct wpa_driver_nl80211_data *drv, const u8 *bssi | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	ret = nl_get_multicast_id(drv, "nl80211", "scan"); | ||||||
|  | 	if (ret >= 0) | ||||||
|  | 		ret = nl_socket_add_membership(drv->nl_handle, ret); | ||||||
|  | 	if (ret < 0) { | ||||||
|  | 		wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast " | ||||||
|  | 			   "membership for scan events: %d (%s)", | ||||||
|  | 			   ret, strerror(-ret)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = nl_get_multicast_id(drv, "nl80211", "mlme"); | ||||||
|  | 	if (ret >= 0) | ||||||
|  | 		ret = nl_socket_add_membership(drv->nl_handle, ret); | ||||||
|  | 	if (ret < 0) { | ||||||
|  | 		wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast " | ||||||
|  | 			   "membership for mlme events: %d (%s)", | ||||||
|  | 			   ret, strerror(-ret)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle), | ||||||
|  | 				 wpa_driver_nl80211_event_receive, drv, | ||||||
|  | 				 drv->hapd); | ||||||
|  | 
 | ||||||
| #ifdef CONFIG_IEEE80211N | #ifdef CONFIG_IEEE80211N | ||||||
| 	if (drv->ht_40mhz_scan) { | 	if (drv->ht_40mhz_scan) { | ||||||
| 		if (nl80211_set_mode(drv, drv->ifname, NL80211_IFTYPE_STATION) | 		if (nl80211_set_mode(drv, drv->ifname, NL80211_IFTYPE_STATION) | ||||||
|  | @ -4899,255 +4932,6 @@ static int i802_sta_clear_stats(void *priv, const u8 *addr) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void |  | ||||||
| hostapd_wireless_event_wireless_custom(struct wpa_driver_nl80211_data *drv, |  | ||||||
| 				       char *custom) |  | ||||||
| { |  | ||||||
| 	wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); |  | ||||||
| 
 |  | ||||||
| 	if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { |  | ||||||
| 		char *pos; |  | ||||||
| 		u8 addr[ETH_ALEN]; |  | ||||||
| 		pos = strstr(custom, "addr="); |  | ||||||
| 		if (pos == NULL) { |  | ||||||
| 			wpa_printf(MSG_DEBUG, |  | ||||||
| 				   "MLME-MICHAELMICFAILURE.indication " |  | ||||||
| 				   "without sender address ignored"); |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
| 		pos += 5; |  | ||||||
| 		if (hwaddr_aton(pos, addr) == 0) { |  | ||||||
| 			hostapd_michael_mic_failure(drv->hapd, addr); |  | ||||||
| 		} else { |  | ||||||
| 			wpa_printf(MSG_DEBUG, |  | ||||||
| 				   "MLME-MICHAELMICFAILURE.indication " |  | ||||||
| 				   "with invalid MAC address"); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static void hostapd_wireless_event_wireless(struct wpa_driver_nl80211_data *drv, |  | ||||||
| 					    char *data, int len) |  | ||||||
| { |  | ||||||
| 	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); |  | ||||||
| 		wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d", |  | ||||||
| 			   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; |  | ||||||
| 			memcpy(dpos, pos + IW_EV_LCP_LEN, |  | ||||||
| 			       sizeof(struct iw_event) - dlen); |  | ||||||
| 		} else { |  | ||||||
| 			memcpy(&iwe_buf, pos, sizeof(struct iw_event)); |  | ||||||
| 			custom += IW_EV_POINT_OFF; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		switch (iwe->cmd) { |  | ||||||
| 		case IWEVCUSTOM: |  | ||||||
| 			if (custom + iwe->u.data.length > end) |  | ||||||
| 				return; |  | ||||||
| 			buf = malloc(iwe->u.data.length + 1); |  | ||||||
| 			if (buf == NULL) |  | ||||||
| 				return; |  | ||||||
| 			memcpy(buf, custom, iwe->u.data.length); |  | ||||||
| 			buf[iwe->u.data.length] = '\0'; |  | ||||||
| 			hostapd_wireless_event_wireless_custom(drv, buf); |  | ||||||
| 			free(buf); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		pos += iwe->len; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static void hostapd_wireless_event_rtm_newlink(struct wpa_driver_nl80211_data *drv, |  | ||||||
| 					       struct nlmsghdr *h, int len) |  | ||||||
| { |  | ||||||
| 	struct ifinfomsg *ifi; |  | ||||||
| 	int attrlen, _nlmsg_len, rta_len; |  | ||||||
| 	struct rtattr *attr; |  | ||||||
| 
 |  | ||||||
| 	if (len < (int) sizeof(*ifi)) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	ifi = NLMSG_DATA(h); |  | ||||||
| 
 |  | ||||||
| 	/* TODO: use ifi->ifi_index to filter out wireless events from other
 |  | ||||||
| 	 * interfaces */ |  | ||||||
| 
 |  | ||||||
| 	_nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); |  | ||||||
| 
 |  | ||||||
| 	attrlen = h->nlmsg_len - _nlmsg_len; |  | ||||||
| 	if (attrlen < 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len); |  | ||||||
| 
 |  | ||||||
| 	rta_len = RTA_ALIGN(sizeof(struct rtattr)); |  | ||||||
| 	while (RTA_OK(attr, attrlen)) { |  | ||||||
| 		if (attr->rta_type == IFLA_WIRELESS) { |  | ||||||
| 			hostapd_wireless_event_wireless( |  | ||||||
| 				drv, ((char *) attr) + rta_len, |  | ||||||
| 				attr->rta_len - rta_len); |  | ||||||
| 		} |  | ||||||
| 		attr = RTA_NEXT(attr, attrlen); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static void hostapd_wireless_event_receive(int sock, void *eloop_ctx, |  | ||||||
| 					   void *sock_ctx) |  | ||||||
| { |  | ||||||
| 	char buf[256]; |  | ||||||
| 	int left; |  | ||||||
| 	struct sockaddr_nl from; |  | ||||||
| 	socklen_t fromlen; |  | ||||||
| 	struct nlmsghdr *h; |  | ||||||
| 	struct wpa_driver_nl80211_data *drv = eloop_ctx; |  | ||||||
| 
 |  | ||||||
| 	fromlen = sizeof(from); |  | ||||||
| 	left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, |  | ||||||
| 			(struct sockaddr *) &from, &fromlen); |  | ||||||
| 	if (left < 0) { |  | ||||||
| 		if (errno != EINTR && errno != EAGAIN) |  | ||||||
| 			perror("recvfrom(netlink)"); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	h = (struct nlmsghdr *) buf; |  | ||||||
| 	while (left >= (int) sizeof(*h)) { |  | ||||||
| 		int len, plen; |  | ||||||
| 
 |  | ||||||
| 		len = h->nlmsg_len; |  | ||||||
| 		plen = len - sizeof(*h); |  | ||||||
| 		if (len > left || plen < 0) { |  | ||||||
| 			printf("Malformed netlink message: " |  | ||||||
| 			       "len=%d left=%d plen=%d\n", |  | ||||||
| 			       len, left, plen); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		switch (h->nlmsg_type) { |  | ||||||
| 		case RTM_NEWLINK: |  | ||||||
| 			hostapd_wireless_event_rtm_newlink(drv, h, plen); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		len = NLMSG_ALIGN(len); |  | ||||||
| 		left -= len; |  | ||||||
| 		h = (struct nlmsghdr *) ((char *) h + len); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (left > 0) { |  | ||||||
| 		printf("%d extra bytes in the end of netlink message\n", left); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static int hostap_get_we_version(struct wpa_driver_nl80211_data *drv) |  | ||||||
| { |  | ||||||
| 	struct iw_range *range; |  | ||||||
| 	struct iwreq iwr; |  | ||||||
| 	int minlen; |  | ||||||
| 	size_t buflen; |  | ||||||
| 
 |  | ||||||
| 	drv->we_version = 0; |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * 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; |  | ||||||
| 
 |  | ||||||
| 	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]"); |  | ||||||
| 		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->we_version = range->we_version_compiled; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	free(range); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static int i802_wireless_event_init(struct wpa_driver_nl80211_data *drv) |  | ||||||
| { |  | ||||||
| 	int s; |  | ||||||
| 	struct sockaddr_nl local; |  | ||||||
| 
 |  | ||||||
| 	hostap_get_we_version(drv); |  | ||||||
| 
 |  | ||||||
| 	drv->wext_sock = -1; |  | ||||||
| 
 |  | ||||||
| 	s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); |  | ||||||
| 	if (s < 0) { |  | ||||||
| 		perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	memset(&local, 0, sizeof(local)); |  | ||||||
| 	local.nl_family = AF_NETLINK; |  | ||||||
| 	local.nl_groups = RTMGRP_LINK; |  | ||||||
| 	if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) { |  | ||||||
| 		perror("bind(netlink)"); |  | ||||||
| 		close(s); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	eloop_register_read_sock(s, hostapd_wireless_event_receive, drv, |  | ||||||
| 				 NULL); |  | ||||||
| 	drv->wext_sock = s; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static void i802_wireless_event_deinit(struct wpa_driver_nl80211_data *drv) |  | ||||||
| { |  | ||||||
| 	if (drv->wext_sock < 0) |  | ||||||
| 		return; |  | ||||||
| 	eloop_unregister_read_sock(drv->wext_sock); |  | ||||||
| 	close(drv->wext_sock); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static int i802_sta_deauth(void *priv, const u8 *addr, int reason) | static int i802_sta_deauth(void *priv, const u8 *addr, int reason) | ||||||
| { | { | ||||||
| 	struct wpa_driver_nl80211_data *drv = priv; | 	struct wpa_driver_nl80211_data *drv = priv; | ||||||
|  | @ -5219,9 +5003,6 @@ static void *i802_init_bssid(struct hostapd_data *hapd, const u8 *bssid) | ||||||
| 	if (i802_init_sockets(drv, bssid)) | 	if (i802_init_sockets(drv, bssid)) | ||||||
| 		goto failed; | 		goto failed; | ||||||
| 
 | 
 | ||||||
| 	if (i802_wireless_event_init(drv)) |  | ||||||
| 		goto failed; |  | ||||||
| 
 |  | ||||||
| 	return drv; | 	return drv; | ||||||
| 
 | 
 | ||||||
| failed: | failed: | ||||||
|  | @ -5241,8 +5022,6 @@ static void i802_deinit(void *priv) | ||||||
| 	struct wpa_driver_nl80211_data *drv = priv; | 	struct wpa_driver_nl80211_data *drv = priv; | ||||||
| 	struct i802_bss *bss, *prev; | 	struct i802_bss *bss, *prev; | ||||||
| 
 | 
 | ||||||
| 	i802_wireless_event_deinit(drv); |  | ||||||
| 
 |  | ||||||
| 	if (drv->last_freq_ht) { | 	if (drv->last_freq_ht) { | ||||||
| 		/* Clear HT flags from the driver */ | 		/* Clear HT flags from the driver */ | ||||||
| 		struct hostapd_freq_params freq; | 		struct hostapd_freq_params freq; | ||||||
|  | @ -5269,6 +5048,7 @@ static void i802_deinit(void *priv) | ||||||
| 		close(drv->eapol_sock); | 		close(drv->eapol_sock); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle)); | ||||||
| 	genl_family_put(drv->nl80211); | 	genl_family_put(drv->nl80211); | ||||||
| 	nl_cache_free(drv->nl_cache); | 	nl_cache_free(drv->nl_cache); | ||||||
| 	nl_handle_destroy(drv->nl_handle); | 	nl_handle_destroy(drv->nl_handle); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen