X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fhs20_supplicant.c;h=a6fff4e66636d5539614a5e19358cb7f01618f9d;hb=dd20eabd16da3b7f459eb89eb4670c73a5062498;hp=72538fb4ca1c23e285cbd7d29cefdfae1045aa1a;hpb=8dd5c1b4e95559cd1688a382cba04f2032e88dae;p=mech_eap.git diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index 72538fb..a6fff4e 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -61,6 +61,46 @@ struct osu_provider { }; +void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s) +{ + struct wpa_bss *bss = wpa_s->current_bss; + u8 *bssid = wpa_s->bssid; + const u8 *ie; + const u8 *ext_capa; + u32 filter = 0; + + if (!bss || !is_hs20_network(wpa_s, wpa_s->current_ssid, bss)) { + wpa_printf(MSG_DEBUG, + "Not configuring frame filtering - BSS " MACSTR + " is not a Hotspot 2.0 network", MAC2STR(bssid)); + return; + } + + ie = wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE); + + /* Check if DGAF disabled bit is zero (5th byte in the IE) */ + if (!ie || ie[1] < 5) + wpa_printf(MSG_DEBUG, + "Not configuring frame filtering - Can't extract DGAF bit"); + else if (!(ie[6] & HS20_DGAF_DISABLED)) + filter |= WPA_DATA_FRAME_FILTER_FLAG_GTK; + + ext_capa = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); + if (!ext_capa || ext_capa[1] < 2) { + wpa_printf(MSG_DEBUG, + "Not configuring frame filtering - Can't extract Proxy ARP bit"); + return; + } + + /* Check if Proxy ARP is enabled (2nd byte in the IE) */ + if (ext_capa[3] & BIT(4)) + filter |= WPA_DATA_FRAME_FILTER_FLAG_ARP | + WPA_DATA_FRAME_FILTER_FLAG_NA; + + wpa_drv_configure_frame_filters(wpa_s, filter); +} + + void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id) { u8 conf; @@ -165,8 +205,8 @@ void hs20_put_anqp_req(u32 stypes, const u8 *payload, size_t payload_len, } -struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload, - size_t payload_len) +static struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload, + size_t payload_len) { struct wpabuf *buf; @@ -189,7 +229,6 @@ int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes, struct wpa_bss *bss; int res; struct icon_entry *icon_entry; - struct icon_entry *picon_entry; bss = wpa_bss_get_bssid(wpa_s, dst); if (!bss) { @@ -232,14 +271,7 @@ int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes, icon_entry->file_name[payload_len] = '\0'; icon_entry->dialog_token = res; - if (wpa_s->icon_head == NULL) { - wpa_s->icon_head = icon_entry; - } else { - picon_entry = wpa_s->icon_head; - while (picon_entry->next) - picon_entry = picon_entry->next; - picon_entry->next = icon_entry; - } + dl_list_add(&wpa_s->icon_head, &icon_entry->list); } return ret; @@ -252,7 +284,7 @@ static struct icon_entry * hs20_find_icon(struct wpa_supplicant *wpa_s, { struct icon_entry *icon; - for (icon = wpa_s->icon_head; icon; icon = icon->next) { + dl_list_for_each(icon, &wpa_s->icon_head, struct icon_entry, list) { if (os_memcmp(icon->bssid, bssid, ETH_ALEN) == 0 && os_strcmp(icon->file_name, file_name) == 0 && icon->image) return icon; @@ -276,9 +308,6 @@ int hs20_get_icon(struct wpa_supplicant *wpa_s, const u8 *bssid, MAC2STR(bssid), file_name, (unsigned int) offset, (unsigned int) size, (unsigned int) buf_len); - if (!wpa_s->icon_head) - return -1; - icon = hs20_find_icon(wpa_s, bssid, file_name); if (!icon || !icon->image || offset >= icon->image_len) return -1; @@ -291,7 +320,7 @@ int hs20_get_icon(struct wpa_supplicant *wpa_s, const u8 *bssid, return -1; b64 = base64_encode(&icon->image[offset], size, &b64_size); - if (buf_len >= b64_size) { + if (b64 && buf_len >= b64_size) { os_memcpy(reply, b64, b64_size); reply_size = b64_size; } else { @@ -318,8 +347,7 @@ static void hs20_free_icon_entry(struct icon_entry *icon) int hs20_del_icon(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name) { - struct icon_entry **picon_entry; - struct icon_entry *icon_entry; + struct icon_entry *icon, *tmp; int count = 0; if (!bssid) @@ -331,22 +359,15 @@ int hs20_del_icon(struct wpa_supplicant *wpa_s, const u8 *bssid, wpa_printf(MSG_DEBUG, "HS20: Delete stored icons for " MACSTR " file name %s", MAC2STR(bssid), file_name); - picon_entry = &wpa_s->icon_head; - while (*picon_entry) { - if ((!bssid || - os_memcmp((*picon_entry)->bssid, bssid, ETH_ALEN) == 0) && + dl_list_for_each_safe(icon, tmp, &wpa_s->icon_head, struct icon_entry, + list) { + if ((!bssid || os_memcmp(icon->bssid, bssid, ETH_ALEN) == 0) && (!file_name || - os_strcmp((*picon_entry)->file_name, file_name) == 0)) { - icon_entry = *picon_entry; - *picon_entry = icon_entry->next; - - hs20_free_icon_entry(icon_entry); + os_strcmp(icon->file_name, file_name) == 0)) { + dl_list_del(&icon->list); + hs20_free_icon_entry(icon); count++; - continue; } - if (*picon_entry == NULL) - break; - picon_entry = &(*picon_entry)->next; } return count == 0 ? -1 : 0; } @@ -376,6 +397,25 @@ static void hs20_set_osu_access_permission(const char *osu_dir, } } + +static void hs20_remove_duplicate_icons(struct wpa_supplicant *wpa_s, + struct icon_entry *new_icon) +{ + struct icon_entry *icon, *tmp; + + dl_list_for_each_safe(icon, tmp, &wpa_s->icon_head, struct icon_entry, + list) { + if (icon == new_icon) + continue; + if (os_memcmp(icon->bssid, new_icon->bssid, ETH_ALEN) == 0 && + os_strcmp(icon->file_name, new_icon->file_name) == 0) { + dl_list_del(&icon->list); + hs20_free_icon_entry(icon); + } + } +} + + static int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *pos, size_t slen, u8 dialog_token) @@ -386,7 +426,7 @@ static int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s, u16 data_len; struct icon_entry *icon; - for (icon = wpa_s->icon_head; icon; icon = icon->next) { + dl_list_for_each(icon, &wpa_s->icon_head, struct icon_entry, list) { if (icon->dialog_token == dialog_token && !icon->image && os_memcmp(icon->bssid, sa, ETH_ALEN) == 0) { icon->image = os_malloc(slen); @@ -394,15 +434,16 @@ static int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s, return -1; os_memcpy(icon->image, pos, slen); icon->image_len = slen; + hs20_remove_duplicate_icons(wpa_s, icon); wpa_msg(wpa_s, MSG_INFO, - "RX-HS20-ICON " MACSTR " %s %u", + RX_HS20_ICON MACSTR " %s %u", MAC2STR(sa), icon->file_name, (unsigned int) icon->image_len); return 0; } } - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR " Icon Binary File", + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " Icon Binary File", MAC2STR(sa)); if (slen < 4) { @@ -465,7 +506,7 @@ static int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s, } fclose(f); - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP-ICON %s", fname); + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP_ICON "%s", fname); return 0; } @@ -529,7 +570,7 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, switch (subtype) { case HS20_STYPE_CAPABILITY_LIST: - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " HS Capability List", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "HS Capability List", pos, slen); if (anqp) { @@ -539,7 +580,7 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, } break; case HS20_STYPE_OPERATOR_FRIENDLY_NAME: - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " Operator Friendly Name", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "oper friendly name", pos, slen); if (anqp) { @@ -555,7 +596,7 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, "Metrics value from " MACSTR, MAC2STR(sa)); break; } - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " WAN Metrics %02x:%u:%u:%u:%u:%u", MAC2STR(sa), pos[0], WPA_GET_LE32(pos + 1), WPA_GET_LE32(pos + 5), pos[9], pos[10], WPA_GET_LE16(pos + 11)); @@ -565,7 +606,7 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, } break; case HS20_STYPE_CONNECTION_CAPABILITY: - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " Connection Capability", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "conn capability", pos, slen); if (anqp) { @@ -575,7 +616,7 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, } break; case HS20_STYPE_OPERATING_CLASS: - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " Operating Class", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "Operating Class", pos, slen); if (anqp) { @@ -585,7 +626,7 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, } break; case HS20_STYPE_OSU_PROVIDERS_LIST: - wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " OSU Providers list", MAC2STR(sa)); wpa_s->num_prov_found++; if (anqp) { @@ -663,6 +704,7 @@ static void hs20_osu_fetch_done(struct wpa_supplicant *wpa_s) f = fopen(fname, "w"); if (f == NULL) { hs20_free_osu_prov(wpa_s); + wpa_s->fetch_anqp_in_progress = 0; return; } @@ -1034,7 +1076,7 @@ static void hs20_osu_scan_res_handler(struct wpa_supplicant *wpa_s, } -int hs20_fetch_osu(struct wpa_supplicant *wpa_s) +int hs20_fetch_osu(struct wpa_supplicant *wpa_s, int skip_scan) { if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - " @@ -1065,7 +1107,16 @@ int hs20_fetch_osu(struct wpa_supplicant *wpa_s) wpa_msg(wpa_s, MSG_INFO, "Starting OSU provisioning information fetch"); wpa_s->num_osu_scans = 0; wpa_s->num_prov_found = 0; - hs20_start_osu_scan(wpa_s); + if (skip_scan) { + wpa_s->network_select = 0; + wpa_s->fetch_all_anqp = 1; + wpa_s->fetch_osu_info = 1; + wpa_s->fetch_osu_icon_in_progress = 0; + + interworking_start_fetch_anqp(wpa_s); + } else { + hs20_start_osu_scan(wpa_s); + } return 0; } @@ -1154,9 +1205,16 @@ void hs20_rx_deauth_imminent_notice(struct wpa_supplicant *wpa_s, u8 code, } +void hs20_init(struct wpa_supplicant *wpa_s) +{ + dl_list_init(&wpa_s->icon_head); +} + + void hs20_deinit(struct wpa_supplicant *wpa_s) { eloop_cancel_timeout(hs20_continue_icon_fetch, wpa_s, NULL); hs20_free_osu_prov(wpa_s); - hs20_del_icon(wpa_s, NULL, NULL); + if (wpa_s->icon_head.next) + hs20_del_icon(wpa_s, NULL, NULL); }