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

📄 driver_nl80211.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				   MACSTR,				   MAC2STR((u8 *) iwe->u.ap_addr.sa_data));			if (is_zero_ether_addr(				    (const u8 *) iwe->u.ap_addr.sa_data) ||			    os_memcmp(iwe->u.ap_addr.sa_data,				      "\x44\x44\x44\x44\x44\x44", ETH_ALEN) ==			    0) {				os_free(drv->assoc_req_ies);				drv->assoc_req_ies = NULL;				os_free(drv->assoc_resp_ies);				drv->assoc_resp_ies = NULL;				wpa_supplicant_event(ctx, EVENT_DISASSOC,						     NULL);						} else {				wpa_driver_nl80211_event_assoc_ies(drv);				wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);			}			break;		case IWEVMICHAELMICFAILURE:			wpa_driver_nl80211_event_wireless_michaelmicfailure(				ctx, custom, iwe->u.data.length);			break;		case IWEVCUSTOM:			if (custom + iwe->u.data.length > end)				return;			buf = os_malloc(iwe->u.data.length + 1);			if (buf == NULL)				return;			os_memcpy(buf, custom, iwe->u.data.length);			buf[iwe->u.data.length] = '\0';			wpa_driver_nl80211_event_wireless_custom(ctx, buf);			os_free(buf);			break;		case SIOCGIWSCAN:			drv->scan_complete_events = 1;			eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,					     drv, ctx);			wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);			break;		case IWEVASSOCREQIE:			wpa_driver_nl80211_event_wireless_assocreqie(				drv, custom, iwe->u.data.length);			break;		case IWEVASSOCRESPIE:			wpa_driver_nl80211_event_wireless_assocrespie(				drv, custom, iwe->u.data.length);			break;		case IWEVPMKIDCAND:			wpa_driver_nl80211_event_wireless_pmkidcand(				drv, custom, iwe->u.data.length);			break;		}		pos += iwe->len;	}}static void wpa_driver_nl80211_event_link(void *ctx, char *buf, size_t len,				       int del){	union wpa_event_data event;	os_memset(&event, 0, sizeof(event));	if (len > sizeof(event.interface_status.ifname))		len = sizeof(event.interface_status.ifname) - 1;	os_memcpy(event.interface_status.ifname, buf, len);	event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :		EVENT_INTERFACE_ADDED;	wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",		   del ? "DEL" : "NEW",		   event.interface_status.ifname,		   del ? "removed" : "added");	wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);}static void wpa_driver_nl80211_event_rtm_newlink(struct wpa_driver_nl80211_data *drv,					      void *ctx, struct nlmsghdr *h,					      size_t len){	struct ifinfomsg *ifi;	int attrlen, _nlmsg_len, rta_len;	struct rtattr * attr;	if (len < sizeof(*ifi))		return;	ifi = NLMSG_DATA(h);	if (drv->ifindex != ifi->ifi_index) {		wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",			   ifi->ifi_index);		return;	}	wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "		   "(%s%s%s%s)",		   drv->operstate, ifi->ifi_flags,		   (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",		   (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",		   (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",		   (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");	/*	 * Some drivers send the association event before the operup event--in	 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()	 * fails. This will hit us when wpa_supplicant does not need to do	 * IEEE 802.1X authentication	 */	if (drv->operstate == 1 &&	    (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&	    !(ifi->ifi_flags & IFF_RUNNING))		wpa_driver_nl80211_send_oper_ifla(drv, -1, IF_OPER_UP);	_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) {			wpa_driver_nl80211_event_wireless(				drv, ctx, ((char *) attr) + rta_len,				attr->rta_len - rta_len);		} else if (attr->rta_type == IFLA_IFNAME) {			wpa_driver_nl80211_event_link(ctx,						   ((char *) attr) + rta_len,						   attr->rta_len - rta_len, 0);		}		attr = RTA_NEXT(attr, attrlen);	}}static void wpa_driver_nl80211_event_rtm_dellink(struct wpa_driver_nl80211_data *drv,					      void *ctx, struct nlmsghdr *h,					      size_t len){	struct ifinfomsg *ifi;	int attrlen, _nlmsg_len, rta_len;	struct rtattr * attr;	if (len < sizeof(*ifi))		return;	ifi = NLMSG_DATA(h);	_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_IFNAME) {			wpa_driver_nl80211_event_link(ctx,						   ((char *) attr) + rta_len,						   attr->rta_len - rta_len, 1);		}		attr = RTA_NEXT(attr, attrlen);	}}static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,					  void *sock_ctx){	char buf[8192];	int left;	struct sockaddr_nl from;	socklen_t fromlen;	struct nlmsghdr *h;	int max_events = 10;try_again:	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) {			wpa_printf(MSG_DEBUG, "Malformed netlink message: "				   "len=%d left=%d plen=%d",				   len, left, plen);			break;		}		switch (h->nlmsg_type) {		case RTM_NEWLINK:			wpa_driver_nl80211_event_rtm_newlink(eloop_ctx, sock_ctx,							  h, plen);			break;		case RTM_DELLINK:			wpa_driver_nl80211_event_rtm_dellink(eloop_ctx, sock_ctx,							  h, plen);			break;		}		len = NLMSG_ALIGN(len);		left -= len;		h = (struct nlmsghdr *) ((char *) h + len);	}	if (left > 0) {		wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "			   "message", left);	}	if (--max_events > 0) {		/*		 * Try to receive all events in one eloop call in order to		 * limit race condition on cases where AssocInfo event, Assoc		 * event, and EAPOL frames are received more or less at the		 * same time. We want to process the event messages first		 * before starting EAPOL processing.		 */		goto try_again;	}}static int wpa_driver_nl80211_get_ifflags_ifname(struct wpa_driver_nl80211_data *drv,					      const char *ifname, int *flags){	struct ifreq ifr;	os_memset(&ifr, 0, sizeof(ifr));	os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);	if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {		perror("ioctl[SIOCGIFFLAGS]");		return -1;	}	*flags = ifr.ifr_flags & 0xffff;	return 0;}/** * wpa_driver_nl80211_get_ifflags - Get interface flags (SIOCGIFFLAGS) * @drv: driver_nl80211 private data * @flags: Pointer to returned flags value * Returns: 0 on success, -1 on failure */static int wpa_driver_nl80211_get_ifflags(struct wpa_driver_nl80211_data *drv,					  int *flags){	return wpa_driver_nl80211_get_ifflags_ifname(drv, drv->ifname, flags);}static int wpa_driver_nl80211_set_ifflags_ifname(	struct wpa_driver_nl80211_data *drv,	const char *ifname, int flags){	struct ifreq ifr;	os_memset(&ifr, 0, sizeof(ifr));	os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);	ifr.ifr_flags = flags & 0xffff;	if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {		perror("SIOCSIFFLAGS");		return -1;	}	return 0;}/** * wpa_driver_nl80211_set_ifflags - Set interface flags (SIOCSIFFLAGS) * @drv: driver_nl80211 private data * @flags: New value for flags * Returns: 0 on success, -1 on failure */static int wpa_driver_nl80211_set_ifflags(struct wpa_driver_nl80211_data *drv,					  int flags){	return wpa_driver_nl80211_set_ifflags_ifname(drv, drv->ifname, flags);}/** * wpa_driver_nl80211_init - Initialize WE driver interface * @ctx: context to be used when calling wpa_supplicant functions, * e.g., wpa_supplicant_event() * @ifname: interface name, e.g., wlan0 * Returns: Pointer to private data, %NULL on failure */void * wpa_driver_nl80211_init(void *ctx, const char *ifname){	int s, flags;	struct sockaddr_nl local;	struct wpa_driver_nl80211_data *drv;	drv = os_zalloc(sizeof(*drv));	if (drv == NULL)		return NULL;	drv->ctx = ctx;	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));	drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);	if (drv->nl_cb == NULL) {		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "			   "callbacks");		goto err1;	}	drv->nl_handle = nl_handle_alloc_cb(drv->nl_cb);	if (drv->nl_handle == NULL) {		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "			   "callbacks");		goto err2;	}	if (genl_connect(drv->nl_handle)) {		wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "			   "netlink");		goto err3;	}	drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);	if (drv->nl_cache == NULL) {		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "			   "netlink cache");		goto err3;	}	drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");	if (drv->nl80211 == NULL) {		wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "			   "found");		goto err4;	}	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);	if (drv->ioctl_sock < 0) {		perror("socket(PF_INET,SOCK_DGRAM)");		goto err5;	}	s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);	if (s < 0) {		perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");		goto err6;	}	os_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);		goto err6;	}	eloop_register_read_sock(s, wpa_driver_nl80211_event_receive, drv,				 ctx);	drv->event_sock = s;	if (wpa_driver_nl80211_get_ifflags(drv, &flags) != 0)		printf("Could not get interface '%s' flags\n", drv->ifname);	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);		} else {			/*			 * Wait some time to allow driver to initialize before			 * starting configuring the driver. This seems to be			 * needed at least some drivers that load firmware etc.			 * when the interface is set up.			 */			wpa_printf(MSG_DEBUG, "Interface %s set UP - waiting "				   "a second for the driver to complete "				   "initialization", drv->ifname);			sleep(1);		}	}	/*	 * 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);	return drv;err6:	close(drv->ioctl_sock);err5:	genl_family_put(drv->nl80211);err4:	nl_cache_free(drv->nl_cache);err3:	nl_handle_destroy(drv->nl_handle);err2:	nl_cb_put(drv->nl_cb);err1:	os_free(drv);	return NULL;}/** * wpa_driver_nl80211_deinit - Deinitialize WE driver interface * @priv: Pointer to private wext 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(). */void wpa_driver_nl80211_deinit(void *priv){	struct wpa_driver_nl80211_data *drv = priv;	int flags;	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->event_sock);	if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0)		(void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);	close(drv->event_sock);	close(drv->ioctl_sock);	os_free(drv->assoc_req_ies);	os_free(drv->assoc_resp_ies);	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;	struct iwreq iwr;	int ret = 0, timeout;	struct iw_scan_req req;	if (ssid_len > IW_ESSID_MAX_SIZE) {		wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",			   __FUNCTION__, (unsigned long) ssid_len);		return -1;	}	os_memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);	if (ssid && ssid_len) {		os_memset(&req, 0, sizeof(req));		req.essid_len = ssid_len;		req.bssid.sa_family = ARPHRD_ETHER;		os_memset(req.bssid.sa_data, 0xff, ETH_ALEN);		os_memcpy(req.essid, ssid, ssid_len);		iwr.u.data.pointer = (caddr_t) &req;		iwr.u.data.length = sizeof(req);		iwr.u.data.flags = IW_SCAN_THIS_ESSID;	}	if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {		perror("ioctl[SIOCSIWSCAN]");

⌨️ 快捷键说明

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