Add hostapd support for nl80211 (mac80211 stack)
[openwrt/openwrt.git] / package / hostapd / patches / 005-use-nl80211-for-get-key.patch
1 ---
2 hostapd/driver_devicescape.c | 96 ++++++++++++++++++++++++++++++++++---------
3 1 file changed, 76 insertions(+), 20 deletions(-)
4
5 --- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:13.000000000 +0100
6 +++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:14.000000000 +0100
7 @@ -228,33 +228,89 @@ static int i802_set_encryption(const cha
8 return ret;
9 }
10
11 +static inline int min_int(int a, int b)
12 +{
13 + if (a<b)
14 + return a;
15 + return b;
16 +}
17 +
18 +static int get_key_handler(struct nl_msg *msg, void *arg)
19 +{
20 + struct nlattr *tb[NL80211_ATTR_MAX];
21 + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
22 +
23 + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
24 + genlmsg_attrlen(gnlh, 0), NULL);
25 +
26 + /*
27 + * TODO: validate the key index and mac address!
28 + * Otherwise, there's a race condition as soon as
29 + * the kernel starts sending key notifications.
30 + */
31 +
32 + if (tb[NL80211_ATTR_KEY_SEQ])
33 + memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
34 + min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
35 + return NL_SKIP;
36 +}
37 +
38 +static int ack_wait_handler(struct nl_msg *msg, void *arg)
39 +{
40 + int *finished = arg;
41 +
42 + *finished = 1;
43 + return NL_STOP;
44 +}
45
46 static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
47 int idx, u8 *seq)
48 {
49 struct i802_driver_data *drv = priv;
50 - struct prism2_hostapd_param *param;
51 - size_t param_len;
52 - int ret;
53 + struct nl_msg *msg;
54 + struct nl_cb *cb = NULL;
55 + int ret = -1;
56 + int err = 0;
57 + int finished = 0;
58
59 - param_len = sizeof(struct prism2_hostapd_param) + 32;
60 - param = os_zalloc(param_len);
61 - if (param == NULL)
62 - return -1;
63 + msg = nlmsg_alloc();
64 + if (!msg)
65 + goto out;
66
67 - param->cmd = PRISM2_GET_ENCRYPTION;
68 - if (addr == NULL)
69 - memset(param->sta_addr, 0xff, ETH_ALEN);
70 - else
71 - memcpy(param->sta_addr, addr, ETH_ALEN);
72 - param->u.crypt.idx = idx;
73 -
74 - ret = hostapd_ioctl_iface(iface, drv, param, param_len);
75 - if (ret == 0) {
76 - memcpy(seq, param->u.crypt.seq_counter,
77 - HOSTAP_SEQ_COUNTER_SIZE);
78 - }
79 - free(param);
80 + genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
81 + 0, NL80211_CMD_GET_KEY, 0);
82 +
83 + if (addr)
84 + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
85 + NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
86 + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
87 +
88 + cb = nl_cb_alloc(NL_CB_CUSTOM);
89 + if (!cb)
90 + goto out;
91 +
92 + memset(seq, 0, 6);
93 +
94 + if (nl_send_auto_complete(drv->nl_handle, msg) < 0)
95 + goto out;
96 +
97 + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_key_handler, seq);
98 + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
99 +
100 + err = nl_recvmsgs(drv->nl_handle, cb);
101 +
102 + if (!finished)
103 + err = nl_wait_for_ack(drv->nl_handle);
104 +
105 + if (err < 0)
106 + goto out;
107 +
108 + ret = 0;
109 +
110 + out:
111 + nl_cb_put(cb);
112 + nla_put_failure:
113 + nlmsg_free(msg);
114 return ret;
115 }
116