summaryrefslogtreecommitdiffstats
path: root/package/hostapd/patches/004-use-nl80211-for-get-key.patch
blob: 142c1939d279ae60cde60a5b521a298a982a2bb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
---
 hostapd/driver_devicescape.c |   96 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 76 insertions(+), 20 deletions(-)

--- hostap.orig/hostapd/driver_devicescape.c	2007-11-09 13:41:13.000000000 +0100
+++ hostap/hostapd/driver_devicescape.c	2007-11-09 13:41:14.000000000 +0100
@@ -228,33 +228,89 @@ static int i802_set_encryption(const cha
 	return ret;
 }
 
+static inline int min_int(int a, int b)
+{
+	if (a<b)
+		return a;
+	return b;
+}
+
+static int get_key_handler(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *tb[NL80211_ATTR_MAX];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+
+	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+	/*
+	 * TODO: validate the key index and mac address!
+	 * Otherwise, there's a race condition as soon as
+	 * the kernel starts sending key notifications.
+	 */
+
+	if (tb[NL80211_ATTR_KEY_SEQ])
+		memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
+		       min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
+	return NL_SKIP;
+}
+
+static int ack_wait_handler(struct nl_msg *msg, void *arg)
+{
+	int *finished = arg;
+
+	*finished = 1;
+	return NL_STOP;
+}
 
 static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
 			   int idx, u8 *seq)
 {
 	struct i802_driver_data *drv = priv;
-	struct prism2_hostapd_param *param;
-	size_t param_len;
-	int ret;
+	struct nl_msg *msg;
+	struct nl_cb *cb = NULL;
+	int ret = -1;
+	int err = 0;
+	int finished = 0;
 
-	param_len = sizeof(struct prism2_hostapd_param) + 32;
-	param = os_zalloc(param_len);
-	if (param == NULL)
-		return -1;
+	msg = nlmsg_alloc();
+	if (!msg)
+		goto out;
 
-	param->cmd = PRISM2_GET_ENCRYPTION;
-	if (addr == NULL)
-		memset(param->sta_addr, 0xff, ETH_ALEN);
-	else
-		memcpy(param->sta_addr, addr, ETH_ALEN);
-	param->u.crypt.idx = idx;
-
-	ret = hostapd_ioctl_iface(iface, drv, param, param_len);
-	if (ret == 0) {
-		memcpy(seq, param->u.crypt.seq_counter,
-		       HOSTAP_SEQ_COUNTER_SIZE);
-	}
-	free(param);
+	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
+		    0, NL80211_CMD_GET_KEY, 0);
+
+	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));
+
+	cb = nl_cb_alloc(NL_CB_CUSTOM);
+	if (!cb)
+		goto out;
+
+	memset(seq, 0, 6);
+
+	if (nl_send_auto_complete(drv->nl_handle, msg) < 0)
+		goto out;
+
+	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_key_handler, seq);
+	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
+
+	err = nl_recvmsgs(drv->nl_handle, cb);
+
+	if (!finished)
+		err = nl_wait_for_ack(drv->nl_handle);
+
+	if (err < 0)
+		goto out;
+
+	ret = 0;
+
+ out:
+	nl_cb_put(cb);
+ nla_put_failure:
+	nlmsg_free(msg);
 	return ret;
 }