static enum ssid_match_result ssid_match(struct hostapd_data *hapd, const u8 *ssid, size_t ssid_len, const u8 *ssid_list, size_t ssid_list_len, const u8 *addr) { const u8 *pos, *end; int wildcard = 0; u8 mac_ascii[MAC_ASCII_LEN]; if (ssid_len == 0) wildcard = 1; mac_to_ascii(mac_ascii, addr); if (ssid_len == MAC_ASCII_LEN && os_memcmp(ssid, mac_ascii, MAC_ASCII_LEN) == 0) return EXACT_SSID_MATCH; if (ssid_list == NULL) return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH; pos = ssid_list; end = ssid_list + ssid_list_len; while (pos + 1 <= end) { if (pos + 2 + pos[1] > end) break; if (pos[1] == 0) wildcard = 1; if (pos[1] == hapd->conf->ssid.ssid_len && os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0) return EXACT_SSID_MATCH; pos += 2 + pos[1]; } return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH; }
static struct hostapd_data * get_hapd_ssid(struct hostapd_data *hapd, const u8 *bssid, const u8 *sa, const u16 fc) { struct hostapd_iface *iface = hapd->iface; size_t i; u8 mac_ascii[MAC_ASCII_LEN]; struct hostapd_config *conf; char *psk; if (bssid == NULL) return NULL; if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) return HAPD_BROADCAST; if (os_memcmp(bssid, iface->bss[0]->own_addr, ETH_ALEN) != 0) return NULL; //判断帧类型, 若是 Probe 帧, 则返回初始 ssid if ((WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) || (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP)) return iface->bss[0]; mac_to_ascii(mac_ascii, sa); for (i = 1; i < iface->num_bss; i++) { if (os_memcmp(mac_ascii, iface->bss[i]->conf->ssid.ssid, iface->bss[i]->conf->ssid.ssid_len) == 0) { wpa_printf(MSG_DEBUG, "发现 STA 设备: " MACSTR, MAC2STR(sa)); return iface->bss[i]; } } //判断帧类型, 若是认证帧,则开始准备新建 ssid if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) { size_t index; wpa_printf(MSG_DEBUG, "根据 MAC 地址新建 BSS:" MACSTR, MAC2STR(sa)); psk = (char *)malloc(64); psk = hostapd_gen_http_req(sa); if (psk == NULL ) { printf("--------未能成功获取密码!--------"); return NULL; } printf("--------成功获得密码,开始创建 AP!--------\n"); iface->num_bss++; iface->bss = (struct hostapd_data **)realloc(iface->bss, iface->num_bss * sizeof(struct hostapd_data *));//分配内存 index = iface->num_bss - 1; conf = iface->interfaces->config_read_cb(iface->config_fname); //接口配置 conf->bss->ssid.ssid_len = MAC_ASCII_LEN; memcpy(conf->bss->ssid.ssid, mac_ascii, MAC_ASCII_LEN); os_free(conf->bss->ssid.wpa_passphrase); conf->bss->ssid.wpa_passphrase = os_strdup(psk); //配置密码 iface->interfaces->set_security_params(conf->bss); iface->bss[index] = hostapd_alloc_bss_data(iface, conf, conf->bss); //数据 iface->bss[index]->driver = iface->bss[0]->driver; //驱动 iface->bss[index]->drv_priv = iface->bss[0]->drv_priv; memcpy(iface->bss[index]->own_addr, iface->bss[0]->own_addr, ETH_ALEN); if (hostapd_setup_bss_dynamically(iface->bss[index])) //新建 bss return NULL; wpa_printf(MSG_DEBUG, "当前 BSS 总数量: %d", (int)iface->num_bss); return iface->bss[index]; } return NULL; }
static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, struct sta_info *sta, const struct ieee80211_mgmt *req, int is_p2p, size_t *resp_len) { struct ieee80211_mgmt *resp; u8 *pos, *epos; size_t buflen; u8 mac_ascii[MAC_ASCII_LEN]; #define MAX_PROBERESP_LEN 768 buflen = MAX_PROBERESP_LEN; #ifdef CONFIG_WPS if (hapd->wps_probe_resp_ie) buflen += wpabuf_len(hapd->wps_probe_resp_ie); #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P if (hapd->p2p_probe_resp_ie) buflen += wpabuf_len(hapd->p2p_probe_resp_ie); #endif /* CONFIG_P2P */ if (hapd->conf->vendor_elements) buflen += wpabuf_len(hapd->conf->vendor_elements); resp = os_zalloc(buflen); if (resp == NULL) return NULL; epos = ((u8 *) resp) + MAX_PROBERESP_LEN; resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_PROBE_RESP); if (req) os_memcpy(resp->da, req->sa, ETH_ALEN); os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); resp->u.probe_resp.beacon_int = host_to_le16(hapd->iconf->beacon_int); /* hardware or low-level driver will setup seq_ctrl and timestamp */ resp->u.probe_resp.capab_info = host_to_le16(hostapd_own_capab_info(hapd, sta, 1)); pos = resp->u.probe_resp.variable; *pos++ = WLAN_EID_SSID; // *pos++ = hapd->conf->ssid.ssid_len; // os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len); // pos += hapd->conf->ssid.ssid_len; //MAC 地址存放在结构体 ieee80211_mgmt 的成员 sa[6] 中 wpa_printf(MSG_DEBUG, "把 MAC 地址设置为 ssid 名称"); //需要转换成 ASCII 码 mac_to_ascii(mac_ascii, req->sa); *pos++ = MAC_ASCII_LEN; os_memcpy(pos, mac_ascii, MAC_ASCII_LEN); pos += MAC_ASCII_LEN; /* Supported rates */ pos = hostapd_eid_supp_rates(hapd, pos); /* DS Params */ pos = hostapd_eid_ds_params(hapd, pos); pos = hostapd_eid_country(hapd, pos, epos - pos); /* ERP Information element */ pos = hostapd_eid_erp_info(hapd, pos); /* Extended supported rates */ pos = hostapd_eid_ext_supp_rates(hapd, pos); /* RSN, MDIE, WPA */ pos = hostapd_eid_wpa(hapd, pos, epos - pos); #ifdef CONFIG_IEEE80211N pos = hostapd_eid_ht_capabilities(hapd, pos); pos = hostapd_eid_ht_operation(hapd, pos); #endif /* CONFIG_IEEE80211N */ pos = hostapd_eid_ext_capab(hapd, pos); pos = hostapd_eid_time_adv(hapd, pos); pos = hostapd_eid_time_zone(hapd, pos); pos = hostapd_eid_interworking(hapd, pos); pos = hostapd_eid_adv_proto(hapd, pos); pos = hostapd_eid_roaming_consortium(hapd, pos); #ifdef CONFIG_IEEE80211AC pos = hostapd_eid_vht_capabilities(hapd, pos); pos = hostapd_eid_vht_operation(hapd, pos); #endif /* CONFIG_IEEE80211AC */ /* Wi-Fi Alliance WMM */ pos = hostapd_eid_wmm(hapd, pos); #ifdef CONFIG_WPS if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) { os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie), wpabuf_len(hapd->wps_probe_resp_ie)); pos += wpabuf_len(hapd->wps_probe_resp_ie); } #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p && hapd->p2p_probe_resp_ie) { os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie), wpabuf_len(hapd->p2p_probe_resp_ie)); pos += wpabuf_len(hapd->p2p_probe_resp_ie); } #endif /* CONFIG_P2P */ #ifdef CONFIG_P2P_MANAGER if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == P2P_MANAGE) pos = hostapd_eid_p2p_manage(hapd, pos); #endif /* CONFIG_P2P_MANAGER */ #ifdef CONFIG_HS20 pos = hostapd_eid_hs20_indication(hapd, pos); #endif /* CONFIG_HS20 */ if (hapd->conf->vendor_elements) { os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements), wpabuf_len(hapd->conf->vendor_elements)); pos += wpabuf_len(hapd->conf->vendor_elements); } *resp_len = pos - (u8 *) resp; return (u8 *) resp; }