* @age: Age of the information in milliseconds (i.e., how many milliseconds
* ago the last Beacon or Probe Response frame was received)
* @ie_len: length of the following IE field in octets
+ * @beacon_ie_len: length of the following Beacon IE field in octets
*
* This structure is used as a generic format for scan results from the
* driver. Each driver interface implementation is responsible for converting
u64 tsf;
unsigned int age;
size_t ie_len;
- /* followed by ie_len octets of IEs */
+ size_t beacon_ie_len;
+ /*
+ * Followed by ie_len octets of IEs from Probe Response frame (or if
+ * the driver does not indicate source of IEs, these may also be from
+ * Beacon frame). After the first set of IEs, another set of IEs may
+ * follow (with beacon_ie_len octets of data) if the driver provides
+ * both IE sets.
+ */
};
/**
[NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
[NL80211_BSS_STATUS] = { .type = NLA_U32 },
[NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
+ [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
};
struct wpa_scan_results *res = arg;
struct wpa_scan_res **tmp;
struct wpa_scan_res *r;
- const u8 *ie;
- size_t ie_len;
+ const u8 *ie, *beacon_ie;
+ size_t ie_len, beacon_ie_len;
+ u8 *pos;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
ie = NULL;
ie_len = 0;
}
+ if (bss[NL80211_BSS_BEACON_IES]) {
+ beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
+ beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
+ } else {
+ beacon_ie = NULL;
+ beacon_ie_len = 0;
+ }
- r = os_zalloc(sizeof(*r) + ie_len);
+ r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
if (r == NULL)
return NL_SKIP;
if (bss[NL80211_BSS_BSSID])
if (bss[NL80211_BSS_SEEN_MS_AGO])
r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
r->ie_len = ie_len;
- if (ie)
- os_memcpy(r + 1, ie, ie_len);
+ pos = (u8 *) (r + 1);
+ if (ie) {
+ os_memcpy(pos, ie, ie_len);
+ pos += ie_len;
+ }
+ r->beacon_ie_len = beacon_ie_len;
+ if (beacon_ie)
+ os_memcpy(pos, beacon_ie, beacon_ie_len);
if (bss[NL80211_BSS_STATUS]) {
enum nl80211_bss_status status;
{
struct wpa_bss *bss;
- bss = os_zalloc(sizeof(*bss) + res->ie_len);
+ bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
if (bss == NULL)
return;
bss->id = wpa_s->bss_next_id++;
os_memcpy(bss->ssid, ssid, ssid_len);
bss->ssid_len = ssid_len;
bss->ie_len = res->ie_len;
- os_memcpy(bss + 1, res + 1, res->ie_len);
+ bss->beacon_ie_len = res->beacon_ie_len;
+ os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
dl_list_add_tail(&wpa_s->bss, &bss->list);
dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);
wpa_bss_copy_res(bss, res);
/* Move the entry to the end of the list */
dl_list_del(&bss->list);
- if (bss->ie_len >= res->ie_len) {
- os_memcpy(bss + 1, res + 1, res->ie_len);
+ if (bss->ie_len + bss->beacon_ie_len >=
+ res->ie_len + res->beacon_ie_len) {
+ os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
bss->ie_len = res->ie_len;
+ bss->beacon_ie_len = res->beacon_ie_len;
} else {
struct wpa_bss *nbss;
struct dl_list *prev = bss->list_id.prev;
dl_list_del(&bss->list_id);
- nbss = os_realloc(bss, sizeof(*bss) + res->ie_len);
+ nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
+ res->beacon_ie_len);
if (nbss) {
bss = nbss;
- os_memcpy(bss + 1, res + 1, res->ie_len);
+ os_memcpy(bss + 1, res + 1,
+ res->ie_len + res->beacon_ie_len);
bss->ie_len = res->ie_len;
+ bss->beacon_ie_len = res->beacon_ie_len;
}
dl_list_add(prev, &bss->list_id);
}
* @level: signal level
* @tsf: Timestamp of last Beacon/Probe Response frame
* @last_update: Time of the last update (i.e., Beacon or Probe Response RX)
- * @ie_len: length of the following IE field in octets
+ * @ie_len: length of the following IE field in octets (from Probe Response)
+ * @beacon_ie_len: length of the following Beacon IE field in octets
*
* This structure is used to store information about neighboring BSSes in
* generic format. It is mainly updated based on scan results from the driver.
u64 tsf;
struct os_time last_update;
size_t ie_len;
+ size_t beacon_ie_len;
/* followed by ie_len octets of IEs */
+ /* followed by beacon_ie_len octets of IEs */
};
void wpa_bss_update_start(struct wpa_supplicant *wpa_s);