driver_test.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. /*
  2. * WPA Supplicant - testing driver interface
  3. * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. /* Make dure we get winsock2.h for Windows build to get sockaddr_storage */
  15. #include "build_config.h"
  16. #ifdef CONFIG_NATIVE_WINDOWS
  17. #include <winsock2.h>
  18. #endif /* CONFIG_NATIVE_WINDOWS */
  19. #include "includes.h"
  20. #ifndef CONFIG_NATIVE_WINDOWS
  21. #include <sys/un.h>
  22. #include <dirent.h>
  23. #include <sys/stat.h>
  24. #define DRIVER_TEST_UNIX
  25. #endif /* CONFIG_NATIVE_WINDOWS */
  26. #include "common.h"
  27. #include "driver.h"
  28. #include "l2_packet/l2_packet.h"
  29. #include "eloop.h"
  30. #include "sha1.h"
  31. #include "ieee802_11_defs.h"
  32. struct wpa_driver_test_global {
  33. int dummy;
  34. };
  35. struct wpa_driver_test_data {
  36. struct wpa_driver_test_global *global;
  37. void *ctx;
  38. u8 own_addr[ETH_ALEN];
  39. int test_socket;
  40. #ifdef DRIVER_TEST_UNIX
  41. struct sockaddr_un hostapd_addr;
  42. #endif /* DRIVER_TEST_UNIX */
  43. int hostapd_addr_set;
  44. struct sockaddr_in hostapd_addr_udp;
  45. int hostapd_addr_udp_set;
  46. char *own_socket_path;
  47. char *test_dir;
  48. u8 bssid[ETH_ALEN];
  49. u8 ssid[32];
  50. size_t ssid_len;
  51. #define MAX_SCAN_RESULTS 30
  52. struct wpa_scan_res *scanres[MAX_SCAN_RESULTS];
  53. size_t num_scanres;
  54. int use_associnfo;
  55. u8 assoc_wpa_ie[80];
  56. size_t assoc_wpa_ie_len;
  57. int use_mlme;
  58. int associated;
  59. u8 *probe_req_ie;
  60. size_t probe_req_ie_len;
  61. };
  62. static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx)
  63. {
  64. struct wpa_driver_test_data *drv = eloop_ctx;
  65. #ifdef DRIVER_TEST_UNIX
  66. if (drv->associated && drv->hostapd_addr_set) {
  67. struct stat st;
  68. if (stat(drv->hostapd_addr.sun_path, &st) < 0) {
  69. wpa_printf(MSG_DEBUG, "%s: lost connection to AP: %s",
  70. __func__, strerror(errno));
  71. drv->associated = 0;
  72. wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
  73. }
  74. }
  75. #endif /* DRIVER_TEST_UNIX */
  76. eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);
  77. }
  78. static int wpa_driver_test_set_wpa(void *priv, int enabled)
  79. {
  80. wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
  81. return 0;
  82. }
  83. static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
  84. {
  85. wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
  86. wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
  87. }
  88. #ifdef DRIVER_TEST_UNIX
  89. static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv,
  90. const char *path)
  91. {
  92. struct dirent *dent;
  93. DIR *dir;
  94. struct sockaddr_un addr;
  95. char cmd[512], *pos, *end;
  96. int ret;
  97. dir = opendir(path);
  98. if (dir == NULL)
  99. return;
  100. end = cmd + sizeof(cmd);
  101. pos = cmd;
  102. ret = os_snprintf(pos, end - pos, "SCAN " MACSTR,
  103. MAC2STR(drv->own_addr));
  104. if (ret >= 0 && ret < end - pos)
  105. pos += ret;
  106. if (drv->probe_req_ie) {
  107. ret = os_snprintf(pos, end - pos, " ");
  108. if (ret >= 0 && ret < end - pos)
  109. pos += ret;
  110. pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ie,
  111. drv->probe_req_ie_len);
  112. }
  113. end[-1] = '\0';
  114. while ((dent = readdir(dir))) {
  115. if (os_strncmp(dent->d_name, "AP-", 3) != 0)
  116. continue;
  117. wpa_printf(MSG_DEBUG, "%s: SCAN %s", __func__, dent->d_name);
  118. os_memset(&addr, 0, sizeof(addr));
  119. addr.sun_family = AF_UNIX;
  120. os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
  121. path, dent->d_name);
  122. if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
  123. (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  124. perror("sendto(test_socket)");
  125. }
  126. }
  127. closedir(dir);
  128. }
  129. #endif /* DRIVER_TEST_UNIX */
  130. static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len)
  131. {
  132. struct wpa_driver_test_data *drv = priv;
  133. wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
  134. drv->num_scanres = 0;
  135. #ifdef DRIVER_TEST_UNIX
  136. if (drv->test_socket >= 0 && drv->test_dir)
  137. wpa_driver_scan_dir(drv, drv->test_dir);
  138. if (drv->test_socket >= 0 && drv->hostapd_addr_set &&
  139. sendto(drv->test_socket, "SCAN", 4, 0,
  140. (struct sockaddr *) &drv->hostapd_addr,
  141. sizeof(drv->hostapd_addr)) < 0) {
  142. perror("sendto(test_socket)");
  143. }
  144. #endif /* DRIVER_TEST_UNIX */
  145. if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
  146. sendto(drv->test_socket, "SCAN", 4, 0,
  147. (struct sockaddr *) &drv->hostapd_addr_udp,
  148. sizeof(drv->hostapd_addr_udp)) < 0) {
  149. perror("sendto(test_socket)");
  150. }
  151. eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
  152. eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
  153. drv->ctx);
  154. return 0;
  155. }
  156. static struct wpa_scan_results * wpa_driver_test_get_scan_results2(void *priv)
  157. {
  158. struct wpa_driver_test_data *drv = priv;
  159. struct wpa_scan_results *res;
  160. size_t i;
  161. res = os_zalloc(sizeof(*res));
  162. if (res == NULL)
  163. return NULL;
  164. res->res = os_zalloc(drv->num_scanres * sizeof(struct wpa_scan_res *));
  165. if (res->res == NULL) {
  166. os_free(res);
  167. return NULL;
  168. }
  169. for (i = 0; i < drv->num_scanres; i++) {
  170. struct wpa_scan_res *r;
  171. if (drv->scanres[i] == NULL)
  172. continue;
  173. r = os_malloc(sizeof(*r) + drv->scanres[i]->ie_len);
  174. if (r == NULL)
  175. break;
  176. os_memcpy(r, drv->scanres[i],
  177. sizeof(*r) + drv->scanres[i]->ie_len);
  178. res->res[res->num++] = r;
  179. }
  180. return res;
  181. }
  182. static int wpa_driver_test_set_key(void *priv, wpa_alg alg, const u8 *addr,
  183. int key_idx, int set_tx,
  184. const u8 *seq, size_t seq_len,
  185. const u8 *key, size_t key_len)
  186. {
  187. wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
  188. __func__, priv, alg, key_idx, set_tx);
  189. if (addr) {
  190. wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
  191. }
  192. if (seq) {
  193. wpa_hexdump(MSG_DEBUG, " seq", seq, seq_len);
  194. }
  195. if (key) {
  196. wpa_hexdump(MSG_DEBUG, " key", key, key_len);
  197. }
  198. return 0;
  199. }
  200. static int wpa_driver_test_associate(
  201. void *priv, struct wpa_driver_associate_params *params)
  202. {
  203. struct wpa_driver_test_data *drv = priv;
  204. wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
  205. "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
  206. __func__, priv, params->freq, params->pairwise_suite,
  207. params->group_suite, params->key_mgmt_suite,
  208. params->auth_alg, params->mode);
  209. if (params->bssid) {
  210. wpa_printf(MSG_DEBUG, " bssid=" MACSTR,
  211. MAC2STR(params->bssid));
  212. }
  213. if (params->ssid) {
  214. wpa_hexdump_ascii(MSG_DEBUG, " ssid",
  215. params->ssid, params->ssid_len);
  216. }
  217. if (params->wpa_ie) {
  218. wpa_hexdump(MSG_DEBUG, " wpa_ie",
  219. params->wpa_ie, params->wpa_ie_len);
  220. drv->assoc_wpa_ie_len = params->wpa_ie_len;
  221. if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie))
  222. drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie);
  223. os_memcpy(drv->assoc_wpa_ie, params->wpa_ie,
  224. drv->assoc_wpa_ie_len);
  225. } else
  226. drv->assoc_wpa_ie_len = 0;
  227. #ifdef DRIVER_TEST_UNIX
  228. if (drv->test_dir && params->bssid) {
  229. os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
  230. drv->hostapd_addr.sun_family = AF_UNIX;
  231. os_snprintf(drv->hostapd_addr.sun_path,
  232. sizeof(drv->hostapd_addr.sun_path),
  233. "%s/AP-" MACSTR,
  234. drv->test_dir, MAC2STR(params->bssid));
  235. drv->hostapd_addr_set = 1;
  236. }
  237. #endif /* DRIVER_TEST_UNIX */
  238. if (drv->test_socket >= 0 &&
  239. (drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) {
  240. char cmd[200], *pos, *end;
  241. int ret;
  242. end = cmd + sizeof(cmd);
  243. pos = cmd;
  244. ret = os_snprintf(pos, end - pos, "ASSOC " MACSTR " ",
  245. MAC2STR(drv->own_addr));
  246. if (ret >= 0 && ret < end - pos)
  247. pos += ret;
  248. pos += wpa_snprintf_hex(pos, end - pos, params->ssid,
  249. params->ssid_len);
  250. ret = os_snprintf(pos, end - pos, " ");
  251. if (ret >= 0 && ret < end - pos)
  252. pos += ret;
  253. pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
  254. params->wpa_ie_len);
  255. end[-1] = '\0';
  256. #ifdef DRIVER_TEST_UNIX
  257. if (drv->hostapd_addr_set &&
  258. sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
  259. (struct sockaddr *) &drv->hostapd_addr,
  260. sizeof(drv->hostapd_addr)) < 0) {
  261. perror("sendto(test_socket)");
  262. return -1;
  263. }
  264. #endif /* DRIVER_TEST_UNIX */
  265. if (drv->hostapd_addr_udp_set &&
  266. sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
  267. (struct sockaddr *) &drv->hostapd_addr_udp,
  268. sizeof(drv->hostapd_addr_udp)) < 0) {
  269. perror("sendto(test_socket)");
  270. return -1;
  271. }
  272. os_memcpy(drv->ssid, params->ssid, params->ssid_len);
  273. drv->ssid_len = params->ssid_len;
  274. } else {
  275. drv->associated = 1;
  276. wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
  277. }
  278. return 0;
  279. }
  280. static int wpa_driver_test_get_bssid(void *priv, u8 *bssid)
  281. {
  282. struct wpa_driver_test_data *drv = priv;
  283. os_memcpy(bssid, drv->bssid, ETH_ALEN);
  284. return 0;
  285. }
  286. static int wpa_driver_test_get_ssid(void *priv, u8 *ssid)
  287. {
  288. struct wpa_driver_test_data *drv = priv;
  289. os_memcpy(ssid, drv->ssid, 32);
  290. return drv->ssid_len;
  291. }
  292. static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv)
  293. {
  294. #ifdef DRIVER_TEST_UNIX
  295. if (drv->test_socket >= 0 &&
  296. sendto(drv->test_socket, "DISASSOC", 8, 0,
  297. (struct sockaddr *) &drv->hostapd_addr,
  298. sizeof(drv->hostapd_addr)) < 0) {
  299. perror("sendto(test_socket)");
  300. return -1;
  301. }
  302. #endif /* DRIVER_TEST_UNIX */
  303. if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
  304. sendto(drv->test_socket, "DISASSOC", 8, 0,
  305. (struct sockaddr *) &drv->hostapd_addr_udp,
  306. sizeof(drv->hostapd_addr_udp)) < 0) {
  307. perror("sendto(test_socket)");
  308. return -1;
  309. }
  310. return 0;
  311. }
  312. static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr,
  313. int reason_code)
  314. {
  315. struct wpa_driver_test_data *drv = priv;
  316. wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
  317. __func__, MAC2STR(addr), reason_code);
  318. os_memset(drv->bssid, 0, ETH_ALEN);
  319. drv->associated = 0;
  320. wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
  321. return wpa_driver_test_send_disassoc(drv);
  322. }
  323. static int wpa_driver_test_disassociate(void *priv, const u8 *addr,
  324. int reason_code)
  325. {
  326. struct wpa_driver_test_data *drv = priv;
  327. wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
  328. __func__, MAC2STR(addr), reason_code);
  329. os_memset(drv->bssid, 0, ETH_ALEN);
  330. drv->associated = 0;
  331. wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
  332. return wpa_driver_test_send_disassoc(drv);
  333. }
  334. static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv,
  335. struct sockaddr *from,
  336. socklen_t fromlen,
  337. const char *data)
  338. {
  339. struct wpa_scan_res *res;
  340. const char *pos, *pos2;
  341. size_t len;
  342. u8 *ie_pos, *ie_start, *ie_end;
  343. #define MAX_IE_LEN 1000
  344. wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data);
  345. if (drv->num_scanres >= MAX_SCAN_RESULTS) {
  346. wpa_printf(MSG_DEBUG, "test_driver: No room for the new scan "
  347. "result");
  348. return;
  349. }
  350. /* SCANRESP BSSID SSID IEs */
  351. res = os_zalloc(sizeof(*res) + MAX_IE_LEN);
  352. if (res == NULL)
  353. return;
  354. ie_start = ie_pos = (u8 *) (res + 1);
  355. ie_end = ie_pos + MAX_IE_LEN;
  356. if (hwaddr_aton(data, res->bssid)) {
  357. wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres");
  358. os_free(res);
  359. return;
  360. }
  361. pos = data + 17;
  362. while (*pos == ' ')
  363. pos++;
  364. pos2 = os_strchr(pos, ' ');
  365. if (pos2 == NULL) {
  366. wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination "
  367. "in scanres");
  368. os_free(res);
  369. return;
  370. }
  371. len = (pos2 - pos) / 2;
  372. if (len > 32)
  373. len = 32;
  374. /*
  375. * Generate SSID IE from the SSID field since this IE is not included
  376. * in the main IE field.
  377. */
  378. *ie_pos++ = WLAN_EID_SSID;
  379. *ie_pos++ = len;
  380. if (hexstr2bin(pos, ie_pos, len) < 0) {
  381. wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres");
  382. os_free(res);
  383. return;
  384. }
  385. ie_pos += len;
  386. pos = pos2 + 1;
  387. pos2 = os_strchr(pos, ' ');
  388. if (pos2 == NULL)
  389. len = os_strlen(pos) / 2;
  390. else
  391. len = (pos2 - pos) / 2;
  392. if ((int) len > ie_end - ie_pos)
  393. len = ie_end - ie_pos;
  394. if (hexstr2bin(pos, ie_pos, len) < 0) {
  395. wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres");
  396. os_free(res);
  397. return;
  398. }
  399. ie_pos += len;
  400. res->ie_len = ie_pos - ie_start;
  401. if (pos2) {
  402. pos = pos2 + 1;
  403. while (*pos == ' ')
  404. pos++;
  405. if (os_strncmp(pos, "PRIVACY", 7) == 0)
  406. res->caps |= IEEE80211_CAP_PRIVACY;
  407. }
  408. os_free(drv->scanres[drv->num_scanres]);
  409. drv->scanres[drv->num_scanres++] = res;
  410. }
  411. static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv,
  412. struct sockaddr *from,
  413. socklen_t fromlen,
  414. const char *data)
  415. {
  416. /* ASSOCRESP BSSID <res> */
  417. if (hwaddr_aton(data, drv->bssid)) {
  418. wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in "
  419. "assocresp");
  420. }
  421. if (drv->use_associnfo) {
  422. union wpa_event_data event;
  423. os_memset(&event, 0, sizeof(event));
  424. event.assoc_info.req_ies = drv->assoc_wpa_ie;
  425. event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len;
  426. wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event);
  427. }
  428. drv->associated = 1;
  429. wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
  430. }
  431. static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv,
  432. struct sockaddr *from,
  433. socklen_t fromlen)
  434. {
  435. drv->associated = 0;
  436. wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
  437. }
  438. static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
  439. struct sockaddr *from,
  440. socklen_t fromlen,
  441. const u8 *data, size_t data_len)
  442. {
  443. const u8 *src = drv->bssid;
  444. if (data_len > 14) {
  445. /* Skip Ethernet header */
  446. src = data + ETH_ALEN;
  447. data += 14;
  448. data_len -= 14;
  449. }
  450. wpa_supplicant_rx_eapol(drv->ctx, src, data, data_len);
  451. }
  452. static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv,
  453. struct sockaddr *from,
  454. socklen_t fromlen,
  455. const u8 *data, size_t data_len)
  456. {
  457. #ifdef CONFIG_CLIENT_MLME
  458. struct ieee80211_rx_status rx_status;
  459. os_memset(&rx_status, 0, sizeof(rx_status));
  460. wpa_supplicant_sta_rx(drv->ctx, data, data_len, &rx_status);
  461. #endif /* CONFIG_CLIENT_MLME */
  462. }
  463. static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx,
  464. void *sock_ctx)
  465. {
  466. struct wpa_driver_test_data *drv = eloop_ctx;
  467. char *buf;
  468. int res;
  469. struct sockaddr_storage from;
  470. socklen_t fromlen = sizeof(from);
  471. const size_t buflen = 2000;
  472. buf = os_malloc(buflen);
  473. if (buf == NULL)
  474. return;
  475. res = recvfrom(sock, buf, buflen - 1, 0,
  476. (struct sockaddr *) &from, &fromlen);
  477. if (res < 0) {
  478. perror("recvfrom(test_socket)");
  479. os_free(buf);
  480. return;
  481. }
  482. buf[res] = '\0';
  483. wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
  484. if (os_strncmp(buf, "SCANRESP ", 9) == 0) {
  485. wpa_driver_test_scanresp(drv, (struct sockaddr *) &from,
  486. fromlen, buf + 9);
  487. } else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) {
  488. wpa_driver_test_assocresp(drv, (struct sockaddr *) &from,
  489. fromlen, buf + 10);
  490. } else if (os_strcmp(buf, "DISASSOC") == 0) {
  491. wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
  492. fromlen);
  493. } else if (os_strcmp(buf, "DEAUTH") == 0) {
  494. wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
  495. fromlen);
  496. } else if (os_strncmp(buf, "EAPOL ", 6) == 0) {
  497. wpa_driver_test_eapol(drv, (struct sockaddr *) &from, fromlen,
  498. (const u8 *) buf + 6, res - 6);
  499. } else if (os_strncmp(buf, "MLME ", 5) == 0) {
  500. wpa_driver_test_mlme(drv, (struct sockaddr *) &from, fromlen,
  501. (const u8 *) buf + 5, res - 5);
  502. } else {
  503. wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
  504. (u8 *) buf, res);
  505. }
  506. os_free(buf);
  507. }
  508. static void * wpa_driver_test_init2(void *ctx, const char *ifname,
  509. void *global_priv)
  510. {
  511. struct wpa_driver_test_data *drv;
  512. drv = os_zalloc(sizeof(*drv));
  513. if (drv == NULL)
  514. return NULL;
  515. drv->global = global_priv;
  516. drv->ctx = ctx;
  517. drv->test_socket = -1;
  518. /* Set dummy BSSID and SSID for testing. */
  519. drv->bssid[0] = 0x02;
  520. drv->bssid[1] = 0x00;
  521. drv->bssid[2] = 0x00;
  522. drv->bssid[3] = 0x00;
  523. drv->bssid[4] = 0x00;
  524. drv->bssid[5] = 0x01;
  525. os_memcpy(drv->ssid, "test", 5);
  526. drv->ssid_len = 4;
  527. /* Generate a MAC address to help testing with multiple STAs */
  528. drv->own_addr[0] = 0x02; /* locally administered */
  529. sha1_prf((const u8 *) ifname, os_strlen(ifname),
  530. "wpa_supplicant test mac addr generation",
  531. NULL, 0, drv->own_addr + 1, ETH_ALEN - 1);
  532. eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);
  533. return drv;
  534. }
  535. static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv)
  536. {
  537. if (drv->test_socket >= 0) {
  538. eloop_unregister_read_sock(drv->test_socket);
  539. close(drv->test_socket);
  540. drv->test_socket = -1;
  541. }
  542. if (drv->own_socket_path) {
  543. unlink(drv->own_socket_path);
  544. os_free(drv->own_socket_path);
  545. drv->own_socket_path = NULL;
  546. }
  547. }
  548. static void wpa_driver_test_deinit(void *priv)
  549. {
  550. struct wpa_driver_test_data *drv = priv;
  551. int i;
  552. wpa_driver_test_close_test_socket(drv);
  553. eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
  554. eloop_cancel_timeout(wpa_driver_test_poll, drv, NULL);
  555. os_free(drv->test_dir);
  556. for (i = 0; i < MAX_SCAN_RESULTS; i++)
  557. os_free(drv->scanres[i]);
  558. os_free(drv->probe_req_ie);
  559. os_free(drv);
  560. }
  561. static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
  562. const char *dir)
  563. {
  564. #ifdef DRIVER_TEST_UNIX
  565. static unsigned int counter = 0;
  566. struct sockaddr_un addr;
  567. size_t len;
  568. os_free(drv->own_socket_path);
  569. if (dir) {
  570. len = os_strlen(dir) + 30;
  571. drv->own_socket_path = os_malloc(len);
  572. if (drv->own_socket_path == NULL)
  573. return -1;
  574. os_snprintf(drv->own_socket_path, len, "%s/STA-" MACSTR,
  575. dir, MAC2STR(drv->own_addr));
  576. } else {
  577. drv->own_socket_path = os_malloc(100);
  578. if (drv->own_socket_path == NULL)
  579. return -1;
  580. os_snprintf(drv->own_socket_path, 100,
  581. "/tmp/wpa_supplicant_test-%d-%d",
  582. getpid(), counter++);
  583. }
  584. drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
  585. if (drv->test_socket < 0) {
  586. perror("socket(PF_UNIX)");
  587. os_free(drv->own_socket_path);
  588. drv->own_socket_path = NULL;
  589. return -1;
  590. }
  591. os_memset(&addr, 0, sizeof(addr));
  592. addr.sun_family = AF_UNIX;
  593. os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
  594. if (bind(drv->test_socket, (struct sockaddr *) &addr,
  595. sizeof(addr)) < 0) {
  596. perror("bind(PF_UNIX)");
  597. close(drv->test_socket);
  598. unlink(drv->own_socket_path);
  599. os_free(drv->own_socket_path);
  600. drv->own_socket_path = NULL;
  601. return -1;
  602. }
  603. eloop_register_read_sock(drv->test_socket,
  604. wpa_driver_test_receive_unix, drv, NULL);
  605. return 0;
  606. #else /* DRIVER_TEST_UNIX */
  607. return -1;
  608. #endif /* DRIVER_TEST_UNIX */
  609. }
  610. static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv,
  611. char *dst)
  612. {
  613. char *pos;
  614. pos = os_strchr(dst, ':');
  615. if (pos == NULL)
  616. return -1;
  617. *pos++ = '\0';
  618. wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos);
  619. drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0);
  620. if (drv->test_socket < 0) {
  621. perror("socket(PF_INET)");
  622. return -1;
  623. }
  624. os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp));
  625. drv->hostapd_addr_udp.sin_family = AF_INET;
  626. #if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
  627. {
  628. int a[4];
  629. u8 *pos;
  630. sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
  631. pos = (u8 *) &drv->hostapd_addr_udp.sin_addr;
  632. *pos++ = a[0];
  633. *pos++ = a[1];
  634. *pos++ = a[2];
  635. *pos++ = a[3];
  636. }
  637. #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
  638. inet_aton(dst, &drv->hostapd_addr_udp.sin_addr);
  639. #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
  640. drv->hostapd_addr_udp.sin_port = htons(atoi(pos));
  641. drv->hostapd_addr_udp_set = 1;
  642. eloop_register_read_sock(drv->test_socket,
  643. wpa_driver_test_receive_unix, drv, NULL);
  644. return 0;
  645. }
  646. static int wpa_driver_test_set_param(void *priv, const char *param)
  647. {
  648. struct wpa_driver_test_data *drv = priv;
  649. const char *pos;
  650. wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
  651. if (param == NULL)
  652. return 0;
  653. wpa_driver_test_close_test_socket(drv);
  654. #ifdef DRIVER_TEST_UNIX
  655. pos = os_strstr(param, "test_socket=");
  656. if (pos) {
  657. const char *pos2;
  658. size_t len;
  659. pos += 12;
  660. pos2 = os_strchr(pos, ' ');
  661. if (pos2)
  662. len = pos2 - pos;
  663. else
  664. len = os_strlen(pos);
  665. if (len > sizeof(drv->hostapd_addr.sun_path))
  666. return -1;
  667. os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
  668. drv->hostapd_addr.sun_family = AF_UNIX;
  669. os_memcpy(drv->hostapd_addr.sun_path, pos, len);
  670. drv->hostapd_addr_set = 1;
  671. }
  672. #endif /* DRIVER_TEST_UNIX */
  673. pos = os_strstr(param, "test_dir=");
  674. if (pos) {
  675. char *end;
  676. os_free(drv->test_dir);
  677. drv->test_dir = os_strdup(pos + 9);
  678. if (drv->test_dir == NULL)
  679. return -1;
  680. end = os_strchr(drv->test_dir, ' ');
  681. if (end)
  682. *end = '\0';
  683. if (wpa_driver_test_attach(drv, drv->test_dir))
  684. return -1;
  685. } else {
  686. pos = os_strstr(param, "test_udp=");
  687. if (pos) {
  688. char *dst, *epos;
  689. dst = os_strdup(pos + 9);
  690. if (dst == NULL)
  691. return -1;
  692. epos = os_strchr(dst, ' ');
  693. if (epos)
  694. *epos = '\0';
  695. if (wpa_driver_test_attach_udp(drv, dst))
  696. return -1;
  697. os_free(dst);
  698. } else if (wpa_driver_test_attach(drv, NULL))
  699. return -1;
  700. }
  701. if (os_strstr(param, "use_associnfo=1")) {
  702. wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
  703. drv->use_associnfo = 1;
  704. }
  705. #ifdef CONFIG_CLIENT_MLME
  706. if (os_strstr(param, "use_mlme=1")) {
  707. wpa_printf(MSG_DEBUG, "test_driver: Use internal MLME");
  708. drv->use_mlme = 1;
  709. }
  710. #endif /* CONFIG_CLIENT_MLME */
  711. return 0;
  712. }
  713. static const u8 * wpa_driver_test_get_mac_addr(void *priv)
  714. {
  715. struct wpa_driver_test_data *drv = priv;
  716. wpa_printf(MSG_DEBUG, "%s", __func__);
  717. return drv->own_addr;
  718. }
  719. static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto,
  720. const u8 *data, size_t data_len)
  721. {
  722. struct wpa_driver_test_data *drv = priv;
  723. char *msg;
  724. size_t msg_len;
  725. struct l2_ethhdr eth;
  726. struct sockaddr *addr;
  727. socklen_t alen;
  728. #ifdef DRIVER_TEST_UNIX
  729. struct sockaddr_un addr_un;
  730. #endif /* DRIVER_TEST_UNIX */
  731. wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len);
  732. os_memset(&eth, 0, sizeof(eth));
  733. os_memcpy(eth.h_dest, dest, ETH_ALEN);
  734. os_memcpy(eth.h_source, drv->own_addr, ETH_ALEN);
  735. eth.h_proto = host_to_be16(proto);
  736. msg_len = 6 + sizeof(eth) + data_len;
  737. msg = os_malloc(msg_len);
  738. if (msg == NULL)
  739. return -1;
  740. os_memcpy(msg, "EAPOL ", 6);
  741. os_memcpy(msg + 6, &eth, sizeof(eth));
  742. os_memcpy(msg + 6 + sizeof(eth), data, data_len);
  743. if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
  744. drv->test_dir == NULL) {
  745. if (drv->hostapd_addr_udp_set) {
  746. addr = (struct sockaddr *) &drv->hostapd_addr_udp;
  747. alen = sizeof(drv->hostapd_addr_udp);
  748. } else {
  749. #ifdef DRIVER_TEST_UNIX
  750. addr = (struct sockaddr *) &drv->hostapd_addr;
  751. alen = sizeof(drv->hostapd_addr);
  752. #else /* DRIVER_TEST_UNIX */
  753. os_free(msg);
  754. return -1;
  755. #endif /* DRIVER_TEST_UNIX */
  756. }
  757. } else {
  758. #ifdef DRIVER_TEST_UNIX
  759. struct stat st;
  760. os_memset(&addr_un, 0, sizeof(addr_un));
  761. addr_un.sun_family = AF_UNIX;
  762. os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
  763. "%s/STA-" MACSTR, drv->test_dir, MAC2STR(dest));
  764. if (stat(addr_un.sun_path, &st) < 0) {
  765. os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
  766. "%s/AP-" MACSTR,
  767. drv->test_dir, MAC2STR(dest));
  768. }
  769. addr = (struct sockaddr *) &addr_un;
  770. alen = sizeof(addr_un);
  771. #else /* DRIVER_TEST_UNIX */
  772. os_free(msg);
  773. return -1;
  774. #endif /* DRIVER_TEST_UNIX */
  775. }
  776. if (sendto(drv->test_socket, msg, msg_len, 0, addr, alen) < 0) {
  777. perror("sendmsg(test_socket)");
  778. os_free(msg);
  779. return -1;
  780. }
  781. os_free(msg);
  782. return 0;
  783. }
  784. static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
  785. {
  786. struct wpa_driver_test_data *drv = priv;
  787. os_memset(capa, 0, sizeof(*capa));
  788. capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
  789. WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
  790. WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
  791. WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
  792. WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE |
  793. WPA_DRIVER_CAPA_KEY_MGMT_FT |
  794. WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
  795. capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 |
  796. WPA_DRIVER_CAPA_ENC_WEP104 |
  797. WPA_DRIVER_CAPA_ENC_TKIP |
  798. WPA_DRIVER_CAPA_ENC_CCMP;
  799. capa->auth = WPA_DRIVER_AUTH_OPEN |
  800. WPA_DRIVER_AUTH_SHARED |
  801. WPA_DRIVER_AUTH_LEAP;
  802. if (drv->use_mlme)
  803. capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;
  804. return 0;
  805. }
  806. static int wpa_driver_test_mlme_setprotection(void *priv, const u8 *addr,
  807. int protect_type,
  808. int key_type)
  809. {
  810. wpa_printf(MSG_DEBUG, "%s: protect_type=%d key_type=%d",
  811. __func__, protect_type, key_type);
  812. if (addr) {
  813. wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR,
  814. __func__, MAC2STR(addr));
  815. }
  816. return 0;
  817. }
  818. #ifdef CONFIG_CLIENT_MLME
  819. static struct wpa_hw_modes *
  820. wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
  821. {
  822. struct wpa_hw_modes *modes;
  823. *num_modes = 1;
  824. *flags = 0;
  825. modes = os_zalloc(*num_modes * sizeof(struct wpa_hw_modes));
  826. if (modes == NULL)
  827. return NULL;
  828. modes[0].mode = WPA_MODE_IEEE80211G;
  829. modes[0].num_channels = 1;
  830. modes[0].num_rates = 1;
  831. modes[0].channels = os_zalloc(sizeof(struct wpa_channel_data));
  832. modes[0].rates = os_zalloc(sizeof(struct wpa_rate_data));
  833. if (modes[0].channels == NULL || modes[0].rates == NULL) {
  834. wpa_supplicant_sta_free_hw_features(modes, *num_modes);
  835. return NULL;
  836. }
  837. modes[0].channels[0].chan = 1;
  838. modes[0].channels[0].freq = 2412;
  839. modes[0].channels[0].flag = WPA_CHAN_W_SCAN | WPA_CHAN_W_ACTIVE_SCAN;
  840. modes[0].rates[0].rate = 10;
  841. modes[0].rates[0].flags = WPA_RATE_BASIC | WPA_RATE_SUPPORTED |
  842. WPA_RATE_CCK | WPA_RATE_MANDATORY;
  843. return modes;
  844. }
  845. static int wpa_driver_test_set_channel(void *priv, wpa_hw_mode phymode,
  846. int chan, int freq)
  847. {
  848. wpa_printf(MSG_DEBUG, "%s: phymode=%d chan=%d freq=%d",
  849. __func__, phymode, chan, freq);
  850. return 0;
  851. }
  852. static int wpa_driver_test_send_mlme(void *priv, const u8 *data,
  853. size_t data_len)
  854. {
  855. struct wpa_driver_test_data *drv = priv;
  856. struct msghdr msg;
  857. struct iovec io[2];
  858. struct sockaddr_un addr;
  859. const u8 *dest;
  860. struct dirent *dent;
  861. DIR *dir;
  862. wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len);
  863. if (data_len < 10)
  864. return -1;
  865. dest = data + 4;
  866. io[0].iov_base = "MLME ";
  867. io[0].iov_len = 5;
  868. io[1].iov_base = (u8 *) data;
  869. io[1].iov_len = data_len;
  870. os_memset(&msg, 0, sizeof(msg));
  871. msg.msg_iov = io;
  872. msg.msg_iovlen = 2;
  873. if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
  874. drv->test_dir == NULL) {
  875. if (drv->hostapd_addr_udp_set) {
  876. msg.msg_name = &drv->hostapd_addr_udp;
  877. msg.msg_namelen = sizeof(drv->hostapd_addr_udp);
  878. } else {
  879. #ifdef DRIVER_TEST_UNIX
  880. msg.msg_name = &drv->hostapd_addr;
  881. msg.msg_namelen = sizeof(drv->hostapd_addr);
  882. #endif /* DRIVER_TEST_UNIX */
  883. }
  884. } else if (os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
  885. {
  886. dir = opendir(drv->test_dir);
  887. if (dir == NULL)
  888. return -1;
  889. while ((dent = readdir(dir))) {
  890. #ifdef _DIRENT_HAVE_D_TYPE
  891. /* Skip the file if it is not a socket.
  892. * Also accept DT_UNKNOWN (0) in case
  893. * the C library or underlying file
  894. * system does not support d_type. */
  895. if (dent->d_type != DT_SOCK &&
  896. dent->d_type != DT_UNKNOWN)
  897. continue;
  898. #endif /* _DIRENT_HAVE_D_TYPE */
  899. if (os_strcmp(dent->d_name, ".") == 0 ||
  900. os_strcmp(dent->d_name, "..") == 0)
  901. continue;
  902. wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s",
  903. __func__, dent->d_name);
  904. os_memset(&addr, 0, sizeof(addr));
  905. addr.sun_family = AF_UNIX;
  906. os_snprintf(addr.sun_path, sizeof(addr.sun_path),
  907. "%s/%s", drv->test_dir, dent->d_name);
  908. msg.msg_name = &addr;
  909. msg.msg_namelen = sizeof(addr);
  910. if (sendmsg(drv->test_socket, &msg, 0) < 0)
  911. perror("sendmsg(test_socket)");
  912. }
  913. closedir(dir);
  914. return 0;
  915. } else {
  916. struct stat st;
  917. os_memset(&addr, 0, sizeof(addr));
  918. addr.sun_family = AF_UNIX;
  919. os_snprintf(addr.sun_path, sizeof(addr.sun_path),
  920. "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest));
  921. if (stat(addr.sun_path, &st) < 0) {
  922. os_snprintf(addr.sun_path, sizeof(addr.sun_path),
  923. "%s/STA-" MACSTR,
  924. drv->test_dir, MAC2STR(dest));
  925. }
  926. msg.msg_name = &addr;
  927. msg.msg_namelen = sizeof(addr);
  928. }
  929. if (sendmsg(drv->test_socket, &msg, 0) < 0) {
  930. perror("sendmsg(test_socket)");
  931. return -1;
  932. }
  933. return 0;
  934. }
  935. static int wpa_driver_test_mlme_add_sta(void *priv, const u8 *addr,
  936. const u8 *supp_rates,
  937. size_t supp_rates_len)
  938. {
  939. wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr));
  940. return 0;
  941. }
  942. static int wpa_driver_test_mlme_remove_sta(void *priv, const u8 *addr)
  943. {
  944. wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr));
  945. return 0;
  946. }
  947. static int wpa_driver_test_set_ssid(void *priv, const u8 *ssid,
  948. size_t ssid_len)
  949. {
  950. wpa_printf(MSG_DEBUG, "%s", __func__);
  951. return 0;
  952. }
  953. static int wpa_driver_test_set_bssid(void *priv, const u8 *bssid)
  954. {
  955. wpa_printf(MSG_DEBUG, "%s: bssid=" MACSTR, __func__, MAC2STR(bssid));
  956. return 0;
  957. }
  958. #endif /* CONFIG_CLIENT_MLME */
  959. static int wpa_driver_test_set_probe_req_ie(void *priv, const u8 *ies,
  960. size_t ies_len)
  961. {
  962. struct wpa_driver_test_data *drv = priv;
  963. os_free(drv->probe_req_ie);
  964. if (ies) {
  965. drv->probe_req_ie = os_malloc(ies_len);
  966. if (drv->probe_req_ie == NULL) {
  967. drv->probe_req_ie_len = 0;
  968. return -1;
  969. }
  970. os_memcpy(drv->probe_req_ie, ies, ies_len);
  971. drv->probe_req_ie_len = ies_len;
  972. } else {
  973. drv->probe_req_ie = NULL;
  974. drv->probe_req_ie_len = 0;
  975. }
  976. return 0;
  977. }
  978. static void * wpa_driver_test_global_init(void)
  979. {
  980. struct wpa_driver_test_global *global;
  981. global = os_zalloc(sizeof(*global));
  982. return global;
  983. }
  984. static void wpa_driver_test_global_deinit(void *priv)
  985. {
  986. struct wpa_driver_test_global *global = priv;
  987. os_free(global);
  988. }
  989. static struct wpa_interface_info *
  990. wpa_driver_test_get_interfaces(void *global_priv)
  991. {
  992. /* struct wpa_driver_test_global *global = priv; */
  993. struct wpa_interface_info *iface;
  994. iface = os_zalloc(sizeof(*iface));
  995. if (iface == NULL)
  996. return iface;
  997. iface->ifname = os_strdup("sta0");
  998. iface->desc = os_strdup("test interface 0");
  999. iface->drv_name = "test";
  1000. iface->next = os_zalloc(sizeof(*iface));
  1001. if (iface->next) {
  1002. iface->next->ifname = os_strdup("sta1");
  1003. iface->next->desc = os_strdup("test interface 1");
  1004. iface->next->drv_name = "test";
  1005. }
  1006. return iface;
  1007. }
  1008. const struct wpa_driver_ops wpa_driver_test_ops = {
  1009. "test",
  1010. "wpa_supplicant test driver",
  1011. wpa_driver_test_get_bssid,
  1012. wpa_driver_test_get_ssid,
  1013. wpa_driver_test_set_wpa,
  1014. wpa_driver_test_set_key,
  1015. NULL /* init */,
  1016. wpa_driver_test_deinit,
  1017. wpa_driver_test_set_param,
  1018. NULL /* set_countermeasures */,
  1019. NULL /* set_drop_unencrypted */,
  1020. wpa_driver_test_scan,
  1021. NULL /* get_scan_results */,
  1022. wpa_driver_test_deauthenticate,
  1023. wpa_driver_test_disassociate,
  1024. wpa_driver_test_associate,
  1025. NULL /* set_auth_alg */,
  1026. NULL /* add_pmkid */,
  1027. NULL /* remove_pmkid */,
  1028. NULL /* flush_pmkid */,
  1029. wpa_driver_test_get_capa,
  1030. NULL /* poll */,
  1031. NULL /* get_ifname */,
  1032. wpa_driver_test_get_mac_addr,
  1033. wpa_driver_test_send_eapol,
  1034. NULL /* set_operstate */,
  1035. wpa_driver_test_mlme_setprotection,
  1036. #ifdef CONFIG_CLIENT_MLME
  1037. wpa_driver_test_get_hw_feature_data,
  1038. wpa_driver_test_set_channel,
  1039. wpa_driver_test_set_ssid,
  1040. wpa_driver_test_set_bssid,
  1041. wpa_driver_test_send_mlme,
  1042. wpa_driver_test_mlme_add_sta,
  1043. wpa_driver_test_mlme_remove_sta,
  1044. #else /* CONFIG_CLIENT_MLME */
  1045. NULL /* get_hw_feature_data */,
  1046. NULL /* set_channel */,
  1047. NULL /* set_ssid */,
  1048. NULL /* set_bssid */,
  1049. NULL /* send_mlme */,
  1050. NULL /* mlme_add_sta */,
  1051. NULL /* mlme_remove_sta */,
  1052. #endif /* CONFIG_CLIENT_MLME */
  1053. NULL /* update_ft_ies */,
  1054. NULL /* send_ft_action */,
  1055. wpa_driver_test_get_scan_results2,
  1056. wpa_driver_test_set_probe_req_ie,
  1057. NULL /* set_mode */,
  1058. NULL /* set_country */,
  1059. wpa_driver_test_global_init,
  1060. wpa_driver_test_global_deinit,
  1061. wpa_driver_test_init2,
  1062. wpa_driver_test_get_interfaces
  1063. };