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

📄 driver_nl80211.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* nothing */			break;		}	}	return ifidx;}static int i802_bss_add(void *priv, const char *ifname, const u8 *bssid){	int ifidx;	/*	 * The kernel supports that when the low-level driver does,	 * but we currently don't because we need per-BSS data that	 * currently we can't handle easily.	 */	return -1;	ifidx = nl80211_create_iface(priv, ifname, NL80211_IFTYPE_AP, bssid);	if (ifidx < 0)		return -1;	if (hostapd_set_iface_flags(priv, ifname, 1)) {		nl80211_remove_iface(priv, ifidx);		return -1;	}	return 0;}static int i802_bss_remove(void *priv, const char *ifname){	nl80211_remove_iface(priv, if_nametoindex(ifname));	return 0;}static int i802_set_beacon(const char *iface, void *priv,			   u8 *head, size_t head_len,			   u8 *tail, size_t tail_len){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	u8 cmd = NL80211_CMD_NEW_BEACON;	int ret;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	if (drv->beacon_set)		cmd = NL80211_CMD_SET_BEACON;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, cmd, 0);	NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);	NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));	NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, drv->beacon_int);	if (!drv->dtim_period)		drv->dtim_period = 2;	NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	if (!ret)		drv->beacon_set = 1;	return ret; nla_put_failure:	return -ENOBUFS;}static int i802_del_beacon(struct i802_driver_data *drv){	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_DEL_BEACON, 0);	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 i802_set_ieee8021x(const char *ifname, void *priv, int enabled){	struct i802_driver_data *drv = priv;	/*	 * FIXME: This needs to be per interface (BSS)	 */	drv->ieee802_1x_active = enabled;	return 0;}static int i802_set_privacy(const char *ifname, void *priv, int enabled){	struct i802_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);	iwr.u.param.flags = IW_AUTH_PRIVACY_INVOKED;	iwr.u.param.value = enabled;	ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr);	/* ignore errors, the kernel/driver might not care */	return 0;}static int i802_set_internal_bridge(void *priv, int value){	return -1;}static int i802_set_beacon_int(void *priv, int value){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	drv->beacon_int = value;	if (!drv->beacon_set)		return 0;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_SET_BEACON, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));	NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, value);	return send_and_recv_msgs(drv, msg, NULL, NULL); nla_put_failure:	return -ENOBUFS;}static int i802_set_dtim_period(const char *iface, void *priv, int value){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_SET_BEACON, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));	drv->dtim_period = value;	NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);	return send_and_recv_msgs(drv, msg, NULL, NULL); nla_put_failure:	return -ENOBUFS;}static int i802_set_bss(void *priv, int cts, int preamble, int slot){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,		    NL80211_CMD_SET_BSS, 0);	if (cts >= 0)		NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);	if (preamble >= 0)		NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);	if (slot >= 0)		NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);	/* TODO: multi-BSS support */	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 i802_set_cts_protect(void *priv, int value){	return i802_set_bss(priv, value, -1, -1);}static int i802_set_preamble(void *priv, int value){	return i802_set_bss(priv, -1, value, -1);}static int i802_set_short_slot_time(void *priv, int value){	return i802_set_bss(priv, -1, -1, value);}static enum nl80211_iftype i802_if_type(enum hostapd_driver_if_type type){	switch (type) {	case HOSTAPD_IF_VLAN:		return NL80211_IFTYPE_AP_VLAN;	case HOSTAPD_IF_WDS:		return NL80211_IFTYPE_WDS;	}	return -1;}static int i802_if_add(const char *iface, void *priv,		       enum hostapd_driver_if_type type, char *ifname,		       const u8 *addr){	if (nl80211_create_iface(priv, ifname, i802_if_type(type), addr) < 0)		return -1;	return 0;}static int i802_if_update(void *priv, enum hostapd_driver_if_type type,			  char *ifname, const u8 *addr){	/* unused at the moment */	return -1;}static int i802_if_remove(void *priv, enum hostapd_driver_if_type type,			  const char *ifname, const u8 *addr){	nl80211_remove_iface(priv, if_nametoindex(ifname));	return 0;}struct phy_info_arg {	u16 *num_modes;	struct hostapd_hw_modes *modes;};static int phy_info_handler(struct nl_msg *msg, void *arg){	struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));	struct phy_info_arg *phy_info = arg;	struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];	struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];	static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {		[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },		[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },		[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },		[NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },		[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },		[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },	};	struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];	static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {		[NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },		[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG },	};	struct nlattr *nl_band;	struct nlattr *nl_freq;	struct nlattr *nl_rate;	int rem_band, rem_freq, rem_rate;	struct hostapd_hw_modes *mode;	int idx, mode_is_set;	nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),		  genlmsg_attrlen(gnlh, 0), NULL);	if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])		return NL_SKIP;	nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) {		mode = realloc(phy_info->modes, (*phy_info->num_modes + 1) * sizeof(*mode));		if (!mode)			return NL_SKIP;		phy_info->modes = mode;		mode_is_set = 0;		mode = &phy_info->modes[*(phy_info->num_modes)];		memset(mode, 0, sizeof(*mode));		*(phy_info->num_modes) += 1;		nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),			  nla_len(nl_band), NULL);		if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {			mode->ht_capab = nla_get_u16(				tb_band[NL80211_BAND_ATTR_HT_CAPA]);		}		nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {			nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),				  nla_len(nl_freq), freq_policy);			if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])				continue;			mode->num_channels++;		}		mode->channels = calloc(mode->num_channels, sizeof(struct hostapd_channel_data));		if (!mode->channels)			return NL_SKIP;		idx = 0;		nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {			nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),				  nla_len(nl_freq), freq_policy);			if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])				continue;			mode->channels[idx].freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);			mode->channels[idx].flag = 0;			if (!mode_is_set) {				/* crude heuristic */				if (mode->channels[idx].freq < 4000)					mode->mode = HOSTAPD_MODE_IEEE80211B;				else					mode->mode = HOSTAPD_MODE_IEEE80211A;				mode_is_set = 1;			}			/* crude heuristic */			if (mode->channels[idx].freq < 4000)				if (mode->channels[idx].freq == 2848)					mode->channels[idx].chan = 14;				else					mode->channels[idx].chan = (mode->channels[idx].freq - 2407) / 5;			else				mode->channels[idx].chan = mode->channels[idx].freq/5 - 1000;			if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])				mode->channels[idx].flag |=					HOSTAPD_CHAN_DISABLED;			if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])				mode->channels[idx].flag |=					HOSTAPD_CHAN_PASSIVE_SCAN;			if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])				mode->channels[idx].flag |=					HOSTAPD_CHAN_NO_IBSS;			if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])				mode->channels[idx].flag |=					HOSTAPD_CHAN_RADAR;			if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] &&			    !tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])				mode->channels[idx].max_tx_power =					nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) / 100;			idx++;		}		nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {			nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),				  nla_len(nl_rate), rate_policy);			if (!tb_rate[NL80211_BITRATE_ATTR_RATE])				continue;			mode->num_rates++;		}		mode->rates = calloc(mode->num_rates, sizeof(struct hostapd_rate_data));		if (!mode->rates)			return NL_SKIP;		idx = 0;		nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {			nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),				  nla_len(nl_rate), rate_policy);			if (!tb_rate[NL80211_BITRATE_ATTR_RATE])				continue;			mode->rates[idx].rate = nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE]);			/* crude heuristic */			if (mode->mode == HOSTAPD_MODE_IEEE80211B &&			    mode->rates[idx].rate > 200)				mode->mode = HOSTAPD_MODE_IEEE80211G;			if (tb_rate[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE])				mode->rates[idx].flags |= HOSTAPD_RATE_PREAMBLE2;			idx++;		}	}	return NL_SKIP;}static struct hostapd_hw_modes *i802_add_11b(struct hostapd_hw_modes *modes,					     u16 *num_modes){	u16 m;	struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;	int i, mode11g_idx = -1;	/* If only 802.11g mode is included, use it to construct matching	 * 802.11b mode data. */	for (m = 0; m < *num_modes; m++) {		if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)			return modes; /* 802.11b already included */		if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)			mode11g_idx = m;	}	if (mode11g_idx < 0)		return modes; /* 2.4 GHz band not supported at all */	nmodes = os_realloc(modes, (*num_modes + 1) * sizeof(*nmodes));	if (nmodes == NULL)		return modes; /* Could not add 802.11b mode */	mode = &nmodes[*num_modes];	os_memset(mode, 0, sizeof(*mode));	(*num_modes)++;	modes = nmodes;	mode->mode = HOSTAPD_MODE_IEEE80211B;	mode11g = &modes[mode11g_idx];	mode->num_channels = mode11g->num_channels;	mode->channels = os_malloc(mode11g->num_channels *				   sizeof(struct hostapd_channel_data));	if (mode->channels == NULL) {		(*num_modes)--;		return modes; /* Could not add 802.11b mode */	}	os_memcpy(mode->channels, mode11g->channels,		  mode11g->num_channels * sizeof(struct hostapd_channel_data));	mode->num_rates = 0;	mode->rates = os_malloc(4 * sizeof(struct hostapd_rate_data));	if (mode->rates == NULL) {		os_free(mode->channels);		(*num_modes)--;		return modes; /* Could not add 802.11b mode */	}	for (i = 0; i < mode11g->num_rates; i++) {		if (mode11g->rates[i].rate > 110 ||		    mode11g->rates[i].flags &		    (HOSTAPD_RATE_ERP | HOSTAPD_RATE_OFDM))			continue;		mode->rates[mode->num_rates] = mode11g->rates[i];		mode->num_rates++;		if (mode->num_rates == 4)			break;	}	if (mode->num_rates == 0) {		os_free(mode->channels);		os_free(mode->rates);		(*num_modes)--;		return modes; /* No 802.11b rates */	}	wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "		   "information");	return modes;}static struct hostapd_hw_modes *i802_get_hw_feature_data(void *priv,							 u16 *num_modes,							 u16 *flags){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	struct phy_info_arg result = {		.num_modes = num_modes,		.modes = NULL,	};	*num_modes = 0;	*flags = 0;	msg = nlmsg_alloc();	if (!msg)		return NULL;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_GET_WIPHY, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));	if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0)		return i802_add_11b(result.modes, num_modes); nla_put_failure:	return NULL;}static int i802_set_sta_vlan(void *priv, const u8 *addr,			     const char *ifname, int vlan_id){	struct i802_driver_data *drv = priv;	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!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));

⌨️ 快捷键说明

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