00001
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019 #include <unistd.h>
00020 #include <sys/socket.h>
00021 #include <sys/un.h>
00022
00023 #include "common.h"
00024 #include "driver.h"
00025 #include "wpa_supplicant.h"
00026 #include "l2_packet.h"
00027 #include "eloop.h"
00028 #include "sha1.h"
00029 #include "wpa.h"
00030
00031
00032 struct wpa_driver_test_data {
00033 void *ctx;
00034 u8 own_addr[ETH_ALEN];
00035 int test_socket;
00036 struct sockaddr_un hostapd_addr;
00037 char *own_socket_path;
00038 u8 bssid[ETH_ALEN];
00039 u8 ssid[32];
00040 size_t ssid_len;
00041 struct wpa_scan_result scanres;
00042 size_t num_scanres;
00043 int use_associnfo;
00044 u8 assoc_wpa_ie[80];
00045 size_t assoc_wpa_ie_len;
00046 };
00047
00048
00049 static int wpa_driver_test_set_wpa(void *priv, int enabled)
00050 {
00051 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
00052 return 0;
00053 }
00054
00055
00056 static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
00057 {
00058 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
00059 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
00060 }
00061
00062
00063 static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len)
00064 {
00065 struct wpa_driver_test_data *drv = priv;
00066 wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
00067
00068 if (drv->test_socket >= 0) {
00069 if (sendto(drv->test_socket, "SCAN", 4, 0,
00070 (struct sockaddr *) &drv->hostapd_addr,
00071 sizeof(drv->hostapd_addr)) < 0) {
00072 perror("sendto(test_socket)");
00073 return -1;
00074 }
00075 } else {
00076 eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
00077 drv->ctx);
00078 }
00079 return 0;
00080 }
00081
00082
00083 static int wpa_driver_test_get_scan_results(void *priv,
00084 struct wpa_scan_result *results,
00085 size_t max_size)
00086 {
00087 struct wpa_driver_test_data *drv = priv;
00088 memcpy(results, &drv->scanres, sizeof(drv->scanres));
00089 return drv->num_scanres;
00090 }
00091
00092
00093 static int wpa_driver_test_set_key(void *priv, wpa_alg alg, const u8 *addr,
00094 int key_idx, int set_tx,
00095 const u8 *seq, size_t seq_len,
00096 const u8 *key, size_t key_len)
00097 {
00098 wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
00099 __func__, priv, alg, key_idx, set_tx);
00100 if (addr) {
00101 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
00102 }
00103 if (seq) {
00104 wpa_hexdump(MSG_DEBUG, " seq", seq, seq_len);
00105 }
00106 if (key) {
00107 wpa_hexdump(MSG_DEBUG, " key", key, key_len);
00108 }
00109 return 0;
00110 }
00111
00112
00113 static int wpa_driver_test_associate(
00114 void *priv, struct wpa_driver_associate_params *params)
00115 {
00116 struct wpa_driver_test_data *drv = priv;
00117 wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
00118 "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
00119 __func__, priv, params->freq, params->pairwise_suite,
00120 params->group_suite, params->key_mgmt_suite,
00121 params->auth_alg, params->mode);
00122 if (params->bssid) {
00123 wpa_printf(MSG_DEBUG, " bssid=" MACSTR,
00124 MAC2STR(params->bssid));
00125 }
00126 if (params->ssid) {
00127 wpa_hexdump_ascii(MSG_DEBUG, " ssid",
00128 params->ssid, params->ssid_len);
00129 }
00130 if (params->wpa_ie) {
00131 wpa_hexdump(MSG_DEBUG, " wpa_ie",
00132 params->wpa_ie, params->wpa_ie_len);
00133 drv->assoc_wpa_ie_len = params->wpa_ie_len;
00134 if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie))
00135 drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie);
00136 memcpy(drv->assoc_wpa_ie, params->wpa_ie,
00137 drv->assoc_wpa_ie_len);
00138 } else
00139 drv->assoc_wpa_ie_len = 0;
00140
00141 if (drv->test_socket >= 0) {
00142 char cmd[200], *pos, *end;
00143 int i;
00144 end = cmd + sizeof(cmd);
00145 pos = cmd;
00146 pos += snprintf(pos, end - pos, "ASSOC " MACSTR " ",
00147 MAC2STR(drv->own_addr));
00148 for (i = 0; i < params->ssid_len; i++) {
00149 pos += snprintf(pos, end - pos, "%02x",
00150 params->ssid[i]);
00151 }
00152 pos += snprintf(pos, end - pos, " ");
00153 for (i = 0; i < params->wpa_ie_len; i++) {
00154 pos += snprintf(pos, end - pos, "%02x",
00155 params->wpa_ie[i]);
00156 }
00157 if (sendto(drv->test_socket, cmd, strlen(cmd), 0,
00158 (struct sockaddr *) &drv->hostapd_addr,
00159 sizeof(drv->hostapd_addr)) < 0) {
00160 perror("sendto(test_socket)");
00161 return -1;
00162 }
00163
00164 memcpy(drv->ssid, params->ssid, params->ssid_len);
00165 drv->ssid_len = params->ssid_len;
00166 } else
00167 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
00168
00169 return 0;
00170 }
00171
00172
00173 static int wpa_driver_test_get_bssid(void *priv, u8 *bssid)
00174 {
00175 struct wpa_driver_test_data *drv = priv;
00176 memcpy(bssid, drv->bssid, ETH_ALEN);
00177 return 0;
00178 }
00179
00180
00181 static int wpa_driver_test_get_ssid(void *priv, u8 *ssid)
00182 {
00183 struct wpa_driver_test_data *drv = priv;
00184 memcpy(ssid, drv->ssid, 32);
00185 return drv->ssid_len;
00186 }
00187
00188
00189 static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv)
00190 {
00191 if (drv->test_socket >= 0 &&
00192 sendto(drv->test_socket, "DISASSOC", 8, 0,
00193 (struct sockaddr *) &drv->hostapd_addr,
00194 sizeof(drv->hostapd_addr)) < 0) {
00195 perror("sendto(test_socket)");
00196 return -1;
00197 }
00198 return 0;
00199 }
00200
00201
00202 static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr,
00203 int reason_code)
00204 {
00205 struct wpa_driver_test_data *drv = priv;
00206 wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
00207 __func__, MAC2STR(addr), reason_code);
00208 memset(drv->bssid, 0, ETH_ALEN);
00209 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
00210 return wpa_driver_test_send_disassoc(drv);
00211 }
00212
00213
00214 static int wpa_driver_test_disassociate(void *priv, const u8 *addr,
00215 int reason_code)
00216 {
00217 struct wpa_driver_test_data *drv = priv;
00218 wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
00219 __func__, MAC2STR(addr), reason_code);
00220 memset(drv->bssid, 0, ETH_ALEN);
00221 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
00222 return wpa_driver_test_send_disassoc(drv);
00223 }
00224
00225
00226 static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv,
00227 struct sockaddr_un *from,
00228 socklen_t fromlen,
00229 const char *data)
00230 {
00231 struct wpa_scan_result *res;
00232 const char *pos, *pos2;
00233 size_t len;
00234 u8 ie[200], *ipos, *end;
00235
00236 wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data);
00237
00238 res = &drv->scanres;
00239 drv->num_scanres = 0;
00240
00241 memset(res, 0, sizeof(*res));
00242 if (hwaddr_aton(data, res->bssid)) {
00243 wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres");
00244 return;
00245 }
00246
00247 pos = data + 17;
00248 while (*pos == ' ')
00249 pos++;
00250 pos2 = strchr(pos, ' ');
00251 if (pos2 == NULL) {
00252 wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination "
00253 "in scanres");
00254 return;
00255 }
00256 len = (pos2 - pos) / 2;
00257 if (len > sizeof(res->ssid))
00258 len = sizeof(res->ssid);
00259 if (hexstr2bin(pos, res->ssid, len) < 0) {
00260 wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres");
00261 return;
00262 }
00263 res->ssid_len = len;
00264
00265 pos = pos2 + 1;
00266 while (*pos == ' ')
00267 pos++;
00268 pos2 = strchr(pos, ' ');
00269 if (pos2 == NULL)
00270 len = strlen(pos) / 2;
00271 else
00272 len = (pos2 - pos) / 2;
00273 if (len > sizeof(ie))
00274 len = sizeof(ie);
00275 if (hexstr2bin(pos, ie, len) < 0) {
00276 wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres");
00277 return;
00278 }
00279
00280 ipos = ie;
00281 end = ipos + len;
00282 while (ipos + 1 < end && ipos + 2 + ipos[1] <= end) {
00283 len = 2 + ipos[1];
00284 if (len > SSID_MAX_WPA_IE_LEN)
00285 len = SSID_MAX_WPA_IE_LEN;
00286 if (ipos[0] == RSN_INFO_ELEM) {
00287 memcpy(res->rsn_ie, ipos, len);
00288 res->rsn_ie_len = len;
00289 } else if (ipos[0] == GENERIC_INFO_ELEM) {
00290 memcpy(res->wpa_ie, ipos, len);
00291 res->wpa_ie_len = len;
00292 }
00293
00294 ipos += 2 + ipos[1];
00295 }
00296
00297 drv->num_scanres = 1;
00298 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
00299 }
00300
00301
00302 static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv,
00303 struct sockaddr_un *from,
00304 socklen_t fromlen,
00305 const char *data)
00306 {
00307
00308 if (hwaddr_aton(data, drv->bssid)) {
00309 wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in "
00310 "assocresp");
00311 }
00312 if (drv->use_associnfo) {
00313 union wpa_event_data event;
00314 memset(&event, 0, sizeof(event));
00315 event.assoc_info.req_ies = drv->assoc_wpa_ie;
00316 event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len;
00317 wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event);
00318 }
00319 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
00320 }
00321
00322
00323 static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv,
00324 struct sockaddr_un *from,
00325 socklen_t fromlen)
00326 {
00327 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
00328 }
00329
00330
00331 static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
00332 struct sockaddr_un *from,
00333 socklen_t fromlen,
00334 const u8 *data, size_t data_len)
00335 {
00336 if (data_len > 14) {
00337
00338 data += 14;
00339 data_len -= 14;
00340 }
00341 wpa_supplicant_rx_eapol(drv->ctx, drv->bssid, (u8 *) data, data_len);
00342 }
00343
00344
00345 static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx,
00346 void *sock_ctx)
00347 {
00348 struct wpa_driver_test_data *drv = eloop_ctx;
00349 char *buf;
00350 int res;
00351 struct sockaddr_un from;
00352 socklen_t fromlen = sizeof(from);
00353 const size_t buflen = 2000;
00354
00355 buf = malloc(buflen);
00356 if (buf == NULL)
00357 return;
00358 res = recvfrom(sock, buf, buflen - 1, 0,
00359 (struct sockaddr *) &from, &fromlen);
00360 if (res < 0) {
00361 perror("recvfrom(test_socket)");
00362 free(buf);
00363 return;
00364 }
00365 buf[res] = '\0';
00366
00367 wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
00368
00369 if (strncmp(buf, "SCANRESP ", 9) == 0) {
00370 wpa_driver_test_scanresp(drv, &from, fromlen, buf + 9);
00371 } else if (strncmp(buf, "ASSOCRESP ", 10) == 0) {
00372 wpa_driver_test_assocresp(drv, &from, fromlen, buf + 10);
00373 } else if (strcmp(buf, "DISASSOC") == 0) {
00374 wpa_driver_test_disassoc(drv, &from, fromlen);
00375 } else if (strcmp(buf, "DEAUTH") == 0) {
00376 wpa_driver_test_disassoc(drv, &from, fromlen);
00377 } else if (strncmp(buf, "EAPOL ", 6) == 0) {
00378 wpa_driver_test_eapol(drv, &from, fromlen,
00379 (const u8 *) buf + 6, res - 6);
00380 } else {
00381 wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
00382 (u8 *) buf, res);
00383 }
00384 free(buf);
00385 }
00386
00387
00388 static void * wpa_driver_test_init(void *ctx, const char *ifname)
00389 {
00390 struct wpa_driver_test_data *drv;
00391
00392 drv = malloc(sizeof(*drv));
00393 if (drv == NULL)
00394 return NULL;
00395 memset(drv, 0, sizeof(*drv));
00396 drv->ctx = ctx;
00397 drv->test_socket = -1;
00398
00399
00400 drv->bssid[0] = 0x02;
00401 drv->bssid[1] = 0x00;
00402 drv->bssid[2] = 0x00;
00403 drv->bssid[3] = 0x00;
00404 drv->bssid[4] = 0x00;
00405 drv->bssid[5] = 0x01;
00406 memcpy(drv->ssid, "test", 5);
00407 drv->ssid_len = 4;
00408
00409
00410 drv->own_addr[0] = 0x02;
00411 sha1_prf((const u8 *) ifname, strlen(ifname),
00412 "wpa_supplicant test mac addr generation",
00413 NULL, 0, drv->own_addr + 1, ETH_ALEN - 1);
00414
00415 return drv;
00416 }
00417
00418
00419 static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv)
00420 {
00421 if (drv->test_socket >= 0) {
00422 eloop_unregister_read_sock(drv->test_socket);
00423 close(drv->test_socket);
00424 drv->test_socket = -1;
00425 }
00426
00427 if (drv->own_socket_path) {
00428 unlink(drv->own_socket_path);
00429 free(drv->own_socket_path);
00430 drv->own_socket_path = NULL;
00431 }
00432 }
00433
00434
00435 static void wpa_driver_test_deinit(void *priv)
00436 {
00437 struct wpa_driver_test_data *drv = priv;
00438 wpa_driver_test_close_test_socket(drv);
00439 free(drv);
00440 }
00441
00442
00443 static int wpa_driver_test_attach(struct wpa_driver_test_data *drv)
00444 {
00445 static unsigned int counter = 0;
00446 struct sockaddr_un addr;
00447
00448 drv->own_socket_path = malloc(100);
00449 if (drv->own_socket_path == NULL)
00450 return -1;
00451 snprintf(drv->own_socket_path, 100, "/tmp/wpa_supplicant_test-%d-%d",
00452 getpid(), counter++);
00453
00454 drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
00455 if (drv->test_socket < 0) {
00456 perror("socket(PF_UNIX)");
00457 free(drv->own_socket_path);
00458 drv->own_socket_path = NULL;
00459 return -1;
00460 }
00461
00462 memset(&addr, 0, sizeof(addr));
00463 addr.sun_family = AF_UNIX;
00464 strncpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
00465 if (bind(drv->test_socket, (struct sockaddr *) &addr,
00466 sizeof(addr)) < 0) {
00467 perror("bind(PF_UNIX)");
00468 close(drv->test_socket);
00469 unlink(drv->own_socket_path);
00470 free(drv->own_socket_path);
00471 drv->own_socket_path = NULL;
00472 return -1;
00473 }
00474
00475 eloop_register_read_sock(drv->test_socket,
00476 wpa_driver_test_receive_unix, drv, NULL);
00477
00478 return 0;
00479 }
00480
00481
00482 static int wpa_driver_test_set_param(void *priv, const char *param)
00483 {
00484 struct wpa_driver_test_data *drv = priv;
00485 const char *pos, *pos2;
00486 size_t len;
00487
00488 wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
00489 if (param == NULL)
00490 return 0;
00491
00492 wpa_driver_test_close_test_socket(drv);
00493 pos = strstr(param, "test_socket=");
00494 if (pos) {
00495 pos += 12;
00496 pos2 = strchr(pos, ' ');
00497 if (pos2)
00498 len = pos2 - pos;
00499 else
00500 len = strlen(pos);
00501 if (len > sizeof(drv->hostapd_addr.sun_path))
00502 return -1;
00503 memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
00504 drv->hostapd_addr.sun_family = AF_UNIX;
00505 memcpy(drv->hostapd_addr.sun_path, pos, len);
00506 wpa_driver_test_attach(drv);
00507 }
00508
00509 if (strstr(param, "use_associnfo=1")) {
00510 wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
00511 drv->use_associnfo = 1;
00512 }
00513
00514 return 0;
00515 }
00516
00517
00518 static const u8 * wpa_driver_test_get_mac_addr(void *priv)
00519 {
00520 struct wpa_driver_test_data *drv = priv;
00521 wpa_printf(MSG_DEBUG, "%s", __func__);
00522 return drv->own_addr;
00523 }
00524
00525
00526 static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto,
00527 const u8 *data, size_t data_len)
00528 {
00529 struct wpa_driver_test_data *drv = priv;
00530 struct msghdr msg;
00531 struct iovec io[3];
00532 struct l2_ethhdr eth;
00533
00534 wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len);
00535
00536 memset(ð, 0, sizeof(eth));
00537 memcpy(eth.h_dest, dest, ETH_ALEN);
00538 memcpy(eth.h_source, drv->own_addr, ETH_ALEN);
00539 eth.h_proto = host_to_be16(proto);
00540
00541 io[0].iov_base = "EAPOL ";
00542 io[0].iov_len = 6;
00543 io[1].iov_base = (u8 *) ð
00544 io[1].iov_len = sizeof(eth);
00545 io[2].iov_base = (u8 *) data;
00546 io[2].iov_len = data_len;
00547
00548 memset(&msg, 0, sizeof(msg));
00549 msg.msg_iov = io;
00550 msg.msg_iovlen = 3;
00551 msg.msg_name = &drv->hostapd_addr;
00552 msg.msg_namelen = sizeof(drv->hostapd_addr);
00553 if (sendmsg(drv->test_socket, &msg, 0) < 0) {
00554 perror("sendmsg(test_socket)");
00555 return -1;
00556 }
00557
00558 return 0;
00559 }
00560
00561
00562 static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
00563 {
00564 memset(capa, 0, sizeof(*capa));
00565 capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
00566 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
00567 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
00568 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
00569 WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE;
00570 capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 |
00571 WPA_DRIVER_CAPA_ENC_WEP104 |
00572 WPA_DRIVER_CAPA_ENC_TKIP |
00573 WPA_DRIVER_CAPA_ENC_CCMP;
00574 capa->auth = WPA_DRIVER_AUTH_OPEN |
00575 WPA_DRIVER_AUTH_SHARED |
00576 WPA_DRIVER_AUTH_LEAP;
00577
00578 return 0;
00579 }
00580
00581
00582 const struct wpa_driver_ops wpa_driver_test_ops = {
00583 .name = "test",
00584 .desc = "wpa_supplicant test driver",
00585 .init = wpa_driver_test_init,
00586 .deinit = wpa_driver_test_deinit,
00587 .set_param = wpa_driver_test_set_param,
00588 .set_wpa = wpa_driver_test_set_wpa,
00589 .scan = wpa_driver_test_scan,
00590 .get_scan_results = wpa_driver_test_get_scan_results,
00591 .set_key = wpa_driver_test_set_key,
00592 .associate = wpa_driver_test_associate,
00593 .get_bssid = wpa_driver_test_get_bssid,
00594 .get_ssid = wpa_driver_test_get_ssid,
00595 .get_mac_addr = wpa_driver_test_get_mac_addr,
00596 .send_eapol = wpa_driver_test_send_eapol,
00597 .deauthenticate = wpa_driver_test_deauthenticate,
00598 .disassociate = wpa_driver_test_disassociate,
00599 .get_capa = wpa_driver_test_get_capa,
00600 };
00601