#include <net/if.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* The L2 protocols */
-#include <linux/wireless.h>
+#include "wireless_copy.h"
#include <net/if_arp.h>
#include "hostapd.h"
}
-static int i802_set_encryption(const char *iface, void *priv, const char *alg,
- const u8 *addr, int idx, const u8 *key,
- size_t key_len, int txkey)
+static int nl_set_encr(int ifindex, struct i802_driver_data *drv,
+ const char *alg, const u8 *addr, int idx, const u8 *key,
+ size_t key_len, int txkey)
{
- struct i802_driver_data *drv = priv;
struct nl_msg *msg;
int ret = -1;
int err = 0;
NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02);
else if (strcmp(alg, "CCMP") == 0)
NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);
- else
+ else if (strcmp(alg, "IGTK") == 0)
+ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC06);
+ else {
+ wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
+ "algorithm '%s'", __func__, alg);
goto out;
+ }
}
if (addr)
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
(err = nl_wait_for_ack(drv->nl_handle)) < 0) {
if (err != -ENOENT) {
- err = 0;
+ ret = 0;
goto out;
}
}
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
0, NL80211_CMD_SET_KEY, 0);
NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
+#ifdef NL80211_MFP_PENDING
+ if (strcmp(alg, "IGTK") == 0)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
+ else
+ NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
+#else /* NL80211_MFP_PENDING */
NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
+#endif /* NL80211_MFP_PENDING */
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
(err = nl_wait_for_ack(drv->nl_handle)) < 0) {
if (err != -ENOENT) {
- err = 0;
+ ret = 0;
goto out;
}
}
}
+static int i802_set_encryption(const char *iface, void *priv, const char *alg,
+ const u8 *addr, int idx, const u8 *key,
+ size_t key_len, int txkey)
+{
+ struct i802_driver_data *drv = priv;
+ int ret;
+
+ ret = nl_set_encr(if_nametoindex(iface), drv, alg, addr, idx, key,
+ key_len, txkey);
+ if (ret < 0)
+ return ret;
+
+ if (strcmp(alg, "IGTK") == 0) {
+ ret = nl_set_encr(drv->monitor_ifidx, drv, alg, addr, idx, key,
+ key_len, txkey);
+ }
+
+ return ret;
+}
+
+
static inline int min_int(int a, int b)
{
if (a < b)
static int get_key_handler(struct nl_msg *msg, void *arg)
{
- struct nlattr *tb[NL80211_ATTR_MAX];
+ struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
if (total_flags & WLAN_STA_SHORT_PREAMBLE)
NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);
+#ifdef NL80211_MFP_PENDING
+ if (total_flags & WLAN_STA_MFP)
+ NLA_PUT_FLAG(flags, NL80211_STA_FLAG_MFP);
+#endif /* NL80211_MFP_PENDING */
+
if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))
goto nla_put_failure;
drv->beacon_int = value;
+ if (!drv->beacon_set)
+ return 0;
+
msg = nlmsg_alloc();
if (!msg)
goto out;
struct nl_msg *msg;
int err = -1;
struct nl_cb *cb = NULL;
- int finished;
+ int finished = 0;
struct phy_info_arg result = {
.num_modes = num_modes,
.modes = NULL,
return 0;
}
-
+
static int i802_init_sockets(struct i802_driver_data *drv, const u8 *bssid)
{
return -1;
}
- memset(&ifr, 0, sizeof(ifr));
- os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
- if (ioctl(drv->ioctl_sock, SIOCGIFHWADDR, &ifr) != 0) {
+ memset(&ifr, 0, sizeof(ifr));
+ os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
+ if (ioctl(drv->ioctl_sock, SIOCGIFHWADDR, &ifr) != 0) {
perror("ioctl(SIOCGIFHWADDR)");
return -1;
- }
+ }
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
printf("Invalid HW-addr family 0x%04x\n",