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

📄 driver_ralink.c

📁 无线网卡驱动程序,RT73_Linux_STA_Drv1.0.3.6.tar
💻 C
📖 第 1 页 / 共 3 页
字号:
		bytes = strspn(spos, "0123456789abcdefABCDEF");
		if (!bytes || (bytes & 1))
			return;
		bytes /= 2;

		data.assoc_info.req_ies = malloc(bytes);
		if (data.assoc_info.req_ies == NULL)
			return;

		data.assoc_info.req_ies_len = bytes;
		hexstr2bin(spos, data.assoc_info.req_ies, bytes);

		spos += bytes * 2;

		data.assoc_info.resp_ies = NULL;
		data.assoc_info.resp_ies_len = 0;

		if (strncmp(spos, " RespIEs=", 9) == 0) {
			spos += 9;

			bytes = strspn(spos, "0123456789abcdefABCDEF");
			if (!bytes || (bytes & 1))
				goto done;
			bytes /= 2;

			data.assoc_info.resp_ies = malloc(bytes);
			if (data.assoc_info.resp_ies == NULL)
				goto done;

			data.assoc_info.resp_ies_len = bytes;
			hexstr2bin(spos, data.assoc_info.resp_ies, bytes);
		}

		wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data);

	done:
		free(data.assoc_info.resp_ies);
		free(data.assoc_info.req_ies);
	}
}

static void wpa_driver_ralink_event_wireless(struct wpa_driver_ralink_data *drv,
					   void *ctx, char *data, int len)
{
	struct iw_event iwe_buf, *iwe = &iwe_buf;
	char *pos, *end, *custom, *buf, *assoc_info_buf, *info_pos;
	struct wpa_supplicant *wpa_s = ctx;
	BOOLEAN  ieee8021x_required_key = FALSE;

    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);

        assoc_info_buf = info_pos = NULL;
	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_compiled > 18 &&
		    (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';

            if (wpa_s->conf->ap_scan == 1) {
			   if ((iwe->u.data.flags == RT_ASSOC_EVENT_FLAG) || (iwe->u.data.flags == RT_REQIE_EVENT_FLAG) ||
			       (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG) || (iwe->u.data.flags == RT_ASSOCINFO_EVENT_FLAG)) {
					   if (scanning_done == 0) {
					      free(buf);
						  return;
					   }
				   }
			}

            if (iwe->u.data.flags == RT_ASSOC_EVENT_FLAG) {
	           wpa_printf(MSG_DEBUG, "Custom wireless event: receive ASSOCIATED_EVENT !!!");

			   // determine whether the dynamic-WEP is used or not 
			   if(wpa_s && wpa_s->current_ssid && wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA)
			   {
					if ((wpa_s->current_ssid->eapol_flags &
	      							(EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) 
					{			
						//wpa_printf(MSG_DEBUG, "The current ssid - (%s), eapol_flag = %d.\n",  
						//	 wpa_ssid_txt(wpa_s->current_ssid->ssid, wpa_s->current_ssid->ssid_len),wpa_s->current_ssid->eapol_flags);
						ieee8021x_required_key = TRUE;						
					}
					
					if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY, (char *) &ieee8021x_required_key, sizeof(BOOLEAN)) < 0)
					{
							wpa_printf(MSG_DEBUG, "ERROR: Failed to set OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)", 
																		(int) ieee8021x_required_key);	
				    }
					
					wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s and eapol_flag(%d).\n", ieee8021x_required_key ? "TRUE" : "FALSE",
																								wpa_s->current_ssid->eapol_flags);					
			   }

               wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
            }
			else if (iwe->u.data.flags == RT_REQIE_EVENT_FLAG) {
			   wpa_printf(MSG_DEBUG, "Custom wireless event: receive ReqIEs !!!");
			   drv->assoc_req_ies = malloc(iwe->u.data.length);

			   if (drv->assoc_req_ies == NULL)
			      return;

               drv->assoc_req_ies_len = iwe->u.data.length;
			   memcpy(drv->assoc_req_ies, custom, iwe->u.data.length);
			}
			else if (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG) {
			   wpa_printf(MSG_DEBUG, "Custom wireless event: receive RespIEs !!!");
			   drv->assoc_resp_ies = malloc(iwe->u.data.length);

			   if (drv->assoc_resp_ies == NULL)
			      return;

               drv->assoc_resp_ies_len = iwe->u.data.length;
			   memcpy(drv->assoc_resp_ies, custom, iwe->u.data.length);
			}
			else if (iwe->u.data.flags == RT_ASSOCINFO_EVENT_FLAG) {
			   wpa_printf(MSG_DEBUG, "Custom wireless event: receive ASSOCINFO_EVENT !!!");
			   assoc_info_buf = malloc(drv->assoc_req_ies_len + drv->assoc_resp_ies_len + 1);

			   if (assoc_info_buf == NULL)
			      return;

			   memcpy(assoc_info_buf, drv->assoc_req_ies, drv->assoc_req_ies_len);
			   info_pos = assoc_info_buf + drv->assoc_req_ies_len;
			   memcpy(info_pos , drv->assoc_resp_ies, drv->assoc_resp_ies_len);
			   assoc_info_buf[drv->assoc_req_ies_len + drv->assoc_resp_ies_len] = '\0';
			   wpa_driver_ralink_event_wireless_custom(drv, ctx, assoc_info_buf);
			   free(drv->assoc_req_ies);
			   free(drv->assoc_resp_ies);
			}
		    else if (iwe->u.data.flags == RT_DISASSOC_EVENT_FLAG) {
			   wpa_printf(MSG_DEBUG, "Custom wireless event: receive DISASSOCIATED_EVENT !!!");
               wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
			}
			else if (iwe->u.data.flags == RT_PMKIDCAND_FLAG) {
			   wpa_printf(MSG_DEBUG, "Custom wireless event: receive PMKIDCAND_EVENT !!!");
               wpa_driver_ralink_event_pmkid(drv, custom, iwe->u.data.length);
			}
            else {
			    wpa_driver_ralink_event_wireless_custom(drv, ctx, buf);
            }
			free(assoc_info_buf);
			free(buf);
			break;
		
		}

		pos += iwe->len;
	}
}

static void wpa_driver_ralink_event_rtm_newlink(struct wpa_driver_ralink_data *drv,
					      void *ctx, struct nlmsghdr *h,
					      int len)
{
	struct ifinfomsg *ifi;
	int attrlen, nlmsg_len, rta_len;
	struct rtattr * attr;

    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);

	if (len < sizeof(*ifi))
		return;

	ifi = NLMSG_DATA(h);
       wpa_hexdump(MSG_DEBUG, "ifi: ",
			    (u8 *)ifi, sizeof(struct ifinfomsg));
	
	nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
       
	attrlen = h->nlmsg_len - nlmsg_len;
	printf("attrlen=%d\n",attrlen);
	if (attrlen < 0)
		return;

	attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
       wpa_hexdump(MSG_DEBUG, "attr1: ",
			    (u8 *)attr,sizeof(struct rtattr));
	rta_len = RTA_ALIGN(sizeof(struct rtattr));
	wpa_hexdump(MSG_DEBUG, "attr2: ",
			    (u8 *)attr,rta_len);
	while (RTA_OK(attr, attrlen)) {
		printf("rta_type=%02x\n",attr->rta_type);
		if (attr->rta_type == IFLA_WIRELESS) {
			wpa_driver_ralink_event_wireless(
				drv, ctx, ((char *) attr) + rta_len,
				attr->rta_len - rta_len);
		} 
		attr = RTA_NEXT(attr, attrlen);
		wpa_hexdump(MSG_DEBUG, "attr3: ",
			    (u8 *)attr,sizeof(struct rtattr));
	}
}

static void wpa_driver_ralink_event_receive(int sock, void *ctx,
					      void *sock_ctx)
{
	char buf[8192];
	int left;
	struct sockaddr_nl from;
	socklen_t fromlen;
	struct nlmsghdr *h;
	
    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);

	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;
	wpa_hexdump(MSG_DEBUG, "h: ",
			    (u8 *)h, h->nlmsg_len);
	while (left >= 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_ralink_event_rtm_newlink(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);
	}

}	

static int
ralink_get_we_version_compiled(struct wpa_driver_ralink_data *drv)
{
        struct iwreq iwr;
	UINT   we_version_compiled = 0;

	memset(&iwr, 0, sizeof(iwr));
	strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
	iwr.u.data.pointer = (caddr_t) &we_version_compiled;
	iwr.u.data.flags = RT_OID_WE_VERSION_COMPILED;

    if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
        wpa_printf(MSG_DEBUG, "%s:  failed",
		    	   __func__);
		return -1;
	}
	
	drv->we_version_compiled = we_version_compiled;
	
	return 0;
}

static int
ralink_set_iface_flags(void *priv, int dev_up)
{
	struct wpa_driver_ralink_data *drv = priv;
	struct ifreq ifr;

    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);

	if (drv->ioctl_sock < 0)
		return -1;

	memset(&ifr, 0, sizeof(ifr));
	snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->ifname);

	if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
		perror("ioctl[SIOCGIFFLAGS]");
		return -1;
	}

	if (dev_up)
		ifr.ifr_flags |= IFF_UP;
	else
		ifr.ifr_flags &= ~IFF_UP;

	if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
		perror("ioctl[SIOCSIFFLAGS]");
		return -1;
	}
	
	return 0;
}

static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
{
	int s;
	struct wpa_driver_ralink_data *drv;
	struct ifreq ifr;
        struct sockaddr_nl local;
        struct wpa_supplicant *wpa_s;
    BOOLEAN  enable_wpa_supplicant;

    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);

	/* open socket to kernel */
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		return NULL;
	}
	/* do it */
	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
	if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
		perror(ifr.ifr_name);
		return NULL;
	}


	drv = malloc(sizeof(*drv));
	if (drv == NULL)
		return NULL;
	memset(drv, 0, sizeof(*drv));
	drv->ctx = ctx;
	strncpy(drv->ifname, ifname, sizeof(drv->ifname));
	drv->ioctl_sock = s;

	//use netlink like this

	s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	if (s < 0) {
		perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
		close(drv->ioctl_sock);
		free(drv);
		return NULL;
	}

	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);
		close(drv->ioctl_sock);
		free(drv);
		return NULL;
	}

	eloop_register_read_sock(s, wpa_driver_ralink_event_receive, drv, ctx);
	drv->event_sock = s;
	drv->no_of_pmkid = 4; // Number of PMKID saved supporte

    ralink_set_iface_flags(drv, 1);	/* mark up during setup */
    ralink_get_we_version_compiled(drv);
    wpa_driver_ralink_flush_pmkid(drv);

    enable_wpa_supplicant = TRUE;
    // trigger driver support wpa_supplicant
	if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT, (char *) &enable_wpa_supplicant, sizeof(BOOLEAN)) < 0)
	{
		wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
			   "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
			   (int) enable_wpa_supplicant);	
	}

    wpa_s = drv->ctx;
    if (wpa_s->conf->ap_scan == 1)
       scanning_done = 0;

	return drv;
}

static void wpa_driver_ralink_deinit(void *priv)
{
	struct wpa_driver_ralink_data *drv = priv;
    BOOLEAN  enable_wpa_supplicant;

    wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);

    enable_wpa_supplicant = FALSE;
    // trigger driver disable wpa_supplicant support
	if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT, (char *) &enable_wpa_supplicant, sizeof(BOOLEAN)) < 0)
	{
		wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
			   "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
			   (int) enable_wpa_supplicant);	
	}

⌨️ 快捷键说明

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