~ubuntu-branches/ubuntu/gutsy/wpasupplicant/gutsy

« back to all changes in this revision

Viewing changes to driver_test.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler, Alexander Sack
  • Date: 2007-08-26 16:06:57 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070826160657-2m8pxoweuxe8f93t
Tags: 0.6.0+0.5.8-0ubuntu1
* New upstream release
* remove patch 11_erroneous_manpage_ref, applied upstream
* remove patch 25_wpas_dbus_unregister_iface_fix, applied upstream

[ Alexander Sack ]
* bumping upstream version to replace development version 0.6.0 with
  this package from stable release branch.
* attempt to fix wierd timeout and high latency issues by going
  back to stable upstream version (0.5.9) (LP: #140763,
  LP: #141233).

Show diffs side-by-side

added added

removed removed

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