[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