taxonomy: implement v3 signature format.
The TX Power levels from the Association Request
appear to be very useful for disambiguating
devices which are otherwise very similar, for example:
+ Apple iPhone 5 from iPad 4th gen from iPad Mini 2nd gen
+ Samsung Galaxy Note 4 from Galaxy S5
Also include the capabilities field from the Association
Request, as that is more distinctive than we believed
at first.
Extended Capabilities can be longer than 4 bytes.
Include whatever is there.
Change-Id: Ife1fa3f69c1c93be5745edd0347707171faedad9
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index bab2e91..438cf81 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -359,7 +359,7 @@
wpa_printf(MSG_ERROR, "open %s failed", tmpfile);
return;
}
- fprintf(f, "wifi|probe:%s|assoc:%s", sta->probe_ie_taxonomy,
+ fprintf(f, "wifi3|probe:%s|assoc:%s", sta->probe_ie_taxonomy,
sta->assoc_ie_taxonomy);
fclose(f);
if (rename(tmpfile, filename)) {
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index bd88c91..d0e04da 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -169,7 +169,7 @@
u8 last_subtype;
#ifdef CONFIG_CLIENT_TAXONOMY
-#define TAXONOMY_STRING_LEN 768
+#define TAXONOMY_STRING_LEN 1536
char probe_ie_taxonomy[TAXONOMY_STRING_LEN];
char assoc_ie_taxonomy[TAXONOMY_STRING_LEN];
#endif /* CONFIG_CLIENT_TAXONOMY */
diff --git a/src/ap/taxonomy.c b/src/ap/taxonomy.c
index b70dcb7..5e1fd2a 100644
--- a/src/ap/taxonomy.c
+++ b/src/ap/taxonomy.c
@@ -75,6 +75,7 @@
}
static void ie_to_string(char *fstr, size_t fstr_len,
+ const char *capability,
const u8 *ie, size_t ie_len)
{
size_t flen = fstr_len - 1;
@@ -85,7 +86,9 @@
char vhtrxmcs[10 + 8 + 1]; // ",vhtrxmcs:" + %08x + trailing NUL
char vhttxmcs[10 + 8 + 1]; // ",vhttxmcs:" + %08x + trailing NUL
char intwrk[8 + 2 + 1]; // ",intwrk:" + %02hx + trailing NUL
- char extcap[8 + 8 + 1]; // ",extcap:" + %08x + trailing NUL
+ #define MAX_EXTCAP 254
+ char extcap[8 + (2 * MAX_EXTCAP) + 1]; // ",extcap:" + hex + trailing NUL
+ char txpow[7 + 4 + 1]; // ",txpow:" + %04hx + trailing NUL
#define WPS_NAME_LEN 32
char wps[WPS_NAME_LEN + 5 + 1]; // room to prepend ",wps:" + trailing NUL
int num = 0;
@@ -98,6 +101,7 @@
memset(vhttxmcs, 0, sizeof(vhttxmcs));
memset(intwrk, 0, sizeof(intwrk));
memset(extcap, 0, sizeof(extcap));
+ memset(txpow, 0, sizeof(txpow));
memset(wps, 0, sizeof(wps));
fstr[0] = '\0';
@@ -176,12 +180,24 @@
/* Interworking */
snprintf(intwrk, sizeof(intwrk), ",intwrk:%02hx", *ie);
}
- if ((id == 127) && (elen >= 4)) {
+ if (id == 127) {
/* Extended Capabilities */
- u32 ext;
- memcpy(&ext, ie, sizeof(ext));
- snprintf(extcap, sizeof(extcap), ",extcap:%08x",
- le_to_host32(ext));
+ int i;
+ int len = (elen < MAX_EXTCAP) ? elen : MAX_EXTCAP;
+ char *p = extcap;
+
+ p += snprintf(extcap, sizeof(extcap), ",extcap:");
+ for (i = 0; i < len; ++i) {
+ int lim = sizeof(extcap) - strlen(extcap);
+ p += snprintf(p, lim, "%02x", *(ie + i));
+ }
+ }
+ if ((id == 33) && (elen == 2)) {
+ /* TX Power */
+ u16 p;
+ memcpy(&p, ie, sizeof(p));
+ snprintf(txpow, sizeof(txpow), ",txpow:%04hx",
+ le_to_host16(p));
}
snprintf(tagbuf, sizeof(tagbuf), "%s%d", sep, id);
@@ -194,6 +210,10 @@
ie_len -= elen;
}
+ if (capability) {
+ strncat(fstr, capability, flen);
+ flen = fstr_len - strlen(fstr) - 1;
+ }
if (strlen(htcap)) {
strncat(fstr, htcap, flen);
flen = fstr_len - strlen(fstr) - 1;
@@ -218,6 +238,10 @@
strncat(fstr, vhttxmcs, flen);
flen = fstr_len - strlen(fstr) - 1;
}
+ if (strlen(txpow)) {
+ strncat(fstr, txpow, flen);
+ flen = fstr_len - strlen(fstr) - 1;
+ }
if (strlen(intwrk)) {
strncat(fstr, intwrk, flen);
flen = fstr_len - strlen(fstr) - 1;
@@ -238,16 +262,18 @@
const u8 *ie, size_t ie_len)
{
ie_to_string(sta->probe_ie_taxonomy,
- sizeof(sta->probe_ie_taxonomy),
- ie, ie_len);
+ sizeof(sta->probe_ie_taxonomy),
+ NULL, ie, ie_len);
}
void hostapd_taxonomy_assoc_req(struct sta_info *sta,
const u8 *ie, size_t ie_len)
{
+ char cap[5 + 4 + 1]; // ",cap:" + %04x + trailing NUL
+ snprintf(cap, sizeof(cap), ",cap:%04hx", sta->capability);
ie_to_string(sta->assoc_ie_taxonomy,
sizeof(sta->assoc_ie_taxonomy),
- ie, ie_len);
+ cap, ie, ie_len);
}
/* vim: set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab : */