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

📄 driver_nl80211.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
static int i802_get_rts(void *priv, int *rts){	struct i802_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->hapd->conf->iface, IFNAMSIZ);	if (ioctl(drv->ioctl_sock, SIOCGIWRTS, &iwr) < 0) {		perror("ioctl[SIOCGIWRTS]");		return -1;	}	*rts = iwr.u.rts.value;	return 0;}static int i802_set_frag(void *priv, int frag){	struct i802_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->hapd->conf->iface, IFNAMSIZ);	iwr.u.frag.value = frag;	iwr.u.frag.fixed = 1;	if (ioctl(drv->ioctl_sock, SIOCSIWFRAG, &iwr) < 0) {		perror("ioctl[SIOCSIWFRAG]");		return -1;	}	return 0;}static int i802_get_frag(void *priv, int *frag){	struct i802_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->hapd->conf->iface, IFNAMSIZ);	if (ioctl(drv->ioctl_sock, SIOCGIWFRAG, &iwr) < 0) {		perror("ioctl[SIOCGIWFRAG]");		return -1;	}	*frag = iwr.u.frag.value;	return 0;}static int i802_set_retry(void *priv, int short_retry, int long_retry){	struct i802_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->hapd->conf->iface, IFNAMSIZ);	iwr.u.retry.value = short_retry;	iwr.u.retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;	if (ioctl(drv->ioctl_sock, SIOCSIWRETRY, &iwr) < 0) {		perror("ioctl[SIOCSIWRETRY(short)]");		return -1;	}	iwr.u.retry.value = long_retry;	iwr.u.retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;	if (ioctl(drv->ioctl_sock, SIOCSIWRETRY, &iwr) < 0) {		perror("ioctl[SIOCSIWRETRY(long)]");		return -1;	}	return 0;}static int i802_get_retry(void *priv, int *short_retry, int *long_retry){	struct i802_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->hapd->conf->iface, IFNAMSIZ);	iwr.u.retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;	if (ioctl(drv->ioctl_sock, SIOCGIWRETRY, &iwr) < 0) {		perror("ioctl[SIOCGIWFRAG(short)]");		return -1;	}	*short_retry = iwr.u.retry.value;	iwr.u.retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;	if (ioctl(drv->ioctl_sock, SIOCGIWRETRY, &iwr) < 0) {		perror("ioctl[SIOCGIWFRAG(long)]");		return -1;	}	*long_retry = iwr.u.retry.value;	return 0;}static int i802_flush(void *priv){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!msg)		return -1;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_DEL_STATION, 0);	/*	 * XXX: FIX! this needs to flush all VLANs too	 */	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,		    if_nametoindex(drv->iface));	return send_and_recv_msgs(drv, msg, NULL, NULL); nla_put_failure:	return -ENOBUFS;}static int get_sta_handler(struct nl_msg *msg, void *arg){	struct nlattr *tb[NL80211_ATTR_MAX + 1];	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));	struct hostap_sta_driver_data *data = arg;	struct nlattr *stats[NL80211_STA_INFO_MAX + 1];	static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {		[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },		[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },		[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },		[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },		[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },	};	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),		  genlmsg_attrlen(gnlh, 0), NULL);	/*	 * TODO: validate the interface and mac address!	 * Otherwise, there's a race condition as soon as	 * the kernel starts sending station notifications.	 */	if (!tb[NL80211_ATTR_STA_INFO]) {		wpa_printf(MSG_DEBUG, "sta stats missing!");		return NL_SKIP;	}	if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,			     tb[NL80211_ATTR_STA_INFO],			     stats_policy)) {		wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");		return NL_SKIP;	}	if (stats[NL80211_STA_INFO_INACTIVE_TIME])		data->inactive_msec =			nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);	if (stats[NL80211_STA_INFO_RX_BYTES])		data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);	if (stats[NL80211_STA_INFO_TX_BYTES])		data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);	if (stats[NL80211_STA_INFO_RX_PACKETS])		data->rx_packets =			nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);	if (stats[NL80211_STA_INFO_TX_PACKETS])		data->tx_packets =			nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);	return NL_SKIP;}static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,			      const u8 *addr){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	os_memset(data, 0, sizeof(*data));	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_GET_STATION, 0);	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));	return send_and_recv_msgs(drv, msg, get_sta_handler, data); nla_put_failure:	return -ENOBUFS;}static int i802_send_eapol(void *priv, const u8 *addr, const u8 *data,			   size_t data_len, int encrypt, const u8 *own_addr){	struct i802_driver_data *drv = priv;	struct ieee80211_hdr *hdr;	size_t len;	u8 *pos;	int res;#if 0 /* FIX */	int qos = sta->flags & WLAN_STA_WME;#else	int qos = 0;#endif	len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +		data_len;	hdr = os_zalloc(len);	if (hdr == NULL) {		printf("malloc() failed for i802_send_data(len=%lu)\n",		       (unsigned long) len);		return -1;	}	hdr->frame_control =		IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);	hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);	if (encrypt)		hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);#if 0 /* To be enabled if qos determination is added above */	if (qos) {		hdr->frame_control |=			host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);	}#endif	memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);	memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);	memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);	pos = (u8 *) (hdr + 1);#if 0 /* To be enabled if qos determination is added above */	if (qos) {		/* add an empty QoS header if needed */		pos[0] = 0;		pos[1] = 0;		pos += 2;	}#endif	memcpy(pos, rfc1042_header, sizeof(rfc1042_header));	pos += sizeof(rfc1042_header);	WPA_PUT_BE16(pos, ETH_P_PAE);	pos += 2;	memcpy(pos, data, data_len);	res = i802_send_frame(drv, (u8 *) hdr, len, encrypt, 0);	free(hdr);	if (res < 0) {		perror("i802_send_eapol: send");		printf("i802_send_eapol - packet len: %lu - failed\n",		       (unsigned long) len);	}	return res;}static int i802_sta_add2(const char *ifname, void *priv,			 struct hostapd_sta_add_params *params){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	int ret = -ENOBUFS;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_NEW_STATION, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,		    if_nametoindex(drv->iface));	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);	NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);	NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,		params->supp_rates);	NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,		    params->listen_interval);#ifdef CONFIG_IEEE80211N	if (params->ht_capabilities) {		NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,			params->ht_capabilities->length,			&params->ht_capabilities->data);	}#endif /* CONFIG_IEEE80211N */	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	if (ret)		wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_NEW_STATION "			   "result: %d (%s)", ret, strerror(-ret));	if (ret == -EEXIST)		ret = 0; nla_put_failure:	return ret;}static int i802_sta_remove(void *priv, const u8 *addr){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	int ret;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_DEL_STATION, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,		    if_nametoindex(drv->iface));	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	if (ret == -ENOENT)		return 0;	return ret; nla_put_failure:	return -ENOBUFS;}static int i802_sta_set_flags(void *priv, const u8 *addr,			      int total_flags, int flags_or, int flags_and){	struct i802_driver_data *drv = priv;	struct nl_msg *msg, *flags = NULL;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	flags = nlmsg_alloc();	if (!flags) {		nlmsg_free(msg);		return -ENOMEM;	}	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_SET_STATION, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,		    if_nametoindex(drv->iface));	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);	if (total_flags & WLAN_STA_AUTHORIZED || !drv->ieee802_1x_active)		NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);	if (total_flags & WLAN_STA_WME)		NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);	if (total_flags & WLAN_STA_SHORT_PREAMBLE)		NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);	if (total_flags & WLAN_STA_MFP)		NLA_PUT_FLAG(flags, NL80211_STA_FLAG_MFP);	if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))		goto nla_put_failure;	nlmsg_free(flags);	return send_and_recv_msgs(drv, msg, NULL, NULL); nla_put_failure: 	nlmsg_free(flags);	return -ENOBUFS;}static int i802_set_regulatory_domain(void *priv, unsigned int rd){	return -1;}static int i802_set_tx_queue_params(void *priv, int queue, int aifs,				    int cw_min, int cw_max, int burst_time){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	struct nlattr *txq, *params;	msg = nlmsg_alloc();	if (!msg)		return -1;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_SET_WIPHY, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));	txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);	if (!txq)		goto nla_put_failure;	/* We are only sending parameters for a single TXQ at a time */	params = nla_nest_start(msg, 1);	if (!params)		goto nla_put_failure;	NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, queue);	/* Burst time is configured in units of 0.1 msec and TXOP parameter in	 * 32 usec, so need to convert the value here. */	NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);	NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);	NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);	NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);	nla_nest_end(msg, params);	nla_nest_end(msg, txq);	if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)		return 0; nla_put_failure:	return -1;}static void nl80211_remove_iface(struct i802_driver_data *drv, int ifidx){	struct nl_msg *msg;	/* stop listening for EAPOL on this interface */	del_ifidx(drv, ifidx);	msg = nlmsg_alloc();	if (!msg)		goto nla_put_failure;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_DEL_INTERFACE, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);	if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)		return; nla_put_failure:	printf("Failed to remove interface.\n");}static int nl80211_create_iface(struct i802_driver_data *drv,				const char *ifname,				enum nl80211_iftype iftype,				const u8 *addr){	struct nl_msg *msg, *flags = NULL;	int ifidx;	struct ifreq ifreq;	struct iwreq iwr;	int ret = -ENOBUFS;	msg = nlmsg_alloc();	if (!msg)		return -1;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_NEW_INTERFACE, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,		    if_nametoindex(drv->hapd->conf->iface));	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);	if (iftype == NL80211_IFTYPE_MONITOR) {		int err;		flags = nlmsg_alloc();		if (!flags)			goto nla_put_failure;		NLA_PUT_FLAG(flags, NL80211_MNTR_FLAG_COOK_FRAMES);		err = nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);		nlmsg_free(flags);		if (err)			goto nla_put_failure;	}	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	if (ret) { nla_put_failure:		printf("Failed to create interface %s.\n", ifname);		return ret;	}	ifidx = if_nametoindex(ifname);	if (ifidx <= 0)		return -1;	/* start listening for EAPOL on this interface */	add_ifidx(drv, ifidx);	if (addr) {		switch (iftype) {		case NL80211_IFTYPE_AP:			os_strlcpy(ifreq.ifr_name, ifname, IFNAMSIZ);			memcpy(ifreq.ifr_hwaddr.sa_data, addr, ETH_ALEN);			ifreq.ifr_hwaddr.sa_family = ARPHRD_ETHER;			if (ioctl(drv->ioctl_sock, SIOCSIFHWADDR, &ifreq)) {				nl80211_remove_iface(drv, ifidx);				return -1;			}			break;		case NL80211_IFTYPE_WDS:			memset(&iwr, 0, sizeof(iwr));			os_strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);			iwr.u.addr.sa_family = ARPHRD_ETHER;			memcpy(iwr.u.addr.sa_data, addr, ETH_ALEN);			if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr))				return -1;			break;		default:

⌨️ 快捷键说明

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