aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAvraham Stern <avraham.stern@intel.com>2017-03-08 12:37:39 (GMT)
committerJouni Malinen <j@w1.fi>2017-03-11 08:36:15 (GMT)
commite044a9d1e0b23c1d8193065469983374505acaf2 (patch)
treec0c3c8306e234fe0da1fa4067acee9cd98844c71 /src
parent13bf18eda56fc64abfdb481caeeae9d9a7d18ba8 (diff)
downloadhostap-e044a9d1e0b23c1d8193065469983374505acaf2.zip
hostap-e044a9d1e0b23c1d8193065469983374505acaf2.tar.gz
hostap-e044a9d1e0b23c1d8193065469983374505acaf2.tar.bz2
common: Add candidate list parsing helper function
Add a helper function that parses candidate list from command line arguments. This function will be used (in the following commits) to add a candidate list to BSS transition management query. Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/common/ieee802_11_common.c102
-rw-r--r--src/common/ieee802_11_common.h3
2 files changed, 105 insertions, 0 deletions
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index a8d68e5..4a04915 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -1594,3 +1594,105 @@ const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
return op;
}
+
+
+int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
+ size_t nei_rep_len)
+{
+ u8 *nei_pos = nei_rep;
+ const char *end;
+
+ /*
+ * BSS Transition Candidate List Entries - Neighbor Report elements
+ * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
+ * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
+ */
+ while (pos) {
+ u8 *nei_start;
+ long int val;
+ char *endptr, *tmp;
+
+ pos = os_strstr(pos, " neighbor=");
+ if (!pos)
+ break;
+ if (nei_pos + 15 > nei_rep + nei_rep_len) {
+ wpa_printf(MSG_DEBUG,
+ "Not enough room for additional neighbor");
+ return -1;
+ }
+ pos += 10;
+
+ nei_start = nei_pos;
+ *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
+ nei_pos++; /* length to be filled in */
+
+ if (hwaddr_aton(pos, nei_pos)) {
+ wpa_printf(MSG_DEBUG, "Invalid BSSID");
+ return -1;
+ }
+ nei_pos += ETH_ALEN;
+ pos += 17;
+ if (*pos != ',') {
+ wpa_printf(MSG_DEBUG, "Missing BSSID Information");
+ return -1;
+ }
+ pos++;
+
+ val = strtol(pos, &endptr, 0);
+ WPA_PUT_LE32(nei_pos, val);
+ nei_pos += 4;
+ if (*endptr != ',') {
+ wpa_printf(MSG_DEBUG, "Missing Operating Class");
+ return -1;
+ }
+ pos = endptr + 1;
+
+ *nei_pos++ = atoi(pos); /* Operating Class */
+ pos = os_strchr(pos, ',');
+ if (pos == NULL) {
+ wpa_printf(MSG_DEBUG, "Missing Channel Number");
+ return -1;
+ }
+ pos++;
+
+ *nei_pos++ = atoi(pos); /* Channel Number */
+ pos = os_strchr(pos, ',');
+ if (pos == NULL) {
+ wpa_printf(MSG_DEBUG, "Missing PHY Type");
+ return -1;
+ }
+ pos++;
+
+ *nei_pos++ = atoi(pos); /* PHY Type */
+ end = os_strchr(pos, ' ');
+ tmp = os_strchr(pos, ',');
+ if (tmp && (!end || tmp < end)) {
+ /* Optional Subelements (hexdump) */
+ size_t len;
+
+ pos = tmp + 1;
+ end = os_strchr(pos, ' ');
+ if (end)
+ len = end - pos;
+ else
+ len = os_strlen(pos);
+ if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
+ wpa_printf(MSG_DEBUG,
+ "Not enough room for neighbor subelements");
+ return -1;
+ }
+ if (len & 0x01 ||
+ hexstr2bin(pos, nei_pos, len / 2) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "Invalid neighbor subelement info");
+ return -1;
+ }
+ nei_pos += len / 2;
+ pos = end;
+ }
+
+ nei_start[1] = nei_pos - nei_start - 2;
+ }
+
+ return nei_pos - nei_rep;
+}
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 966eeac..b3a74f1 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -186,4 +186,7 @@ u8 country_to_global_op_class(const char *country, u8 op_class);
const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
+int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
+ size_t nei_rep_len);
+
#endif /* IEEE802_11_COMMON_H */