aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2016-04-06 16:42:18 (GMT)
committerJouni Malinen <j@w1.fi>2016-04-17 14:45:14 (GMT)
commitcf667c66aceb796da6c5ee952a140cd7b009b9cc (patch)
tree0f0aa67ef051ea703674a9a02560303be5e503b0 /wpa_supplicant
parent00ed0aa2dd5d65053b9b1d65467b2dba69183171 (diff)
downloadhostap-cf667c66aceb796da6c5ee952a140cd7b009b9cc.zip
hostap-cf667c66aceb796da6c5ee952a140cd7b009b9cc.tar.gz
hostap-cf667c66aceb796da6c5ee952a140cd7b009b9cc.tar.bz2
RRM: Modify the processing of a received neighbor report
Parse a received neighbor report and report for each neighbor report the data received for it: RRM-NEIGHBOR-REP-RECEIVED bssid=<BSSID> info=0x<hex> op_class=<class> chan=<chan> [lci=hex] [civic=hex] Note that this modifies the previous format that originally reported only the length of the received frame. Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ctrl_iface.c100
1 files changed, 94 insertions, 6 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index e450e3b..3c97819 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -8236,15 +8236,103 @@ static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd)
static void wpas_ctrl_neighbor_rep_cb(void *ctx, struct wpabuf *neighbor_rep)
{
struct wpa_supplicant *wpa_s = ctx;
+ size_t len;
+ const u8 *data;
- if (neighbor_rep) {
- wpa_msg_ctrl(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_RXED
- "length=%u",
- (unsigned int) wpabuf_len(neighbor_rep));
- wpabuf_free(neighbor_rep);
- } else {
+ /*
+ * Neighbor Report element (IEEE P802.11-REVmc/D5.0)
+ * BSSID[6]
+ * BSSID Information[4]
+ * Operating Class[1]
+ * Channel Number[1]
+ * PHY Type[1]
+ * Optional Subelements[variable]
+ */
+#define NR_IE_MIN_LEN (ETH_ALEN + 4 + 1 + 1 + 1)
+
+ if (!neighbor_rep || wpabuf_len(neighbor_rep) == 0) {
wpa_msg_ctrl(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_FAILED);
+ goto out;
+ }
+
+ data = wpabuf_head_u8(neighbor_rep);
+ len = wpabuf_len(neighbor_rep);
+
+ while (len >= 2 + NR_IE_MIN_LEN) {
+ const u8 *nr;
+ char lci[256 * 2 + 1];
+ char civic[256 * 2 + 1];
+ u8 nr_len = data[1];
+ const u8 *pos = data, *end;
+
+ if (pos[0] != WLAN_EID_NEIGHBOR_REPORT ||
+ nr_len < NR_IE_MIN_LEN) {
+ wpa_printf(MSG_DEBUG,
+ "CTRL: Invalid Neighbor Report element: id=%u len=%u",
+ data[0], nr_len);
+ goto out;
+ }
+
+ if (2U + nr_len > len) {
+ wpa_printf(MSG_DEBUG,
+ "CTRL: Invalid Neighbor Report element: id=%u len=%zu nr_len=%u",
+ data[0], len, nr_len);
+ goto out;
+ }
+ pos += 2;
+ end = pos + nr_len;
+
+ nr = pos;
+ pos += NR_IE_MIN_LEN;
+
+ lci[0] = '\0';
+ civic[0] = '\0';
+ while (end - pos > 2) {
+ u8 s_id, s_len;
+
+ s_id = *pos++;
+ s_len = *pos++;
+ if (s_len > end - pos)
+ goto out;
+ if (s_id == WLAN_EID_MEASURE_REPORT && s_len > 3) {
+ /* Measurement Token[1] */
+ /* Measurement Report Mode[1] */
+ /* Measurement Type[1] */
+ /* Measurement Report[variable] */
+ switch (pos[2]) {
+ case MEASURE_TYPE_LCI:
+ if (lci[0])
+ break;
+ wpa_snprintf_hex(lci, sizeof(lci),
+ pos, s_len);
+ break;
+ case MEASURE_TYPE_LOCATION_CIVIC:
+ if (civic[0])
+ break;
+ wpa_snprintf_hex(civic, sizeof(civic),
+ pos, s_len);
+ break;
+ }
+ }
+
+ pos += s_len;
+ }
+
+ wpa_msg(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_RXED
+ "bssid=" MACSTR
+ " info=0x%x op_class=%u chan=%u phy_type=%u%s%s%s%s",
+ MAC2STR(nr), WPA_GET_LE32(nr + ETH_ALEN),
+ nr[ETH_ALEN + 4], nr[ETH_ALEN + 5],
+ nr[ETH_ALEN + 6],
+ lci[0] ? " lci=" : "", lci,
+ civic[0] ? " civic=" : "", civic);
+
+ data = end;
+ len -= 2 + nr_len;
}
+
+out:
+ wpabuf_free(neighbor_rep);
}