📄 driver_test.c
字号:
/* * WPA Supplicant - testing driver interface * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include <sys/un.h>#include <dirent.h>#include <sys/stat.h>#include "common.h"#include "driver.h"#include "l2_packet/l2_packet.h"#include "eloop.h"#include "sha1.h"#include "ieee802_11_defs.h"struct wpa_driver_test_data { void *ctx; u8 own_addr[ETH_ALEN]; int test_socket; struct sockaddr_un hostapd_addr; int hostapd_addr_set; char *own_socket_path; char *test_dir; u8 bssid[ETH_ALEN]; u8 ssid[32]; size_t ssid_len;#define MAX_SCAN_RESULTS 30 struct wpa_scan_res *scanres[MAX_SCAN_RESULTS]; size_t num_scanres; int use_associnfo; u8 assoc_wpa_ie[80]; size_t assoc_wpa_ie_len; int use_mlme; int associated;};static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx){ struct wpa_driver_test_data *drv = eloop_ctx; if (drv->associated && drv->hostapd_addr_set) { struct stat st; if (stat(drv->hostapd_addr.sun_path, &st) < 0) { wpa_printf(MSG_DEBUG, "%s: lost connection to AP: %s", __func__, strerror(errno)); drv->associated = 0; wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); } } eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);}static int wpa_driver_test_set_wpa(void *priv, int enabled){ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); return 0;}static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx){ wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);}static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv, const char *path){ struct dirent *dent; DIR *dir; struct sockaddr_un addr; dir = opendir(path); if (dir == NULL) return; while ((dent = readdir(dir))) { if (os_strncmp(dent->d_name, "AP-", 3) != 0) continue; wpa_printf(MSG_DEBUG, "%s: SCAN %s", __func__, dent->d_name); os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, dent->d_name); if (sendto(drv->test_socket, "SCAN", 4, 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("sendto(test_socket)"); } } closedir(dir);}static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len){ struct wpa_driver_test_data *drv = priv; wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv); drv->num_scanres = 0; if (drv->test_socket >= 0 && drv->test_dir) wpa_driver_scan_dir(drv, drv->test_dir); if (drv->test_socket >= 0 && drv->hostapd_addr_set && sendto(drv->test_socket, "SCAN", 4, 0, (struct sockaddr *) &drv->hostapd_addr, sizeof(drv->hostapd_addr)) < 0) { perror("sendto(test_socket)"); } eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx); eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv, drv->ctx); return 0;}static struct wpa_scan_results * wpa_driver_test_get_scan_results2(void *priv){ struct wpa_driver_test_data *drv = priv; struct wpa_scan_results *res; size_t i; res = os_zalloc(sizeof(*res)); if (res == NULL) return NULL; res->res = os_zalloc(drv->num_scanres * sizeof(struct wpa_scan_res *)); if (res->res == NULL) { os_free(res); return NULL; } for (i = 0; i < drv->num_scanres; i++) { struct wpa_scan_res *r; if (drv->scanres[i] == NULL) continue; r = os_malloc(sizeof(*r) + drv->scanres[i]->ie_len); if (r == NULL) break; os_memcpy(r, drv->scanres[i], sizeof(*r) + drv->scanres[i]->ie_len); res->res[res->num++] = r; } return res;}static int wpa_driver_test_set_key(void *priv, wpa_alg alg, const u8 *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len){ wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d", __func__, priv, alg, key_idx, set_tx); if (addr) { wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr)); } if (seq) { wpa_hexdump(MSG_DEBUG, " seq", seq, seq_len); } if (key) { wpa_hexdump(MSG_DEBUG, " key", key, key_len); } return 0;}static int wpa_driver_test_associate( void *priv, struct wpa_driver_associate_params *params){ struct wpa_driver_test_data *drv = priv; wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d " "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d", __func__, priv, params->freq, params->pairwise_suite, params->group_suite, params->key_mgmt_suite, params->auth_alg, params->mode); if (params->bssid) { wpa_printf(MSG_DEBUG, " bssid=" MACSTR, MAC2STR(params->bssid)); } if (params->ssid) { wpa_hexdump_ascii(MSG_DEBUG, " ssid", params->ssid, params->ssid_len); } if (params->wpa_ie) { wpa_hexdump(MSG_DEBUG, " wpa_ie", params->wpa_ie, params->wpa_ie_len); drv->assoc_wpa_ie_len = params->wpa_ie_len; if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie)) drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie); os_memcpy(drv->assoc_wpa_ie, params->wpa_ie, drv->assoc_wpa_ie_len); } else drv->assoc_wpa_ie_len = 0; if (drv->test_dir && params->bssid) { os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr)); drv->hostapd_addr.sun_family = AF_UNIX; os_snprintf(drv->hostapd_addr.sun_path, sizeof(drv->hostapd_addr.sun_path), "%s/AP-" MACSTR, drv->test_dir, MAC2STR(params->bssid)); drv->hostapd_addr_set = 1; } if (drv->test_socket >= 0 && drv->hostapd_addr_set) { char cmd[200], *pos, *end; int ret; end = cmd + sizeof(cmd); pos = cmd; ret = os_snprintf(pos, end - pos, "ASSOC " MACSTR " ", MAC2STR(drv->own_addr)); if (ret >= 0 && ret < end - pos) pos += ret; pos += wpa_snprintf_hex(pos, end - pos, params->ssid, params->ssid_len); ret = os_snprintf(pos, end - pos, " "); if (ret >= 0 && ret < end - pos) pos += ret; pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie, params->wpa_ie_len); end[-1] = '\0'; if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0, (struct sockaddr *) &drv->hostapd_addr, sizeof(drv->hostapd_addr)) < 0) { perror("sendto(test_socket)"); return -1; } os_memcpy(drv->ssid, params->ssid, params->ssid_len); drv->ssid_len = params->ssid_len; } else { drv->associated = 1; wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); } return 0;}static int wpa_driver_test_get_bssid(void *priv, u8 *bssid){ struct wpa_driver_test_data *drv = priv; os_memcpy(bssid, drv->bssid, ETH_ALEN); return 0;}static int wpa_driver_test_get_ssid(void *priv, u8 *ssid){ struct wpa_driver_test_data *drv = priv; os_memcpy(ssid, drv->ssid, 32); return drv->ssid_len;}static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv){ if (drv->test_socket >= 0 && sendto(drv->test_socket, "DISASSOC", 8, 0, (struct sockaddr *) &drv->hostapd_addr, sizeof(drv->hostapd_addr)) < 0) { perror("sendto(test_socket)"); return -1; } return 0;}static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr, int reason_code){ struct wpa_driver_test_data *drv = priv; wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", __func__, MAC2STR(addr), reason_code); os_memset(drv->bssid, 0, ETH_ALEN); drv->associated = 0; wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); return wpa_driver_test_send_disassoc(drv);}static int wpa_driver_test_disassociate(void *priv, const u8 *addr, int reason_code){ struct wpa_driver_test_data *drv = priv; wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", __func__, MAC2STR(addr), reason_code); os_memset(drv->bssid, 0, ETH_ALEN); drv->associated = 0; wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); return wpa_driver_test_send_disassoc(drv);}static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv, struct sockaddr_un *from, socklen_t fromlen, const char *data){ struct wpa_scan_res *res; const char *pos, *pos2; size_t len; u8 *ie_pos, *ie_start, *ie_end;#define MAX_IE_LEN 1000 wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data); if (drv->num_scanres >= MAX_SCAN_RESULTS) { wpa_printf(MSG_DEBUG, "test_driver: No room for the new scan " "result"); return; } /* SCANRESP BSSID SSID IEs */ res = os_zalloc(sizeof(*res) + MAX_IE_LEN); if (res == NULL) return; ie_start = ie_pos = (u8 *) (res + 1); ie_end = ie_pos + MAX_IE_LEN; if (hwaddr_aton(data, res->bssid)) { wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres"); os_free(res); return; } pos = data + 17; while (*pos == ' ') pos++; pos2 = os_strchr(pos, ' '); if (pos2 == NULL) { wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination " "in scanres"); os_free(res); return; } len = (pos2 - pos) / 2; if (len > 32) len = 32; /* * Generate SSID IE from the SSID field since this IE is not included * in the main IE field. */ *ie_pos++ = WLAN_EID_SSID; *ie_pos++ = len; if (hexstr2bin(pos, ie_pos, len) < 0) { wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres"); os_free(res); return; } ie_pos += len; pos = pos2 + 1; pos2 = os_strchr(pos, ' '); if (pos2 == NULL) len = os_strlen(pos) / 2; else len = (pos2 - pos) / 2; if ((int) len > ie_end - ie_pos) len = ie_end - ie_pos; if (hexstr2bin(pos, ie_pos, len) < 0) { wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres"); os_free(res); return; } ie_pos += len; res->ie_len = ie_pos - ie_start; if (pos2) { pos = pos2 + 1; while (*pos == ' ') pos++; if (os_strncmp(pos, "PRIVACY", 7) == 0) res->caps |= IEEE80211_CAP_PRIVACY; } os_free(drv->scanres[drv->num_scanres]); drv->scanres[drv->num_scanres++] = res;}static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv, struct sockaddr_un *from, socklen_t fromlen, const char *data){ /* ASSOCRESP BSSID <res> */ if (hwaddr_aton(data, drv->bssid)) { wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in " "assocresp"); } if (drv->use_associnfo) { union wpa_event_data event; os_memset(&event, 0, sizeof(event)); event.assoc_info.req_ies = drv->assoc_wpa_ie; event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len; wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event); } drv->associated = 1; wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);}static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv, struct sockaddr_un *from, socklen_t fromlen){ drv->associated = 0; wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);}static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv, struct sockaddr_un *from, socklen_t fromlen, const u8 *data, size_t data_len){ const u8 *src = drv->bssid; if (data_len > 14) { /* Skip Ethernet header */ src = data + ETH_ALEN; data += 14; data_len -= 14; } wpa_supplicant_rx_eapol(drv->ctx, src, data, data_len);}static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv, struct sockaddr_un *from, socklen_t fromlen, const u8 *data, size_t data_len){ struct ieee80211_rx_status rx_status; os_memset(&rx_status, 0, sizeof(rx_status)); wpa_supplicant_sta_rx(drv->ctx, data, data_len, &rx_status);}static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx, void *sock_ctx){ struct wpa_driver_test_data *drv = eloop_ctx; char *buf; int res; struct sockaddr_un from; socklen_t fromlen = sizeof(from); const size_t buflen = 2000; buf = os_malloc(buflen); if (buf == NULL) return; res = recvfrom(sock, buf, buflen - 1, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(test_socket)"); os_free(buf); return; } buf[res] = '\0'; wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res); if (os_strncmp(buf, "SCANRESP ", 9) == 0) { wpa_driver_test_scanresp(drv, &from, fromlen, buf + 9); } else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) { wpa_driver_test_assocresp(drv, &from, fromlen, buf + 10); } else if (os_strcmp(buf, "DISASSOC") == 0) { wpa_driver_test_disassoc(drv, &from, fromlen); } else if (os_strcmp(buf, "DEAUTH") == 0) { wpa_driver_test_disassoc(drv, &from, fromlen); } else if (os_strncmp(buf, "EAPOL ", 6) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -