--- hostapd/driver_devicescape.c | 93 ++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 26 deletions(-) --- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:12.000000000 +0100 +++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:13.000000000 +0100 @@ -150,38 +150,79 @@ static int i802_set_encryption(const cha size_t key_len, int txkey) { struct i802_driver_data *drv = priv; - struct prism2_hostapd_param *param; - u8 *buf; - size_t blen; - int ret = 0; + struct nl_msg *msg; + int ret = -1; + int err = 0; - blen = sizeof(*param) + key_len; - buf = os_zalloc(blen); - if (buf == NULL) - return -1; + msg = nlmsg_alloc(); + if (!msg) + goto out; - param = (struct prism2_hostapd_param *) buf; - param->cmd = PRISM2_SET_ENCRYPTION; - if (addr == NULL) - memset(param->sta_addr, 0xff, ETH_ALEN); - else - memcpy(param->sta_addr, addr, ETH_ALEN); - os_strlcpy((char *) param->u.crypt.alg, alg, - HOSTAP_CRYPT_ALG_NAME_LEN); - param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; - param->u.crypt.idx = idx; - param->u.crypt.key_len = key_len; - memcpy(param->u.crypt.key, key, key_len); + if (strcmp(alg, "none") == 0) { + genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, + 0, NL80211_CMD_DEL_KEY, 0); + } else { + genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, + 0, NL80211_CMD_NEW_KEY, 0); + NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key); + if (strcmp(alg, "WEP") == 0) { + if (key_len == 5) + NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, + 0x000FAC01); + else + NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, + 0x000FAC05); + } else if (strcmp(alg, "TKIP") == 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 + goto out; + } - if (hostapd_ioctl_iface(iface, drv, param, blen) && errno != ENOENT) { - printf("%s: Failed to set encryption to alg '%s' addr " MACSTR - " errno=%d\n", - iface, alg, MAC2STR(param->sta_addr), errno); - ret = -1; + 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)); + + if (nl_send_auto_complete(drv->nl_handle, msg) < 0 || + (err = nl_wait_for_ack(drv->nl_handle)) < 0) { + if (err != -ENOENT) { + err = 0; + goto out; + } } - free(buf); + if (!txkey) { + ret = 0; + goto out; + } + + nlmsg_free(msg); + + msg = nlmsg_alloc(); + if (!msg) + 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_FLAG(msg, NL80211_ATTR_KEY_DEFAULT); + + if (nl_send_auto_complete(drv->nl_handle, msg) < 0 || + (err = nl_wait_for_ack(drv->nl_handle)) < 0) { + if (err != -ENOENT) { + err = 0; + goto out; + } + } + + ret = 0; + + out: + nla_put_failure: + nlmsg_free(msg); return ret; }