~ubuntu-branches/ubuntu/oneiric/wpasupplicant/oneiric

« back to all changes in this revision

Viewing changes to driver_bsd.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2006-10-05 08:04:01 UTC
  • mfrom: (1.2.1 upstream) (2.1.14 edgy)
  • Revision ID: james.westby@ubuntu.com-20061005080401-myfwjtq7di70dyeo
* Update madwifi headers to latest SVN. (Closes: #388316)
* Remove failed attempt at action locking. [debian/functions.sh,
  debian/wpa_action.sh]
* Add hysteresis checking functions, to avoid "event loops" while
  using wpa-roam. [debian/functions.sh, debian/wpa_action.sh]
* Change of co-maintainer email address.
* Add ishex() function to functions.sh to determine wpa-psk value type in
  plaintext or hex. This effectively eliminates the need for the bogus and
  somewhat confusing wpa-passphrase contruct specific to our scripts and
  allows wpa-psk to work with either a 8 to 63 character long plaintext
  string or 64 character long hex string.
* Adjust README.modes to not refer to the redundant wpa-passphrase stuff.
* Add big fat NOTE about acceptable wpa-psk's to top of example gallery.
* Strip surrounding quotes from wpa-ssid if present, instead of just whining
  about them.
* Update email address in copyright blurb of functions.sh, ifupdown.sh and
  wpa_action.sh.  

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 * See README and COPYING for more details.
13
13
 */
14
14
 
15
 
#include <stdlib.h>
16
 
#include <stdio.h>
17
 
#include <unistd.h>
18
 
#include <string.h>
 
15
#include "includes.h"
19
16
#include <sys/ioctl.h>
20
 
#include <errno.h>
21
17
 
22
18
#include "common.h"
23
19
#include "driver.h"
24
 
#include "driver_wext.h"
25
20
#include "eloop.h"
26
21
#include "wpa_supplicant.h"
27
22
#include "l2_packet.h"
 
23
#include "wpa.h"                        /* XXX for RSN_INFO_ELEM */
28
24
 
29
 
#include <sys/socket.h>
30
25
#include <net/if.h>
 
26
#include <net/ethernet.h>
31
27
 
32
28
#include <net80211/ieee80211.h>
33
29
#include <net80211/ieee80211_crypto.h>
37
33
        int     sock;                   /* open socket for 802.11 ioctls */
38
34
        int     route;                  /* routing socket for events */
39
35
        char    ifname[IFNAMSIZ+1];     /* interface name */
 
36
        unsigned int ifindex;           /* interface index */
40
37
        void    *ctx;
 
38
        int     prev_roaming;           /* roaming state to restore on deinit */
 
39
        int     prev_privacy;           /* privacy state to restore on deinit */
 
40
        int     prev_wpa;               /* wpa state to restore on deinit */
41
41
};
42
42
 
43
43
static int
52
52
        ireq.i_data = (void *) arg;
53
53
 
54
54
        if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) {
55
 
                perror("ioctl[SIOCS80211]");
 
55
                fprintf(stderr, "ioctl[SIOCS80211, op %u, len %u]: %s\n",
 
56
                        op, arg_len, strerror(errno));
56
57
                return -1;
57
58
        }
58
59
        return 0;
70
71
        ireq.i_data = arg;
71
72
 
72
73
        if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) {
73
 
                perror("ioctl[SIOCG80211]");
 
74
                fprintf(stderr, "ioctl[SIOCG80211, op %u, len %u]: %s\n",
 
75
                        op, arg_len, strerror(errno));
74
76
                return -1;
75
77
        }
76
78
        return ireq.i_len;
87
89
        ireq.i_val = arg;
88
90
 
89
91
        if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) {
90
 
                perror("ioctl[SIOCS80211]");
 
92
                fprintf(stderr, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n",
 
93
                        op, arg, strerror(errno));
91
94
                return -1;
92
95
        }
93
96
        return 0;
94
97
}
95
98
 
96
99
static int
 
100
get80211param(struct wpa_driver_bsd_data *drv, int op)
 
101
{
 
102
        struct ieee80211req ireq;
 
103
 
 
104
        memset(&ireq, 0, sizeof(ireq));
 
105
        strncpy(ireq.i_name, drv->ifname, IFNAMSIZ);
 
106
        ireq.i_type = op;
 
107
 
 
108
        if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) {
 
109
                fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n",
 
110
                        op, strerror(errno));
 
111
                return -1;
 
112
        }
 
113
        return ireq.i_val;
 
114
}
 
115
 
 
116
static int
97
117
getifflags(struct wpa_driver_bsd_data *drv, int *flags)
98
118
{
99
119
        struct ifreq ifr;
169
189
}
170
190
 
171
191
static int
 
192
wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
 
193
{
 
194
        struct wpa_driver_bsd_data *drv = priv;
 
195
        int ret = 0;
 
196
 
 
197
        wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d",
 
198
                __FUNCTION__, wpa, privacy);
 
199
 
 
200
        if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0)
 
201
                ret = -1;
 
202
        if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
 
203
                ret = -1;
 
204
        if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0)
 
205
                ret = -1;
 
206
 
 
207
        return ret;
 
208
}
 
209
 
 
210
static int
172
211
wpa_driver_bsd_set_wpa(void *priv, int enabled)
173
212
{
174
 
        struct wpa_driver_bsd_data *drv = priv;
175
 
        int ret = 0;
176
 
 
177
213
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
178
214
 
179
 
        if (!enabled && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0)
180
 
                ret = -1;
181
 
        if (set80211param(drv, IEEE80211_IOC_ROAMING, enabled ? 2 : 0) < 0)
182
 
                ret = -1;
183
 
        if (set80211param(drv, IEEE80211_IOC_PRIVACY, enabled) < 0)
184
 
                ret = -1;
185
 
        if (set80211param(drv, IEEE80211_IOC_WPA, enabled ? 3 : 0) < 0)
186
 
                ret = -1;
187
 
 
188
 
        return ret;
 
215
        return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled);
189
216
}
190
217
 
191
218
static int
194
221
{
195
222
        struct ieee80211req_del_key wk;
196
223
 
197
 
        wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __FUNCTION__, key_idx);
198
224
        memset(&wk, 0, sizeof(wk));
199
 
        wk.idk_keyix = key_idx;
200
 
        if (addr != NULL)
 
225
        if (addr != NULL &&
 
226
            bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) {
 
227
                struct ether_addr ea;
 
228
 
 
229
                memcpy(&ea, addr, IEEE80211_ADDR_LEN);
 
230
                wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d",
 
231
                        __func__, ether_ntoa(&ea), key_idx);
201
232
                memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
202
 
 
 
233
                wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE;
 
234
        } else {
 
235
                wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx);
 
236
                wk.idk_keyix = key_idx;
 
237
        }
203
238
        return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
204
239
}
205
240
 
211
246
{
212
247
        struct wpa_driver_bsd_data *drv = priv;
213
248
        struct ieee80211req_key wk;
 
249
        struct ether_addr ea;
214
250
        char *alg_name;
215
251
        u_int8_t cipher;
216
252
 
232
268
                break;
233
269
        default:
234
270
                wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
235
 
                        __FUNCTION__, alg);
 
271
                        __func__, alg);
236
272
                return -1;
237
273
        }
238
274
 
239
 
        wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%d "
240
 
                   "key_len=%d", __FUNCTION__, alg_name, key_idx, set_tx,
241
 
                   seq_len, key_len);
 
275
        memcpy(&ea, addr, IEEE80211_ADDR_LEN);
 
276
        wpa_printf(MSG_DEBUG,
 
277
                "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu",
 
278
                __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx,
 
279
                seq_len, key_len);
242
280
 
243
281
        if (seq_len > sizeof(u_int64_t)) {
244
 
                wpa_printf(MSG_DEBUG, "%s: seq_len %d too big",
245
 
                        __FUNCTION__, seq_len);
 
282
                wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big",
 
283
                        __func__, seq_len);
246
284
                return -2;
247
285
        }
248
286
        if (key_len > sizeof(wk.ik_keydata)) {
249
 
                wpa_printf(MSG_DEBUG, "%s: key length %d too big",
250
 
                        __FUNCTION__, key_len);
 
287
                wpa_printf(MSG_DEBUG, "%s: key length %zu too big",
 
288
                        __func__, key_len);
251
289
                return -3;
252
290
        }
253
291
 
254
292
        memset(&wk, 0, sizeof(wk));
255
293
        wk.ik_type = cipher;
256
294
        wk.ik_flags = IEEE80211_KEY_RECV;
257
 
        if (set_tx) {
258
 
                wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT;
259
 
                memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
260
 
        } else
261
 
                memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN);
262
 
        wk.ik_keyix = key_idx;
 
295
        if (set_tx)
 
296
                wk.ik_flags |= IEEE80211_KEY_XMIT;
 
297
        memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
 
298
        /*
 
299
         * Deduce whether group/global or unicast key by checking
 
300
         * the address (yech).  Note also that we can only mark global
 
301
         * keys default; doing this for a unicast key is an error.
 
302
         */
 
303
        if (bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) == 0) {
 
304
                wk.ik_flags |= IEEE80211_KEY_GROUP;
 
305
                wk.ik_keyix = key_idx;
 
306
        } else {
 
307
                wk.ik_keyix = (key_idx == 0 ? IEEE80211_KEYIX_NONE : key_idx);
 
308
        }
 
309
        if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
 
310
                wk.ik_flags |= IEEE80211_KEY_DEFAULT;
263
311
        wk.ik_keylen = key_len;
264
312
        memcpy(&wk.ik_keyrsc, seq, seq_len);
265
313
        memcpy(wk.ik_keydata, key, key_len);
272
320
{
273
321
        struct wpa_driver_bsd_data *drv = priv;
274
322
 
275
 
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
 
323
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
276
324
        return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
277
325
}
278
326
 
282
330
{
283
331
        struct wpa_driver_bsd_data *drv = priv;
284
332
 
285
 
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
 
333
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
286
334
        return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled);
287
335
}
288
336
 
292
340
        struct wpa_driver_bsd_data *drv = priv;
293
341
        struct ieee80211req_mlme mlme;
294
342
 
295
 
        wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
 
343
        wpa_printf(MSG_DEBUG, "%s", __func__);
 
344
        memset(&mlme, 0, sizeof(mlme));
296
345
        mlme.im_op = IEEE80211_MLME_DEAUTH;
297
346
        mlme.im_reason = reason_code;
298
347
        memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
305
354
        struct wpa_driver_bsd_data *drv = priv;
306
355
        struct ieee80211req_mlme mlme;
307
356
 
308
 
        wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
 
357
        wpa_printf(MSG_DEBUG, "%s", __func__);
 
358
        memset(&mlme, 0, sizeof(mlme));
309
359
        mlme.im_op = IEEE80211_MLME_DISASSOC;
310
360
        mlme.im_reason = reason_code;
311
361
        memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
317
367
{
318
368
        struct wpa_driver_bsd_data *drv = priv;
319
369
        struct ieee80211req_mlme mlme;
320
 
 
321
 
        int ret = 0;
322
 
 
323
 
        wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
324
 
 
325
 
        /*
326
 
         * NB: Don't need to set the freq or cipher-related state as
327
 
         *     this is implied by the bssid which is used to locate
328
 
         *     the scanned node state which holds it.  The ssid is
329
 
         *     needed to disambiguate an AP that broadcasts multiple
330
 
         *     ssid's but uses the same bssid.
331
 
         */
 
370
        int privacy;
 
371
 
 
372
        wpa_printf(MSG_DEBUG,
 
373
                "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
 
374
                , __func__
 
375
                , params->ssid_len, params->ssid
 
376
                , params->wpa_ie_len
 
377
                , params->pairwise_suite
 
378
                , params->group_suite
 
379
                , params->key_mgmt_suite
 
380
        );
 
381
 
332
382
        /* XXX error handling is wrong but unclear what to do... */
333
383
        if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
334
 
                ret = -1;
 
384
                return -1;
 
385
#ifndef NEW_FREEBSD_MLME_ASSOC
335
386
        if (wpa_driver_bsd_set_ssid(drv, params->ssid, params->ssid_len) < 0)
336
 
                ret = -1;
 
387
                return -1;
 
388
#endif
 
389
 
 
390
        privacy = !(params->pairwise_suite == CIPHER_NONE &&
 
391
            params->group_suite == CIPHER_NONE &&
 
392
            params->key_mgmt_suite == KEY_MGMT_NONE &&
 
393
            params->wpa_ie_len == 0);
 
394
        wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
 
395
 
 
396
        if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
 
397
                return -1;
 
398
 
 
399
        if (params->wpa_ie_len &&
 
400
            set80211param(drv, IEEE80211_IOC_WPA,
 
401
                          params->wpa_ie[0] == RSN_INFO_ELEM ? 2 : 1) < 0)
 
402
                return -1;
 
403
 
337
404
        memset(&mlme, 0, sizeof(mlme));
338
405
        mlme.im_op = IEEE80211_MLME_ASSOC;
339
 
        memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
 
406
#ifdef NEW_FREEBSD_MLME_ASSOC
 
407
        if (params->ssid != NULL)
 
408
                memcpy(mlme.im_ssid, params->ssid, params->ssid_len);
 
409
        mlme.im_ssid_len = params->ssid_len;
 
410
#endif
 
411
        if (params->bssid != NULL)
 
412
                memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
340
413
        if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)
341
 
                ret = -1;
342
 
 
343
 
        return ret;
 
414
                return -1;
 
415
        return 0;
 
416
}
 
417
 
 
418
static int
 
419
wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg)
 
420
{
 
421
        struct wpa_driver_bsd_data *drv = priv;
 
422
        int authmode;
 
423
 
 
424
        if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) &&
 
425
            (auth_alg & AUTH_ALG_SHARED_KEY))
 
426
                authmode = IEEE80211_AUTH_AUTO;
 
427
        else if (auth_alg & AUTH_ALG_SHARED_KEY)
 
428
                authmode = IEEE80211_AUTH_SHARED;
 
429
        else
 
430
                authmode = IEEE80211_AUTH_OPEN;
 
431
 
 
432
        return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode);
344
433
}
345
434
 
346
435
static int
367
456
static void
368
457
wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
369
458
{
 
459
        struct wpa_driver_bsd_data *drv = sock_ctx;
370
460
        char buf[2048];
371
461
        struct if_announcemsghdr *ifan;
 
462
        struct if_msghdr *ifm;
372
463
        struct rt_msghdr *rtm;
373
464
        union wpa_event_data event;
374
465
        struct ieee80211_michael_event *mic;
387
478
                        "understood\n", rtm->rtm_version);
388
479
                return;
389
480
        }
390
 
        ifan = (struct if_announcemsghdr *) rtm;
 
481
        memset(&event, 0, sizeof(event));
391
482
        switch (rtm->rtm_type) {
392
483
        case RTM_IFANNOUNCE:
393
 
                memset(&event, 0, sizeof(event));
394
 
                /* XXX name buffer must be >= IFNAMSIZ */
395
 
                /* XXX check return value */
396
 
                if_indextoname(ifan->ifan_index, event.interface_status.ifname);
 
484
                ifan = (struct if_announcemsghdr *) rtm;
 
485
                if (ifan->ifan_index != drv->ifindex)
 
486
                        break;
 
487
                strlcpy(event.interface_status.ifname, drv->ifname,
 
488
                        sizeof(event.interface_status.ifname));
397
489
                switch (ifan->ifan_what) {
398
 
                case IFAN_ARRIVAL:
399
 
                        event.interface_status.ievent = EVENT_INTERFACE_ADDED;
400
 
                        break;
401
490
                case IFAN_DEPARTURE:
402
491
                        event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
403
492
                default:
410
499
                wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
411
500
                break;
412
501
        case RTM_IEEE80211:
 
502
                ifan = (struct if_announcemsghdr *) rtm;
 
503
                if (ifan->ifan_index != drv->ifindex)
 
504
                        break;
413
505
                switch (ifan->ifan_what) {
414
506
                case RTM_IEEE80211_ASSOC:
 
507
                case RTM_IEEE80211_REASSOC:
415
508
                        wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
416
509
                        break;
417
510
                case RTM_IEEE80211_DISASSOC:
420
513
                case RTM_IEEE80211_SCAN:
421
514
                        wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
422
515
                        break;
423
 
                case RTM_IEEE80211_REASSOC:
424
516
                case RTM_IEEE80211_REPLAY:
425
517
                        /* ignore */
426
518
                        break;
439
531
                        break;
440
532
                }
441
533
                break;
 
534
        case RTM_IFINFO:
 
535
                ifm = (struct if_msghdr *) rtm;
 
536
                if (ifm->ifm_index != drv->ifindex)
 
537
                        break;
 
538
                if ((rtm->rtm_flags & RTF_UP) == 0) {
 
539
                        strlcpy(event.interface_status.ifname, drv->ifname,
 
540
                                sizeof(event.interface_status.ifname));
 
541
                        event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
 
542
                        wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
 
543
                                   event.interface_status.ifname);
 
544
                        wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
 
545
                }
 
546
                break;
442
547
        }
443
548
}
444
549
 
574
679
static void *
575
680
wpa_driver_bsd_init(void *ctx, const char *ifname)
576
681
{
 
682
#define GETPARAM(drv, param, v) \
 
683
        (((v) = get80211param(drv, param)) != -1)
577
684
        struct wpa_driver_bsd_data *drv;
578
685
 
579
 
        drv = malloc(sizeof(*drv));
 
686
        drv = wpa_zalloc(sizeof(*drv));
580
687
        if (drv == NULL)
581
688
                return NULL;
582
 
        memset(drv, 0, sizeof(*drv));
 
689
        /*
 
690
         * NB: We require the interface name be mappable to an index.
 
691
         *     This implies we do not support having wpa_supplicant
 
692
         *     wait for an interface to appear.  This seems ok; that
 
693
         *     doesn't belong here; it's really the job of devd.
 
694
         */
 
695
        drv->ifindex = if_nametoindex(ifname);
 
696
        if (drv->ifindex == 0) {
 
697
                wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
 
698
                           __func__, ifname);
 
699
                goto fail1;
 
700
        }
583
701
        drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
584
 
        if (drv->sock < 0) {
585
 
                free(drv);
586
 
                return NULL;
587
 
        }
 
702
        if (drv->sock < 0)
 
703
                goto fail1;
588
704
        drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
589
 
        if (drv->route < 0) {
590
 
                close(drv->sock);
591
 
                free(drv);
592
 
                return NULL;
593
 
        }
 
705
        if (drv->route < 0)
 
706
                goto fail;
594
707
        eloop_register_read_sock(drv->route,
595
 
                wpa_driver_bsd_event_receive, ctx, NULL);
 
708
                wpa_driver_bsd_event_receive, ctx, drv);
596
709
 
597
710
        drv->ctx = ctx;
598
711
        strncpy(drv->ifname, ifname, sizeof(drv->ifname));
599
712
 
 
713
        if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
 
714
                wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
 
715
                        __func__, strerror(errno));
 
716
                goto fail;
 
717
        }
 
718
        if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) {
 
719
                wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s",
 
720
                        __func__, strerror(errno));
 
721
                goto fail;
 
722
        }
 
723
        if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) {
 
724
                wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s",
 
725
                        __func__, strerror(errno));
 
726
                goto fail;
 
727
        }
 
728
        if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) {
 
729
                wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "
 
730
                           "roaming: %s", __func__, strerror(errno));
 
731
                goto fail;
 
732
        }
 
733
 
 
734
        if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) {
 
735
                wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s",
 
736
                           __func__, strerror(errno));
 
737
                goto fail;
 
738
        }
 
739
 
600
740
        return drv;
 
741
fail:
 
742
        close(drv->sock);
 
743
fail1:
 
744
        free(drv);
 
745
        return NULL;
 
746
#undef GETPARAM
601
747
}
602
748
 
603
749
static void
610
756
        if (getifflags(drv, &flags) == 0)
611
757
                (void) setifflags(drv, flags &~ IFF_UP);
612
758
 
 
759
        wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
 
760
        if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
 
761
                wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
 
762
                        __func__);
 
763
 
613
764
        (void) close(drv->route);               /* ioctl socket */
614
765
        (void) close(drv->sock);                /* event socket */
615
766
        free(drv);
616
767
}
617
768
 
618
769
 
619
 
struct wpa_driver_ops wpa_driver_bsd_ops = {
 
770
const struct wpa_driver_ops wpa_driver_bsd_ops = {
620
771
        .name                   = "bsd",
621
772
        .desc                   = "BSD 802.11 support (Atheros, etc.)",
622
773
        .init                   = wpa_driver_bsd_init,
632
783
        .deauthenticate         = wpa_driver_bsd_deauthenticate,
633
784
        .disassociate           = wpa_driver_bsd_disassociate,
634
785
        .associate              = wpa_driver_bsd_associate,
 
786
        .set_auth_alg           = wpa_driver_bsd_set_auth_alg,
635
787
};