📄 driver_test.c
字号:
struct sta_info *sta; int new_assoc, res; hapd = test_driver_get_hapd(drv, bss); if (hapd == NULL) return -1; hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated"); sta = ap_get_sta(hapd, addr); if (sta) { accounting_sta_stop(hapd, sta); } else { sta = ap_sta_add(hapd, addr); if (sta == NULL) return -1; } sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); if (hapd->conf->wpa) { if (ie == NULL || ielen == 0) { if (hapd->conf->wps_state) { sta->flags |= WLAN_STA_WPS; goto skip_wpa_check; } printf("test_driver: no IE from STA\n"); return -1; } if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { sta->flags |= WLAN_STA_WPS; goto skip_wpa_check; } if (sta->wpa_sm == NULL) sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr); if (sta->wpa_sm == NULL) { printf("test_driver: Failed to initialize WPA state " "machine\n"); return -1; } res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, ie, ielen, NULL, 0); if (res != WPA_IE_OK) { printf("WPA/RSN information element rejected? " "(res %u)\n", res); wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); return -1; } }skip_wpa_check: new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); hostapd_new_assoc_sta(hapd, sta, !new_assoc); ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); return 0;}static void test_driver_assoc(struct test_driver_data *drv, struct sockaddr_un *from, socklen_t fromlen, char *data){ struct test_client_socket *cli; u8 ie[256], ssid[32]; size_t ielen, ssid_len = 0; char *pos, *pos2, cmd[50]; struct test_driver_bss *bss; /* data: STA-addr SSID(hex) IEs(hex) */ cli = os_zalloc(sizeof(*cli)); if (cli == NULL) return; if (hwaddr_aton(data, cli->addr)) { printf("test_socket: Invalid MAC address '%s' in ASSOC\n", data); free(cli); return; } pos = data + 17; while (*pos == ' ') pos++; pos2 = strchr(pos, ' '); ielen = 0; if (pos2) { ssid_len = (pos2 - pos) / 2; if (hexstr2bin(pos, ssid, ssid_len) < 0) { wpa_printf(MSG_DEBUG, "%s: Invalid SSID", __func__); free(cli); return; } wpa_hexdump_ascii(MSG_DEBUG, "test_driver_assoc: SSID", ssid, ssid_len); pos = pos2 + 1; ielen = strlen(pos) / 2; if (ielen > sizeof(ie)) ielen = sizeof(ie); if (hexstr2bin(pos, ie, ielen) < 0) ielen = 0; } for (bss = drv->bss; bss; bss = bss->next) { if (bss->ssid_len == ssid_len && memcmp(bss->ssid, ssid, ssid_len) == 0) break; } if (bss == NULL) { wpa_printf(MSG_DEBUG, "%s: No matching SSID found from " "configured BSSes", __func__); free(cli); return; } cli->bss = bss; memcpy(&cli->un, from, sizeof(cli->un)); cli->unlen = fromlen; cli->next = drv->cli; drv->cli = cli; wpa_hexdump_ascii(MSG_DEBUG, "test_socket: ASSOC sun_path", (const u8 *) cli->un.sun_path, cli->unlen - sizeof(cli->un.sun_family)); snprintf(cmd, sizeof(cmd), "ASSOCRESP " MACSTR " 0", MAC2STR(bss->bssid)); sendto(drv->test_socket, cmd, strlen(cmd), 0, (struct sockaddr *) from, fromlen); if (test_driver_new_sta(drv, bss, cli->addr, ie, ielen) < 0) { wpa_printf(MSG_DEBUG, "test_driver: failed to add new STA"); }}static void test_driver_disassoc(struct test_driver_data *drv, struct sockaddr_un *from, socklen_t fromlen){ struct test_client_socket *cli; struct sta_info *sta; cli = test_driver_get_cli(drv, from, fromlen); if (!cli) return; hostapd_logger(drv->hapd, cli->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated"); sta = ap_get_sta(drv->hapd, cli->addr); if (sta != NULL) { sta->flags &= ~WLAN_STA_ASSOC; wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); ap_free_sta(drv->hapd, sta); }}static void test_driver_eapol(struct test_driver_data *drv, struct sockaddr_un *from, socklen_t fromlen, u8 *data, size_t datalen){ struct test_client_socket *cli; if (datalen > 14) { /* Skip Ethernet header */ wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src=" MACSTR " proto=%04x", MAC2STR(data), MAC2STR(data + ETH_ALEN), WPA_GET_BE16(data + 2 * ETH_ALEN)); data += 14; datalen -= 14; } cli = test_driver_get_cli(drv, from, fromlen); if (cli) { struct hostapd_data *hapd; hapd = test_driver_get_hapd(drv, cli->bss); if (hapd == NULL) return; ieee802_1x_receive(hapd, cli->addr, data, datalen); } else { wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown " "client"); }}static void test_driver_ether(struct test_driver_data *drv, struct sockaddr_un *from, socklen_t fromlen, u8 *data, size_t datalen){ struct l2_ethhdr *eth; if (datalen < sizeof(*eth)) return; eth = (struct l2_ethhdr *) data; wpa_printf(MSG_DEBUG, "test_driver: RX ETHER dst=" MACSTR " src=" MACSTR " proto=%04x", MAC2STR(eth->h_dest), MAC2STR(eth->h_source), be_to_host16(eth->h_proto));#ifdef CONFIG_IEEE80211R if (be_to_host16(eth->h_proto) == ETH_P_RRB) { wpa_ft_rrb_rx(drv->hapd->wpa_auth, eth->h_source, data + sizeof(*eth), datalen - sizeof(*eth)); }#endif /* CONFIG_IEEE80211R */}static void test_driver_mlme(struct test_driver_data *drv, struct sockaddr_un *from, socklen_t fromlen, u8 *data, size_t datalen){ struct ieee80211_hdr *hdr; u16 fc; hdr = (struct ieee80211_hdr *) data; if (test_driver_get_cli(drv, from, fromlen) == NULL && datalen >= 16) { struct test_client_socket *cli; cli = os_zalloc(sizeof(*cli)); if (cli == NULL) return; wpa_printf(MSG_DEBUG, "Adding client entry for " MACSTR, MAC2STR(hdr->addr2)); memcpy(cli->addr, hdr->addr2, ETH_ALEN); memcpy(&cli->un, from, sizeof(cli->un)); cli->unlen = fromlen; cli->next = drv->cli; drv->cli = cli; } wpa_hexdump(MSG_MSGDUMP, "test_driver_mlme: received frame", data, datalen); fc = le_to_host16(hdr->frame_control); if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) { wpa_printf(MSG_ERROR, "%s: received non-mgmt frame", __func__); return; } ieee802_11_mgmt(drv->hapd, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);}static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx){ struct test_driver_data *drv = eloop_ctx; char buf[2000]; int res; struct sockaddr_un from; socklen_t fromlen = sizeof(from); res = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(test_socket)"); return; } buf[res] = '\0'; wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res); if (strncmp(buf, "SCAN", 4) == 0) { test_driver_scan(drv, &from, fromlen, buf + 4); } else if (strncmp(buf, "ASSOC ", 6) == 0) { test_driver_assoc(drv, &from, fromlen, buf + 6); } else if (strcmp(buf, "DISASSOC") == 0) { test_driver_disassoc(drv, &from, fromlen); } else if (strncmp(buf, "EAPOL ", 6) == 0) { test_driver_eapol(drv, &from, fromlen, (u8 *) buf + 6, res - 6); } else if (strncmp(buf, "ETHER ", 6) == 0) { test_driver_ether(drv, &from, fromlen, (u8 *) buf + 6, res - 6); } else if (strncmp(buf, "MLME ", 5) == 0) { test_driver_mlme(drv, &from, fromlen, (u8 *) buf + 5, res - 5); } else { wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command", (u8 *) buf, res); }}static struct test_driver_bss *test_driver_get_bss(struct test_driver_data *drv, const char *ifname){ struct test_driver_bss *bss; for (bss = drv->bss; bss; bss = bss->next) { if (strcmp(bss->ifname, ifname) == 0) return bss; } return NULL;}static int test_driver_set_generic_elem(const char *ifname, void *priv, const u8 *elem, size_t elem_len){ struct test_driver_data *drv = priv; struct test_driver_bss *bss; bss = test_driver_get_bss(drv, ifname); if (bss == NULL) return -1; free(bss->ie); if (elem == NULL) { bss->ie = NULL; bss->ielen = 0; return 0; } bss->ie = malloc(elem_len); if (bss->ie == NULL) { bss->ielen = 0; return -1; } memcpy(bss->ie, elem, elem_len); bss->ielen = elem_len; return 0;}static int test_driver_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *ie, size_t len){ struct test_driver_data *drv = priv; struct test_driver_bss *bss; wpa_hexdump(MSG_DEBUG, "test_driver: Beacon WPS IE", ie, len); bss = test_driver_get_bss(drv, ifname); if (bss == NULL) return -1; free(bss->wps_beacon_ie); if (ie == NULL) { bss->wps_beacon_ie = NULL; bss->wps_beacon_ie_len = 0; return 0; } bss->wps_beacon_ie = malloc(len); if (bss->wps_beacon_ie == NULL) { bss->wps_beacon_ie_len = 0; return -1; } memcpy(bss->wps_beacon_ie, ie, len); bss->wps_beacon_ie_len = len; return 0;}static int test_driver_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *ie, size_t len){ struct test_driver_data *drv = priv; struct test_driver_bss *bss; wpa_hexdump(MSG_DEBUG, "test_driver: ProbeResp WPS IE", ie, len); bss = test_driver_get_bss(drv, ifname); if (bss == NULL) return -1; free(bss->wps_probe_resp_ie); if (ie == NULL) { bss->wps_probe_resp_ie = NULL; bss->wps_probe_resp_ie_len = 0; return 0; } bss->wps_probe_resp_ie = malloc(len); if (bss->wps_probe_resp_ie == NULL) { bss->wps_probe_resp_ie_len = 0; return -1; } memcpy(bss->wps_probe_resp_ie, ie, len); bss->wps_probe_resp_ie_len = len; return 0;}static int test_driver_sta_deauth(void *priv, const u8 *addr, int reason){ struct test_driver_data *drv = priv; struct test_client_socket *cli; if (drv->test_socket < 0) return -1; cli = drv->cli; while (cli) { if (memcmp(cli->addr, addr, ETH_ALEN) == 0) break; cli = cli->next; } if (!cli) return -1; return sendto(drv->test_socket, "DEAUTH", 6, 0, (struct sockaddr *) &cli->un, cli->unlen);}static int test_driver_sta_disassoc(void *priv, const u8 *addr, int reason){ struct test_driver_data *drv = priv; struct test_client_socket *cli; if (drv->test_socket < 0) return -1; cli = drv->cli; while (cli) { if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -