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

📄 driver_atheros.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	} else if (strncmp(custom, "Manage.prob_req ", 16) == 0) {		/*		 * Atheros driver uses a hack to pass Probe Request frames as a		 * binary data in the custom wireless event. The old way (using		 * packet sniffing) didn't work when bridging.		 * Format: "Manage.prob_req <frame len>" | zero padding | frame		 */#define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */		int len = atoi(custom + 16);		if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) {			wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event "				   "length %d", len);			return;		}		madwifi_raw_receive(drv, NULL,				    (u8 *) custom + WPS_FRAM_TAG_SIZE, len);#endif /* CONFIG_WPS */	}}static voidmadwifi_wireless_event_wireless(struct madwifi_driver_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_MSGDUMP, "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 == IWEVASSOCREQIE ||		     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 IWEVEXPIRED:			hostapd_notif_disassoc(drv->hapd,					       (u8 *) iwe->u.addr.sa_data);			break;		case IWEVREGISTERED:			madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data);			break;		case IWEVASSOCREQIE:			/* Driver hack.. Use IWEVASSOCREQIE to bypass			 * IWEVCUSTOM size limitations. Need to handle this			 * just like IWEVCUSTOM.			 */		case IWEVCUSTOM:			if (custom + iwe->u.data.length > end)				return;			buf = malloc(iwe->u.data.length + 1);			if (buf == NULL)				return;		/* XXX */			memcpy(buf, custom, iwe->u.data.length);			buf[iwe->u.data.length] = '\0';			madwifi_wireless_event_wireless_custom(				drv, buf, buf + iwe->u.data.length);			free(buf);			break;		}		pos += iwe->len;	}}static voidmadwifi_wireless_event_rtm_newlink(struct madwifi_driver_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);	if (ifi->ifi_index != drv->ifindex)		return;	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) {			madwifi_wireless_event_wireless(				drv, ((char *) attr) + rta_len,				attr->rta_len - rta_len);		}		attr = RTA_NEXT(attr, attrlen);	}}static voidmadwifi_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 madwifi_driver_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:			madwifi_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 intmadwifi_get_we_version(struct madwifi_driver_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->iface, 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 intmadwifi_wireless_event_init(void *priv){	struct madwifi_driver_data *drv = priv;	int s;	struct sockaddr_nl local;	madwifi_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, madwifi_wireless_event_receive, drv, NULL);	drv->wext_sock = s;	return 0;}static voidmadwifi_wireless_event_deinit(void *priv){	struct madwifi_driver_data *drv = priv;	if (drv != NULL) {		if (drv->wext_sock < 0)			return;		eloop_unregister_read_sock(drv->wext_sock);		close(drv->wext_sock);	}}static intmadwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,		   int encrypt, const u8 *own_addr){	struct madwifi_driver_data *drv = priv;	unsigned char buf[3000];	unsigned char *bp = buf;	struct l2_ethhdr *eth;	size_t len;	int status;	/*	 * Prepend the Ethernet header.  If the caller left us	 * space at the front we could just insert it but since	 * we don't know we copy to a local buffer.  Given the frequency	 * and size of frames this probably doesn't matter.	 */	len = data_len + sizeof(struct l2_ethhdr);	if (len > sizeof(buf)) {		bp = malloc(len);		if (bp == NULL) {			printf("EAPOL frame discarded, cannot malloc temp "			       "buffer of size %lu!\n", (unsigned long) len);			return -1;		}	}	eth = (struct l2_ethhdr *) bp;	memcpy(eth->h_dest, addr, ETH_ALEN);	memcpy(eth->h_source, own_addr, ETH_ALEN);	eth->h_proto = host_to_be16(ETH_P_EAPOL);	memcpy(eth+1, data, data_len);	wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);	status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);	if (bp != buf)		free(bp);	return status;}static voidhandle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len){	struct madwifi_driver_data *drv = ctx;	hostapd_eapol_receive(drv->hapd, src_addr,			      buf + sizeof(struct l2_ethhdr),			      len - sizeof(struct l2_ethhdr));}static void *madwifi_init(struct hostapd_data *hapd){	struct madwifi_driver_data *drv;	struct ifreq ifr;	struct iwreq iwr;	drv = os_zalloc(sizeof(struct madwifi_driver_data));	if (drv == NULL) {		printf("Could not allocate memory for madwifi driver data\n");		return NULL;	}	drv->hapd = hapd;	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);	if (drv->ioctl_sock < 0) {		perror("socket[PF_INET,SOCK_DGRAM]");		goto bad;	}	memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));	memset(&ifr, 0, sizeof(ifr));	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {		perror("ioctl(SIOCGIFINDEX)");		goto bad;	}	drv->ifindex = ifr.ifr_ifindex;	drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,					handle_read, drv, 1);	if (drv->sock_xmit == NULL)		goto bad;	if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr))		goto bad;	if (hapd->conf->bridge[0] != '\0') {		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",			   hapd->conf->bridge);		drv->sock_recv = l2_packet_init(hapd->conf->bridge, NULL,						ETH_P_EAPOL, handle_read, drv,						1);		if (drv->sock_recv == NULL)			goto bad;	} else		drv->sock_recv = drv->sock_xmit;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);	iwr.u.mode = IW_MODE_MASTER;	if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {		perror("ioctl[SIOCSIWMODE]");		printf("Could not set interface to master mode!\n");		goto bad;	}	madwifi_set_iface_flags(drv, 0);	/* mark down during setup */	madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */	madwifi_receive_probe_req(drv);	return drv;bad:	if (drv->sock_xmit != NULL)		l2_packet_deinit(drv->sock_xmit);	if (drv->ioctl_sock >= 0)		close(drv->ioctl_sock);	if (drv != NULL)		free(drv);	return NULL;}static voidmadwifi_deinit(void *priv){	struct madwifi_driver_data *drv = priv;	(void) madwifi_set_iface_flags(drv, 0);	if (drv->ioctl_sock >= 0)		close(drv->ioctl_sock);	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)		l2_packet_deinit(drv->sock_recv);	if (drv->sock_xmit != NULL)		l2_packet_deinit(drv->sock_xmit);	if (drv->sock_raw)		l2_packet_deinit(drv->sock_raw);	free(drv);}static intmadwifi_set_ssid(const char *ifname, void *priv, const u8 *buf, int len){	struct madwifi_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);	iwr.u.essid.flags = 1; /* SSID active */	iwr.u.essid.pointer = (caddr_t) buf;	iwr.u.essid.length = len + 1;	if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {		perror("ioctl[SIOCSIWESSID]");		printf("len=%d\n", len);		return -1;	}	return 0;}static intmadwifi_get_ssid(const char *ifname, void *priv, u8 *buf, int len){	struct madwifi_driver_data *drv = priv;	struct iwreq iwr;	int ret = 0;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);	iwr.u.essid.pointer = (caddr_t) buf;	iwr.u.essid.length = len;	if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {		perror("ioctl[SIOCGIWESSID]");		ret = -1;	} else		ret = iwr.u.essid.length;	return ret;}static intmadwifi_set_countermeasures(void *priv, int enabled){	struct madwifi_driver_data *drv = priv;	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);	return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled);}static intmadwifi_commit(void *priv){	return madwifi_set_iface_flags(priv, 1);}const struct wpa_driver_ops wpa_driver_atheros_ops = {	.name			= "atheros",	.init			= madwifi_init,	.deinit			= madwifi_deinit,	.set_ieee8021x		= madwifi_set_ieee8021x,	.set_privacy		= madwifi_set_privacy,	.set_encryption		= madwifi_set_key,	.get_seqnum		= madwifi_get_seqnum,	.flush			= madwifi_flush,	.set_generic_elem	= madwifi_set_opt_ie,	.wireless_event_init	= madwifi_wireless_event_init,	.wireless_event_deinit	= madwifi_wireless_event_deinit,	.sta_set_flags		= madwifi_sta_set_flags,	.read_sta_data		= madwifi_read_sta_driver_data,	.send_eapol		= madwifi_send_eapol,	.sta_disassoc		= madwifi_sta_disassoc,	.sta_deauth		= madwifi_sta_deauth,	.set_ssid		= madwifi_set_ssid,	.get_ssid		= madwifi_get_ssid,	.set_countermeasures	= madwifi_set_countermeasures,	.sta_clear_stats	= madwifi_sta_clear_stats,	.commit			= madwifi_commit,	.set_wps_beacon_ie	= madwifi_set_wps_beacon_ie,	.set_wps_probe_resp_ie	= madwifi_set_wps_probe_resp_ie,};

⌨️ 快捷键说明

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