📄 driver_test.c
字号:
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 *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 *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 *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 *from, socklen_t fromlen, const u8 *data, size_t data_len){#ifdef CONFIG_CLIENT_MLME 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);#endif /* CONFIG_CLIENT_MLME */}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_storage 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, (struct sockaddr *) &from, fromlen, buf + 9); } else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) { wpa_driver_test_assocresp(drv, (struct sockaddr *) &from, fromlen, buf + 10); } else if (os_strcmp(buf, "DISASSOC") == 0) { wpa_driver_test_disassoc(drv, (struct sockaddr *) &from, fromlen); } else if (os_strcmp(buf, "DEAUTH") == 0) { wpa_driver_test_disassoc(drv, (struct sockaddr *) &from, fromlen); } else if (os_strncmp(buf, "EAPOL ", 6) == 0) { wpa_driver_test_eapol(drv, (struct sockaddr *) &from, fromlen, (const u8 *) buf + 6, res - 6); } else if (os_strncmp(buf, "MLME ", 5) == 0) { wpa_driver_test_mlme(drv, (struct sockaddr *) &from, fromlen, (const u8 *) buf + 5, res - 5); } else { wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command", (u8 *) buf, res); } os_free(buf);}static void * wpa_driver_test_init2(void *ctx, const char *ifname, void *global_priv){ struct wpa_driver_test_data *drv; drv = os_zalloc(sizeof(*drv)); if (drv == NULL) return NULL; drv->global = global_priv; drv->ctx = ctx; drv->test_socket = -1; /* Set dummy BSSID and SSID for testing. */ drv->bssid[0] = 0x02; drv->bssid[1] = 0x00; drv->bssid[2] = 0x00; drv->bssid[3] = 0x00; drv->bssid[4] = 0x00; drv->bssid[5] = 0x01; os_memcpy(drv->ssid, "test", 5); drv->ssid_len = 4; /* Generate a MAC address to help testing with multiple STAs */ drv->own_addr[0] = 0x02; /* locally administered */ sha1_prf((const u8 *) ifname, os_strlen(ifname), "wpa_supplicant test mac addr generation", NULL, 0, drv->own_addr + 1, ETH_ALEN - 1); eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL); return drv;}static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv){ if (drv->test_socket >= 0) { eloop_unregister_read_sock(drv->test_socket); close(drv->test_socket); drv->test_socket = -1; } if (drv->own_socket_path) { unlink(drv->own_socket_path); os_free(drv->own_socket_path); drv->own_socket_path = NULL; }}static void wpa_driver_test_deinit(void *priv){ struct wpa_driver_test_data *drv = priv; int i; wpa_driver_test_close_test_socket(drv); eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx); eloop_cancel_timeout(wpa_driver_test_poll, drv, NULL); os_free(drv->test_dir); for (i = 0; i < MAX_SCAN_RESULTS; i++) os_free(drv->scanres[i]); os_free(drv->probe_req_ie); os_free(drv);}static int wpa_driver_test_attach(struct wpa_driver_test_data *drv, const char *dir){#ifdef DRIVER_TEST_UNIX static unsigned int counter = 0; struct sockaddr_un addr; size_t len; os_free(drv->own_socket_path); if (dir) { len = os_strlen(dir) + 30; drv->own_socket_path = os_malloc(len); if (drv->own_socket_path == NULL) return -1; os_snprintf(drv->own_socket_path, len, "%s/STA-" MACSTR, dir, MAC2STR(drv->own_addr)); } else { drv->own_socket_path = os_malloc(100); if (drv->own_socket_path == NULL) return -1; os_snprintf(drv->own_socket_path, 100, "/tmp/wpa_supplicant_test-%d-%d", getpid(), counter++); } drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0); if (drv->test_socket < 0) { perror("socket(PF_UNIX)"); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path)); if (bind(drv->test_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); close(drv->test_socket); unlink(drv->own_socket_path); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } eloop_register_read_sock(drv->test_socket, wpa_driver_test_receive_unix, drv, NULL); return 0;#else /* DRIVER_TEST_UNIX */ return -1;#endif /* DRIVER_TEST_UNIX */}static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv, char *dst){ char *pos; pos = os_strchr(dst, ':'); if (pos == NULL) return -1; *pos++ = '\0'; wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos); drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0); if (drv->test_socket < 0) { perror("socket(PF_INET)"); return -1; } os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp)); drv->hostapd_addr_udp.sin_family = AF_INET;#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) { int a[4]; u8 *pos; sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); pos = (u8 *) &drv->hostapd_addr_udp.sin_addr; *pos++ = a[0]; *pos++ = a[1]; *pos++ = a[2]; *pos++ = a[3]; }#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ inet_aton(dst, &drv->hostapd_addr_udp.sin_addr);#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ drv->hostapd_addr_udp.sin_port = htons(atoi(pos)); drv->hostapd_addr_udp_set = 1; eloop_register_read_sock(drv->test_socket, wpa_driver_test_receive_unix, drv, NULL); return 0;}static int wpa_driver_test_set_param(void *priv, const char *param){ struct wpa_driver_test_data *drv = priv; const char *pos; wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); if (param == NULL) return 0; wpa_driver_test_close_test_socket(drv);#ifdef DRIVER_TEST_UNIX pos = os_strstr(param, "test_socket="); if (pos) { const char *pos2; size_t len; pos += 12; pos2 = os_strchr(pos, ' '); if (pos2) len = pos2 - pos; else len = os_strlen(pos); if (len > sizeof(drv->hostapd_addr.sun_path)) return -1; os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr)); drv->hostapd_addr.sun_family = AF_UNIX; os_memcpy(drv->hostapd_addr.sun_path, pos, len); drv->hostapd_addr_set = 1; }#endif /* DRIVER_TEST_UNIX */ pos = os_strstr(param, "test_dir="); if (pos) { char *end; os_free(drv->test_dir); drv->test_dir = os_strdup(pos + 9); if (drv->test_dir == NULL) return -1; end = os_strchr(drv->test_dir, ' '); if (end) *end = '\0'; if (wpa_driver_test_attach(drv, drv->test_dir)) return -1; } else { pos = os_strstr(param, "test_udp="); if (pos) { char *dst, *epos; dst = os_strdup(pos + 9); if (dst == NULL) return -1; epos = os_strchr(dst, ' '); if (epos) *epos = '\0'; if (wpa_driver_test_attach_udp(drv, dst)) return -1; os_free(dst); } else if (wpa_driver_test_attach(drv, NULL)) return -1; } if (os_strstr(param, "use_associnfo=1")) { wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events"); drv->use_associnfo = 1; }#ifdef CONFIG_CLIENT_MLME if (os_strstr(param, "use_mlme=1")) { wpa_printf(MSG_DEBUG, "test_driver: Use internal MLME"); drv->use_mlme = 1; }#endif /* CONFIG_CLIENT_MLME */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -