[PATCH 2/2] Client Taxonomy
Richard Frankel
rofrankel at google.com
Wed Aug 10 16:40:54 PDT 2016
Signed-off-by: Richard Frankel <rofrankel at google.com>
Signed-off-by: Richard Frankel <richard at frankel.tv>
On Wed, Aug 10, 2016 at 6:52 PM, Denton Gentry <dgentry at google.com> wrote:
> taxonomy: store probes in hostapd_sta_info.
>
> A weakness in the initial client taxonomy mechanism is
> from storing both the Probe and Associate in the sta_info_t.
> The sta_info_t is created after a client associates, which
> means that any Probes sent prior to association are not
> retained. The Associate Request has to be seen, and then
> another Probe request after association, before we have
> a signature for the client.
>
> Most clients send lots of Probes (lots and lots and lots
> of Probes, actually), but a few do not. ChromeOS is notably
> sparing in sending Probes, it can take a long time before
> a signature for a ChromeOS device is available.
>
> Store the most recent Probe Request in the hostapd_sta_info
> tracking list. When a sta_info_t is created, move the probe
> from the hostapd_sta_info to the sta_info_t.
>
> Signed-off-by: dgentry at google.com (Denton Gentry)
> Signed-off-by: denny at geekhold.com (Denton Gentry)
> ---
> src/ap/beacon.c | 40 ++++++++++++++++++++++++++++++++++++----
> src/ap/beacon.h | 3 +++
> src/ap/hostapd.c | 2 +-
> src/ap/hostapd.h | 2 ++
> src/ap/ieee802_11.c | 2 +-
> src/ap/sta_info.c | 3 +++
> src/ap/taxonomy.c | 19 +++++++++++++++++--
> src/ap/taxonomy.h | 6 ++++--
> 8 files changed, 67 insertions(+), 10 deletions(-)
>
> diff --git a/src/ap/beacon.c b/src/ap/beacon.c
> index 7cfc7f2..6eaa71e 100644
> --- a/src/ap/beacon.c
> +++ b/src/ap/beacon.c
> @@ -578,6 +578,17 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
> }
>
>
> +void sta_track_del(struct hostapd_sta_info *info)
> +{
> + if (info->probe_ie_taxonomy) {
> + os_free((void *)info->probe_ie_taxonomy);
> + info->probe_ie_taxonomy = NULL;
> + }
> +
> + os_free(info);
> +}
> +
> +
> void sta_track_expire(struct hostapd_iface *iface, int force)
> {
> struct os_reltime now;
> @@ -600,7 +611,7 @@ void sta_track_expire(struct hostapd_iface *iface, int force)
> MAC2STR(info->addr));
> dl_list_del(&info->list);
> iface->num_sta_seen--;
> - os_free(info);
> + sta_track_del(info);
> }
> }
>
> @@ -673,6 +684,21 @@ sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
> return NULL;
> }
>
> +void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
> + const u8 **probe_ie_taxonomy, size_t *probe_ie_taxonomy_len)
> +{
> + struct hostapd_sta_info *info = sta_track_get(iface, addr);
> + if (!info) {
> + *probe_ie_taxonomy = NULL;
> + *probe_ie_taxonomy_len = 0;
> + return;
> + }
> +
> + *probe_ie_taxonomy = info->probe_ie_taxonomy;
> + info->probe_ie_taxonomy = NULL;
> + *probe_ie_taxonomy_len = info->probe_ie_taxonomy_len;
> + info->probe_ie_taxonomy_len = 0;
> +}
>
> void handle_probe_req(struct hostapd_data *hapd,
> const struct ieee80211_mgmt *mgmt, size_t len,
> @@ -784,9 +810,15 @@ void handle_probe_req(struct hostapd_data *hapd,
> #endif /* CONFIG_P2P */
>
> {
> - struct sta_info *sta = ap_get_sta(hapd, mgmt->sa);
> - if (sta) {
> - hostapd_taxonomy_probe_req(hapd, sta, ie, ie_len);
> + struct sta_info *sta;
> + struct hostapd_sta_info *info;
> +
> + if ((sta = ap_get_sta(hapd, mgmt->sa)) != NULL) {
> + taxonomy_sta_info_probe_req(hapd, sta, ie, ie_len);
> + } else if ((info = sta_track_get(hapd->iface,
> + mgmt->sa)) != NULL) {
> + taxonomy_hostapd_sta_info_probe_req(hapd, info,
> + ie, ie_len);
> }
> }
>
> diff --git a/src/ap/beacon.h b/src/ap/beacon.h
> index d98f42e..266da39 100644
> --- a/src/ap/beacon.h
> +++ b/src/ap/beacon.h
> @@ -22,9 +22,12 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
> struct wpa_driver_ap_params *params);
> void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params);
> void sta_track_add(struct hostapd_iface *iface, const u8 *addr);
> +void sta_track_del(struct hostapd_sta_info *info);
> void sta_track_expire(struct hostapd_iface *iface, int force);
> struct hostapd_data *
> sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
> const char *ifname);
> +void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
> + const u8 **probe_ie_taxonomy, size_t *probe_ie_taxonomy_len);
>
> #endif /* BEACON_H */
> diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
> index 65f513d..e5ed0b1 100644
> --- a/src/ap/hostapd.c
> +++ b/src/ap/hostapd.c
> @@ -374,7 +374,7 @@ static void sta_track_deinit(struct hostapd_iface *iface)
> list))) {
> dl_list_del(&info->list);
> iface->num_sta_seen--;
> - os_free(info);
> + sta_track_del(info);
> }
> }
>
> diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
> index 195679e..963d9cb 100644
> --- a/src/ap/hostapd.h
> +++ b/src/ap/hostapd.h
> @@ -311,6 +311,8 @@ struct hostapd_sta_info {
> struct dl_list list;
> u8 addr[ETH_ALEN];
> struct os_reltime last_seen;
> + const u8 *probe_ie_taxonomy;
> + size_t probe_ie_taxonomy_len;
> };
>
> /**
> diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
> index 52413cc..7d4f314 100644
> --- a/src/ap/ieee802_11.c
> +++ b/src/ap/ieee802_11.c
> @@ -2251,7 +2251,7 @@ static void handle_assoc(struct hostapd_data *hapd,
> * remove the STA immediately. */
> sta->timeout_next = STA_NULLFUNC;
>
> - hostapd_taxonomy_assoc_req(hapd, sta, pos, left);
> + taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
>
> fail:
> /*
> diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
> index ed321f7..899cafd 100644
> --- a/src/ap/sta_info.c
> +++ b/src/ap/sta_info.c
> @@ -671,6 +671,9 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
> sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
> dl_list_init(&sta->ip6addr);
>
> + sta_track_claim_taxonomy_info(hapd->iface, addr,
> + &sta->probe_ie_taxonomy, &sta->probe_ie_taxonomy_len);
> +
> return sta;
> }
>
> diff --git a/src/ap/taxonomy.c b/src/ap/taxonomy.c
> index 71f1645..3915b51 100644
> --- a/src/ap/taxonomy.c
> +++ b/src/ap/taxonomy.c
> @@ -271,7 +271,7 @@ int retrieve_sta_taxonomy(const struct hostapd_data *hapd,
> return 0;
> }
>
> -void hostapd_taxonomy_probe_req(const struct hostapd_data *hapd,
> +void taxonomy_sta_info_probe_req(const struct hostapd_data *hapd,
> struct sta_info *sta, const u8 *ie, size_t ie_len)
> {
> if (sta->probe_ie_taxonomy) {
> @@ -286,7 +286,22 @@ void hostapd_taxonomy_probe_req(const struct hostapd_data *hapd,
> }
> }
>
> -void hostapd_taxonomy_assoc_req(const struct hostapd_data *hapd,
> +void taxonomy_hostapd_sta_info_probe_req(const struct hostapd_data *hapd,
> + struct hostapd_sta_info *info, const u8 *ie, size_t ie_len)
> +{
> + if (info->probe_ie_taxonomy) {
> + os_free(info->probe_ie_taxonomy);
> + info->probe_ie_taxonomy = NULL;
> + info->probe_ie_taxonomy_len = 0;
> + }
> + if (hapd->iconf->client_taxonomy) {
> + info->probe_ie_taxonomy = os_malloc(ie_len);
> + os_memcpy(info->probe_ie_taxonomy, ie, ie_len);
> + info->probe_ie_taxonomy_len = ie_len;
> + }
> +}
> +
> +void taxonomy_sta_info_assoc_req(const struct hostapd_data *hapd,
> struct sta_info *sta, const u8 *ie, size_t ie_len)
> {
> if (sta->assoc_ie_taxonomy) {
> diff --git a/src/ap/taxonomy.h b/src/ap/taxonomy.h
> index 6d2ec39..3b88a4d 100644
> --- a/src/ap/taxonomy.h
> +++ b/src/ap/taxonomy.h
> @@ -9,9 +9,11 @@
> #ifndef TAXONOMY_H
> #define TAXONOMY_H
>
> -void hostapd_taxonomy_probe_req(const struct hostapd_data *hapd,
> +void taxonomy_sta_info_probe_req(const struct hostapd_data *hapd,
> struct sta_info *sta, const u8 *ie, size_t ie_len);
> -void hostapd_taxonomy_assoc_req(const struct hostapd_data *hapd,
> +void taxonomy_hostapd_sta_info_probe_req(const struct hostapd_data *hapd,
> + struct hostapd_sta_info *sta, const u8 *ie, size_t ie_len);
> +void taxonomy_sta_info_assoc_req(const struct hostapd_data *hapd,
> struct sta_info *sta, const u8 *ie, size_t ie_len);
> int retrieve_sta_taxonomy(const struct hostapd_data *hapd,
> struct sta_info *sta, char *buf, size_t buflen);
> --
> 2.8.0.rc3.226.g39d4020
>
More information about the Hostap
mailing list