diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 5ae9c61a0..99351d95c 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -294,7 +294,7 @@ struct wpa_driver_nl80211_data { struct wpa_driver_scan_filter *filter_ssids; size_t num_filter_ssids; - struct i802_bss first_bss; + struct i802_bss *first_bss; int eapol_tx_sock; @@ -1036,7 +1036,8 @@ static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv, event.interface_status.ifname, del ? "removed" : "added"); - if (os_strcmp(drv->first_bss.ifname, event.interface_status.ifname) == 0) { + if (os_strcmp(drv->first_bss->ifname, event.interface_status.ifname) == + 0) { if (del) { if (drv->if_removed) { wpa_printf(MSG_DEBUG, "nl80211: if_removed " @@ -1045,11 +1046,11 @@ static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv, } drv->if_removed = 1; } else { - if (if_nametoindex(drv->first_bss.ifname) == 0) { + if (if_nametoindex(drv->first_bss->ifname) == 0) { wpa_printf(MSG_DEBUG, "nl80211: Interface %s " "does not exist - ignore " "RTM_NEWLINK", - drv->first_bss.ifname); + drv->first_bss->ifname); return; } if (!drv->if_removed) { @@ -1077,8 +1078,8 @@ static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv, rta_len = RTA_ALIGN(sizeof(struct rtattr)); while (RTA_OK(attr, attrlen)) { if (attr->rta_type == IFLA_IFNAME) { - if (os_strcmp(((char *) attr) + rta_len, drv->first_bss.ifname) - == 0) + if (os_strcmp(((char *) attr) + rta_len, + drv->first_bss->ifname) == 0) return 1; else break; @@ -1150,7 +1151,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) { if (if_indextoname(ifi->ifi_index, namebuf) && linux_iface_up(drv->global->ioctl_sock, - drv->first_bss.ifname) > 0) { + drv->first_bss->ifname) > 0) { wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down " "event since interface %s is up", namebuf); return; @@ -1170,18 +1171,18 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) { if (if_indextoname(ifi->ifi_index, namebuf) && linux_iface_up(drv->global->ioctl_sock, - drv->first_bss.ifname) == 0) { + drv->first_bss->ifname) == 0) { wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up " "event since interface %s is down", namebuf); - } else if (if_nametoindex(drv->first_bss.ifname) == 0) { + } else if (if_nametoindex(drv->first_bss->ifname) == 0) { wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up " "event since interface %s does not exist", - drv->first_bss.ifname); + drv->first_bss->ifname); } else if (drv->if_removed) { wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up " "event since interface %s is marked " - "removed", drv->first_bss.ifname); + "removed", drv->first_bss->ifname); } else { wpa_printf(MSG_DEBUG, "nl80211: Interface up"); drv->if_disabled = 0; @@ -1681,7 +1682,7 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv, if (type == EVENT_DISASSOC) { event.disassoc_info.locally_generated = - !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN); + !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN); event.disassoc_info.addr = bssid; event.disassoc_info.reason_code = reason_code; if (frame + len > mgmt->u.disassoc.variable) { @@ -1691,7 +1692,7 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv, } } else { event.deauth_info.locally_generated = - !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN); + !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN); event.deauth_info.addr = bssid; event.deauth_info.reason_code = reason_code; if (frame + len > mgmt->u.deauth.variable) { @@ -2623,7 +2624,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED && (cmd == NL80211_CMD_NEW_SCAN_RESULTS || cmd == NL80211_CMD_SCAN_ABORTED)) { - wpa_driver_nl80211_set_mode(&drv->first_bss, + wpa_driver_nl80211_set_mode(drv->first_bss, drv->ap_scan_as_station); drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED; } @@ -2775,7 +2776,7 @@ static int process_drv_event(struct nl_msg *msg, void *arg) if (tb[NL80211_ATTR_IFINDEX]) { ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); - for (bss = &drv->first_bss; bss; bss = bss->next) + for (bss = drv->first_bss; bss; bss = bss->next) if (ifidx == -1 || ifidx == bss->ifindex) { do_process_drv_event(bss, gnlh->cmd, tb); return NL_SKIP; @@ -2786,7 +2787,7 @@ static int process_drv_event(struct nl_msg *msg, void *arg) } else if (tb[NL80211_ATTR_WDEV]) { u64 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]); wpa_printf(MSG_DEBUG, "nl80211: Process event on P2P device"); - for (bss = &drv->first_bss; bss; bss = bss->next) { + for (bss = drv->first_bss; bss; bss = bss->next) { if (bss->wdev_id_set && wdev_id == bss->wdev_id) { do_process_drv_event(bss, gnlh->cmd, tb); return NL_SKIP; @@ -2824,7 +2825,7 @@ static int process_global_event(struct nl_msg *msg, void *arg) dl_list_for_each_safe(drv, tmp, &global->interfaces, struct wpa_driver_nl80211_data, list) { - for (bss = &drv->first_bss; bss; bss = bss->next) { + for (bss = drv->first_bss; bss; bss = bss->next) { if ((ifidx == -1 && !wdev_id_set) || ifidx == bss->ifindex || (wdev_id_set && bss->wdev_id_set && @@ -3319,7 +3320,7 @@ static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv, nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY); NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP); - if (nl80211_set_iface_id(msg, &drv->first_bss) < 0) + if (nl80211_set_iface_id(msg, drv->first_bss) < 0) goto nla_put_failure; if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info)) @@ -3575,7 +3576,7 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx) { struct wpa_driver_nl80211_data *drv = ctx; wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked"); - if (i802_set_iface_flags(&drv->first_bss, 1)) { + if (i802_set_iface_flags(drv->first_bss, 1)) { wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP " "after rfkill unblock"); return; @@ -3687,7 +3688,13 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname, return NULL; drv->global = global_priv; drv->ctx = ctx; - bss = &drv->first_bss; + + drv->first_bss = os_zalloc(sizeof(*drv->first_bss)); + if (!drv->first_bss) { + os_free(drv); + return NULL; + } + bss = drv->first_bss; bss->drv = drv; bss->ctx = ctx; @@ -4108,7 +4115,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv) #ifndef HOSTAPD enum nl80211_iftype nlmode = NL80211_IFTYPE_STATION; #endif /* HOSTAPD */ - struct i802_bss *bss = &drv->first_bss; + struct i802_bss *bss = drv->first_bss; int send_rfkill_event = 0; drv->ifindex = if_nametoindex(bss->ifname); @@ -4275,7 +4282,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss) } nl_cb_put(drv->nl_cb); - nl80211_destroy_bss(&drv->first_bss); + nl80211_destroy_bss(drv->first_bss); os_free(drv->filter_ssids); @@ -4286,6 +4293,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss) os_free(drv->extended_capa); os_free(drv->extended_capa_mask); + os_free(drv->first_bss); os_free(drv); } @@ -4302,7 +4310,7 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx) { struct wpa_driver_nl80211_data *drv = eloop_ctx; if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) { - wpa_driver_nl80211_set_mode(&drv->first_bss, + wpa_driver_nl80211_set_mode(drv->first_bss, drv->ap_scan_as_station); drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED; } @@ -4907,7 +4915,7 @@ nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv) goto nla_put_failure; nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN); - if (nl80211_set_iface_id(msg, &drv->first_bss) < 0) + if (nl80211_set_iface_id(msg, drv->first_bss) < 0) goto nla_put_failure; arg.drv = drv; @@ -5550,7 +5558,7 @@ static int wpa_driver_nl80211_authenticate_retry( struct wpa_driver_nl80211_data *drv) { struct wpa_driver_auth_params params; - struct i802_bss *bss = &drv->first_bss; + struct i802_bss *bss = drv->first_bss; int i; wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again"); @@ -6999,7 +7007,7 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv, return -1; nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_INTERFACE); - if (nl80211_set_iface_id(msg, &drv->first_bss) < 0) + if (nl80211_set_iface_id(msg, drv->first_bss) < 0) goto nla_put_failure; NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname); NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype); @@ -7412,17 +7420,17 @@ nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv) return 0; } - if (os_strncmp(drv->first_bss.ifname, "p2p-", 4) == 0) { + if (os_strncmp(drv->first_bss->ifname, "p2p-", 4) == 0) { /* * P2P interface name is of the format p2p-%s-%d. For monitor * interface name corresponding to P2P GO, replace "p2p-" with * "mon-" to retain the same interface name length and to * indicate that it is a monitor interface. */ - snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss.ifname + 4); + snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss->ifname + 4); } else { /* Non-P2P interface with AP functionality. */ - snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss.ifname); + snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss->ifname); } buf[IFNAMSIZ - 1] = '\0'; @@ -7719,14 +7727,14 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv, nlmode = NL80211_IFTYPE_AP; old_mode = drv->nlmode; - if (wpa_driver_nl80211_set_mode(&drv->first_bss, nlmode)) { + if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) { nl80211_remove_monitor_interface(drv); return -1; } - if (wpa_driver_nl80211_set_freq(&drv->first_bss, &freq)) { + if (wpa_driver_nl80211_set_freq(drv->first_bss, &freq)) { if (old_mode != nlmode) - wpa_driver_nl80211_set_mode(&drv->first_bss, old_mode); + wpa_driver_nl80211_set_mode(drv->first_bss, old_mode); nl80211_remove_monitor_interface(drv); return -1; } @@ -7758,7 +7766,7 @@ static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv) wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully"); nla_put_failure: - if (wpa_driver_nl80211_set_mode(&drv->first_bss, + if (wpa_driver_nl80211_set_mode(drv->first_bss, NL80211_IFTYPE_STATION)) { wpa_printf(MSG_INFO, "nl80211: Failed to set interface into " "station mode"); @@ -7778,7 +7786,7 @@ static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv, wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); - if (wpa_driver_nl80211_set_mode(&drv->first_bss, + if (wpa_driver_nl80211_set_mode(drv->first_bss, NL80211_IFTYPE_ADHOC)) { wpa_printf(MSG_INFO, "nl80211: Failed to set interface into " "IBSS mode"); @@ -8291,7 +8299,7 @@ static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv, return -ENOMEM; nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_INTERFACE); - if (nl80211_set_iface_id(msg, &drv->first_bss) < 0) + if (nl80211_set_iface_id(msg, drv->first_bss) < 0) goto nla_put_failure; NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode); @@ -9202,7 +9210,7 @@ static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr) struct wpa_driver_nl80211_data *drv; dl_list_for_each(drv, &global->interfaces, struct wpa_driver_nl80211_data, list) { - if (os_memcmp(addr, drv->first_bss.addr, ETH_ALEN) == 0) + if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0) return 1; } return 0; @@ -9217,9 +9225,9 @@ static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data *drv, if (!drv->global) return -1; - os_memcpy(new_addr, drv->first_bss.addr, ETH_ALEN); + os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN); for (idx = 0; idx < 64; idx++) { - new_addr[0] = drv->first_bss.addr[0] | 0x02; + new_addr[0] = drv->first_bss->addr[0] | 0x02; new_addr[0] ^= idx << 2; if (!nl80211_addr_in_use(drv->global, new_addr)) break; @@ -9372,10 +9380,10 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type, os_memcpy(new_bss->addr, if_addr, ETH_ALEN); new_bss->ifindex = ifidx; new_bss->drv = drv; - new_bss->next = drv->first_bss.next; - new_bss->freq = drv->first_bss.freq; + new_bss->next = drv->first_bss->next; + new_bss->freq = drv->first_bss->freq; new_bss->ctx = bss_ctx; - drv->first_bss.next = new_bss; + drv->first_bss->next = new_bss; if (drv_priv) *drv_priv = new_bss; nl80211_init_bss(new_bss); @@ -9423,10 +9431,10 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, bss->brname, strerror(errno)); } - if (bss != &drv->first_bss) { + if (bss != drv->first_bss) { struct i802_bss *tbss; - for (tbss = &drv->first_bss; tbss; tbss = tbss->next) { + for (tbss = drv->first_bss; tbss; tbss = tbss->next) { if (tbss->next == bss) { tbss->next = bss->next; /* Unsubscribe management frames */ @@ -10029,10 +10037,10 @@ static int wpa_driver_nl80211_shared_freq(void *priv) wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s " MACSTR, - driver->phyname, driver->first_bss.ifname, - MAC2STR(driver->first_bss.addr)); + driver->phyname, driver->first_bss->ifname, + MAC2STR(driver->first_bss->addr)); if (is_ap_interface(driver->nlmode)) - freq = driver->first_bss.freq; + freq = driver->first_bss->freq; else freq = nl80211_get_assoc_freq(driver); wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",