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

« back to all changes in this revision

Viewing changes to src/drivers/driver_atmel.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 - Driver interaction with Atmel Wireless LAN drivers
3
 
 * Copyright (c) 2000-2005, ATMEL Corporation
4
 
 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License version 2 as
8
 
 * published by the Free Software Foundation.
9
 
 *
10
 
 * Alternatively, this software may be distributed under the terms of BSD
11
 
 * license.
12
 
 *
13
 
 * See README and COPYING for more details.
14
 
 */
15
 
 
16
 
/******************************************************************************
17
 
        Copyright 2000-2001 ATMEL Corporation.
18
 
        
19
 
    WPA Supplicant - driver interaction with Atmel Wireless lan drivers.
20
 
    
21
 
    This is free software; you can redistribute it and/or modify
22
 
    it under the terms of the GNU General Public License as published by
23
 
    the Free Software Foundation; either version 2 of the License, or
24
 
    (at your option) any later version.
25
 
 
26
 
    This program is distributed in the hope that it will be useful,
27
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
28
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
 
    GNU General Public License for more details.
30
 
 
31
 
    You should have received a copy of the GNU General Public License
32
 
    along with Atmel wireless lan drivers; if not, write to the Free Software
33
 
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
34
 
 
35
 
******************************************************************************/
36
 
 
37
 
/*
38
 
 * Alternatively, this software may be distributed under the terms of BSD
39
 
 * license.
40
 
 */
41
 
 
42
 
#include "includes.h"
43
 
#include <sys/ioctl.h>
44
 
 
45
 
#include "wireless_copy.h"
46
 
#include "common.h"
47
 
#include "driver.h"
48
 
#include "driver_wext.h"
49
 
 
50
 
struct wpa_driver_atmel_data {
51
 
        void *wext; /* private data for driver_wext */
52
 
        void *ctx;
53
 
        char ifname[IFNAMSIZ + 1];
54
 
        int sock;
55
 
};
56
 
 
57
 
 
58
 
#define ATMEL_WPA_IOCTL                (SIOCIWFIRSTPRIV + 2)
59
 
#define ATMEL_WPA_IOCTL_PARAM          (SIOCIWFIRSTPRIV + 3)
60
 
#define ATMEL_WPA_IOCTL_GET_PARAM      (SIOCIWFIRSTPRIV + 4)
61
 
 
62
 
 
63
 
/* ATMEL_WPA_IOCTL ioctl() cmd: */
64
 
enum {
65
 
    SET_WPA_ENCRYPTION  = 1,
66
 
    SET_CIPHER_SUITES   = 2,
67
 
    MLME_STA_DEAUTH     = 3,
68
 
    MLME_STA_DISASSOC   = 4
69
 
};
70
 
 
71
 
/* ATMEL_WPA_IOCTL_PARAM ioctl() cmd: */
72
 
enum {
73
 
            ATMEL_PARAM_WPA = 1,
74
 
            ATMEL_PARAM_PRIVACY_INVOKED = 2,
75
 
            ATMEL_PARAM_WPA_TYPE = 3
76
 
};
77
 
 
78
 
#define MAX_KEY_LENGTH      40
79
 
 
80
 
struct atmel_param{
81
 
    unsigned char sta_addr[6];
82
 
        int     cmd;
83
 
        u8      alg;
84
 
        u8      key_idx;
85
 
        u8      set_tx;
86
 
        u8      seq[8];
87
 
        u8      seq_len;
88
 
        u16     key_len;
89
 
        u8      key[MAX_KEY_LENGTH];
90
 
    struct{
91
 
        int     reason_code;
92
 
        u8      state;
93
 
    }mlme;
94
 
    u8          pairwise_suite;
95
 
    u8          group_suite;
96
 
    u8          key_mgmt_suite;
97
 
};
98
 
 
99
 
    
100
 
    
101
 
static int atmel_ioctl(struct wpa_driver_atmel_data *drv,
102
 
                       struct atmel_param *param,
103
 
                       int len, int show_err)
104
 
{
105
 
        struct iwreq iwr;
106
 
 
107
 
        os_memset(&iwr, 0, sizeof(iwr));
108
 
        os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
109
 
        iwr.u.data.pointer = (caddr_t) param;
110
 
        iwr.u.data.length = len;
111
 
 
112
 
        if (ioctl(drv->sock, ATMEL_WPA_IOCTL, &iwr) < 0) {
113
 
                int ret;
114
 
                ret = errno;
115
 
                if (show_err) 
116
 
                        perror("ioctl[ATMEL_WPA_IOCTL]");
117
 
                return ret;
118
 
        }
119
 
 
120
 
        return 0;
121
 
}
122
 
 
123
 
 
124
 
static int atmel2param(struct wpa_driver_atmel_data *drv, int param, int value)
125
 
{
126
 
        struct iwreq iwr;
127
 
        int *i, ret = 0;
128
 
 
129
 
        os_memset(&iwr, 0, sizeof(iwr));
130
 
        os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
131
 
        i = (int *) iwr.u.name;
132
 
        *i++ = param;
133
 
        *i++ = value;
134
 
 
135
 
        if (ioctl(drv->sock, ATMEL_WPA_IOCTL_PARAM, &iwr) < 0) {
136
 
                perror("ioctl[ATMEL_WPA_IOCTL_PARAM]");
137
 
                ret = -1;
138
 
        }
139
 
        return ret;
140
 
}
141
 
 
142
 
 
143
 
#if 0
144
 
static int wpa_driver_atmel_set_wpa_ie(struct wpa_driver_atmel_data *drv,
145
 
                                       const char *wpa_ie, size_t wpa_ie_len)
146
 
{
147
 
        struct atmel_param *param;
148
 
        int res;
149
 
        size_t blen = ATMEL_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len;
150
 
        if (blen < sizeof(*param))
151
 
                blen = sizeof(*param);
152
 
 
153
 
        param = os_zalloc(blen);
154
 
        if (param == NULL)
155
 
                return -1;
156
 
 
157
 
        param->cmd = ATMEL_SET_GENERIC_ELEMENT;
158
 
        param->u.generic_elem.len = wpa_ie_len;
159
 
        os_memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len);
160
 
        res = atmel_ioctl(drv, param, blen, 1);
161
 
 
162
 
        os_free(param);
163
 
 
164
 
        return res;
165
 
}
166
 
#endif
167
 
 
168
 
 
169
 
static int wpa_driver_atmel_set_wpa(void *priv, int enabled)
170
 
{
171
 
        struct wpa_driver_atmel_data *drv = priv;
172
 
        int ret = 0;
173
 
        
174
 
        printf("wpa_driver_atmel_set_wpa %s\n", drv->ifname);
175
 
 
176
 
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
177
 
 
178
 
#if 0
179
 
        if (!enabled && wpa_driver_atmel_set_wpa_ie(drv, NULL, 0) < 0)
180
 
                ret = -1;
181
 
#endif
182
 
        if (atmel2param(drv, ATMEL_PARAM_PRIVACY_INVOKED, enabled) < 0)
183
 
                ret = -1;
184
 
        if (atmel2param(drv, ATMEL_PARAM_WPA, enabled) < 0)
185
 
                ret = -1;
186
 
 
187
 
        return ret;
188
 
}
189
 
 
190
 
 
191
 
static int wpa_driver_atmel_set_key(void *priv, wpa_alg alg,
192
 
                                    const u8 *addr, int key_idx,
193
 
                                    int set_tx, const u8 *seq, size_t seq_len,
194
 
                                    const u8 *key, size_t key_len)
195
 
{
196
 
        struct wpa_driver_atmel_data *drv = priv;
197
 
        int ret = 0;
198
 
        struct atmel_param *param;
199
 
        u8 *buf;
200
 
        u8 alg_type;
201
 
        
202
 
        size_t blen;
203
 
        char *alg_name;
204
 
 
205
 
        switch (alg) {
206
 
        case WPA_ALG_NONE:
207
 
                alg_name = "none";
208
 
                alg_type = 0;
209
 
                break;
210
 
        case WPA_ALG_WEP:
211
 
                alg_name = "WEP";
212
 
                alg_type = 1;
213
 
                break;
214
 
        case WPA_ALG_TKIP:
215
 
                alg_name = "TKIP";
216
 
                alg_type = 2;
217
 
                break;
218
 
        case WPA_ALG_CCMP:
219
 
                alg_name = "CCMP";
220
 
                alg_type = 3;
221
 
                break;
222
 
        default:
223
 
                return -1;
224
 
        }
225
 
 
226
 
        wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
227
 
                   "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
228
 
                   (unsigned long) seq_len, (unsigned long) key_len);
229
 
 
230
 
        if (seq_len > 8)
231
 
                return -2;
232
 
 
233
 
        blen = sizeof(*param) + key_len;
234
 
        buf = os_zalloc(blen);
235
 
        if (buf == NULL)
236
 
                return -1;
237
 
 
238
 
        param = (struct atmel_param *) buf;
239
 
        
240
 
        param->cmd = SET_WPA_ENCRYPTION; 
241
 
        
242
 
        if (addr == NULL)
243
 
                os_memset(param->sta_addr, 0xff, ETH_ALEN);
244
 
        else
245
 
                os_memcpy(param->sta_addr, addr, ETH_ALEN);
246
 
        
247
 
        param->alg = alg_type;
248
 
        param->key_idx = key_idx;
249
 
        param->set_tx = set_tx;
250
 
        os_memcpy(param->seq, seq, seq_len);
251
 
        param->seq_len = seq_len;
252
 
        param->key_len = key_len;
253
 
        os_memcpy((u8 *)param->key, key, key_len);
254
 
        
255
 
        if (atmel_ioctl(drv, param, blen, 1)) {
256
 
                wpa_printf(MSG_WARNING, "Failed to set encryption.");
257
 
                /* TODO: show key error*/
258
 
                ret = -1;
259
 
        }
260
 
        os_free(buf);
261
 
 
262
 
        return ret;
263
 
}
264
 
 
265
 
 
266
 
static int wpa_driver_atmel_set_countermeasures(void *priv,
267
 
                                                 int enabled)
268
 
{
269
 
        /* FIX */
270
 
        printf("wpa_driver_atmel_set_countermeasures - not yet "
271
 
               "implemented\n");
272
 
        return 0;
273
 
}
274
 
 
275
 
 
276
 
static int wpa_driver_atmel_set_drop_unencrypted(void *priv,
277
 
                                                  int enabled)
278
 
{
279
 
        /* FIX */
280
 
        printf("wpa_driver_atmel_set_drop_unencrypted - not yet "
281
 
               "implemented\n");
282
 
        return 0;
283
 
}
284
 
 
285
 
 
286
 
static int wpa_driver_atmel_mlme(void *priv, const u8 *addr, int cmd,
287
 
                                 int reason_code)
288
 
{
289
 
        struct wpa_driver_atmel_data *drv = priv;
290
 
        struct atmel_param param;
291
 
        int ret;
292
 
        int mgmt_error = 0xaa;
293
 
        
294
 
        os_memset(&param, 0, sizeof(param));
295
 
        os_memcpy(param.sta_addr, addr, ETH_ALEN);
296
 
        param.cmd = cmd;
297
 
        param.mlme.reason_code = reason_code;
298
 
        param.mlme.state = mgmt_error;
299
 
        ret = atmel_ioctl(drv, &param, sizeof(param), 1);
300
 
        return ret;
301
 
}
302
 
 
303
 
 
304
 
#if 0
305
 
static int wpa_driver_atmel_set_suites(struct wpa_driver_atmel_data *drv,
306
 
                                       u8 pairwise_suite, u8 group_suite,
307
 
                                       u8 key_mgmt_suite)
308
 
{
309
 
        struct atmel_param param;
310
 
        int ret;
311
 
        
312
 
        os_memset(&param, 0, sizeof(param));
313
 
        param.cmd = SET_CIPHER_SUITES;
314
 
        param.pairwise_suite = pairwise_suite;
315
 
        param.group_suite = group_suite;
316
 
        param.key_mgmt_suite = key_mgmt_suite;
317
 
                
318
 
        ret = atmel_ioctl(drv, &param, sizeof(param), 1);
319
 
        return ret;
320
 
}
321
 
#endif
322
 
 
323
 
 
324
 
static int wpa_driver_atmel_deauthenticate(void *priv, const u8 *addr,
325
 
                                           int reason_code)
326
 
{
327
 
        struct wpa_driver_atmel_data *drv = priv;
328
 
        printf("wpa_driver_atmel_deauthenticate\n");
329
 
        wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
330
 
        return wpa_driver_atmel_mlme(drv, addr, MLME_STA_DEAUTH,
331
 
                                     reason_code);
332
 
 
333
 
}
334
 
 
335
 
 
336
 
static int wpa_driver_atmel_disassociate(void *priv, const u8 *addr,
337
 
                                         int reason_code)
338
 
{
339
 
        struct wpa_driver_atmel_data *drv = priv;
340
 
        printf("wpa_driver_atmel_disassociate\n");
341
 
        wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
342
 
        return wpa_driver_atmel_mlme(drv, addr, MLME_STA_DISASSOC,
343
 
                                     reason_code);
344
 
 
345
 
}
346
 
 
347
 
 
348
 
#if 0
349
 
/* Atmel driver uses specific values for each cipher suite */
350
 
static int convertSuiteToDriver(wpa_cipher suite)
351
 
{
352
 
    u8 suite_type;
353
 
    
354
 
    switch(suite) {
355
 
        case CIPHER_NONE:
356
 
                suite_type =  0;
357
 
                break;
358
 
        case CIPHER_WEP40:
359
 
                suite_type =  1;
360
 
                break;
361
 
        case CIPHER_TKIP:
362
 
                suite_type = 2;
363
 
                break;
364
 
        case CIPHER_WEP104:
365
 
                suite_type = 5;
366
 
                break;
367
 
        case CIPHER_CCMP:
368
 
                suite_type = 3;
369
 
                break;
370
 
        default:
371
 
                suite_type = 2;
372
 
    }
373
 
    
374
 
    return suite_type;
375
 
 
376
 
}
377
 
#endif
378
 
    
379
 
static int
380
 
wpa_driver_atmel_associate(void *priv,
381
 
                           struct wpa_driver_associate_params *params)
382
 
{
383
 
        struct wpa_driver_atmel_data *drv = priv;
384
 
        int ret = 0;
385
 
#if 0
386
 
        u8 pairwise_suite_driver;
387
 
        u8 group_suite_driver;
388
 
        u8 key_mgmt_suite_driver;
389
 
 
390
 
        pairwise_suite_driver = convertSuiteToDriver(params->pairwise_suite);
391
 
        group_suite_driver    = convertSuiteToDriver(params->group_suite);
392
 
        key_mgmt_suite_driver = convertSuiteToDriver(params->key_mgmt_suite);
393
 
 
394
 
        if (wpa_driver_atmel_set_suites(drv, pairwise_suite_driver,
395
 
                                        group_suite_driver,
396
 
                                        key_mgmt_suite_driver) < 0){
397
 
                printf("wpa_driver_atmel_set_suites.\n");
398
 
                ret = -1;
399
 
        }
400
 
        if (wpa_driver_wext_set_freq(drv->wext, params->freq) < 0) {
401
 
                printf("wpa_driver_atmel_set_freq.\n");
402
 
                ret = -1;
403
 
        }
404
 
#endif
405
 
        if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len)
406
 
            < 0) {
407
 
                printf("FAILED : wpa_driver_atmel_set_ssid.\n");
408
 
                ret = -1;
409
 
        }
410
 
        if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0) {
411
 
                printf("FAILED : wpa_driver_atmel_set_bssid.\n");
412
 
                ret = -1;
413
 
        }
414
 
 
415
 
        return ret;
416
 
}
417
 
 
418
 
 
419
 
static int wpa_driver_atmel_get_bssid(void *priv, u8 *bssid)
420
 
{
421
 
        struct wpa_driver_atmel_data *drv = priv;
422
 
        return wpa_driver_wext_get_bssid(drv->wext, bssid);
423
 
}
424
 
 
425
 
 
426
 
static int wpa_driver_atmel_get_ssid(void *priv, u8 *ssid)
427
 
{
428
 
        struct wpa_driver_atmel_data *drv = priv;
429
 
        return wpa_driver_wext_get_ssid(drv->wext, ssid);
430
 
}
431
 
 
432
 
 
433
 
static int wpa_driver_atmel_scan(void *priv, const u8 *ssid, size_t ssid_len)
434
 
{
435
 
        struct wpa_driver_atmel_data *drv = priv;
436
 
        return wpa_driver_wext_scan(drv->wext, ssid, ssid_len);
437
 
}
438
 
 
439
 
 
440
 
static int wpa_driver_atmel_get_scan_results(void *priv,
441
 
                                            struct wpa_scan_result *results,
442
 
                                            size_t max_size)
443
 
{
444
 
        struct wpa_driver_atmel_data *drv = priv;
445
 
        return wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
446
 
}
447
 
 
448
 
 
449
 
static int wpa_driver_atmel_set_operstate(void *priv, int state)
450
 
{
451
 
        struct wpa_driver_atmel_data *drv = priv;
452
 
        return wpa_driver_wext_set_operstate(drv->wext, state);
453
 
}
454
 
 
455
 
 
456
 
static void * wpa_driver_atmel_init(void *ctx, const char *ifname)
457
 
{
458
 
        struct wpa_driver_atmel_data *drv;
459
 
 
460
 
        drv = os_zalloc(sizeof(*drv));
461
 
        if (drv == NULL)
462
 
                return NULL;
463
 
        drv->wext = wpa_driver_wext_init(ctx, ifname);
464
 
        if (drv->wext == NULL) {
465
 
                os_free(drv);
466
 
                return NULL;
467
 
        }
468
 
 
469
 
        drv->ctx = ctx;
470
 
        os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
471
 
        drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
472
 
        if (drv->sock < 0) {
473
 
                wpa_driver_wext_deinit(drv->wext);
474
 
                os_free(drv);
475
 
                return NULL;
476
 
        }
477
 
 
478
 
        return drv;
479
 
}
480
 
 
481
 
 
482
 
static void wpa_driver_atmel_deinit(void *priv)
483
 
{
484
 
        struct wpa_driver_atmel_data *drv = priv;
485
 
        wpa_driver_wext_deinit(drv->wext);
486
 
        close(drv->sock);
487
 
        os_free(drv);
488
 
}
489
 
 
490
 
 
491
 
const struct wpa_driver_ops wpa_driver_atmel_ops = {
492
 
        .name = "atmel",
493
 
        .desc = "ATMEL AT76C5XXx (USB, PCMCIA)",
494
 
        .get_bssid = wpa_driver_atmel_get_bssid,
495
 
        .get_ssid = wpa_driver_atmel_get_ssid,
496
 
        .set_wpa = wpa_driver_atmel_set_wpa,
497
 
        .set_key = wpa_driver_atmel_set_key,
498
 
        .init = wpa_driver_atmel_init,
499
 
        .deinit = wpa_driver_atmel_deinit,
500
 
        .set_countermeasures = wpa_driver_atmel_set_countermeasures,
501
 
        .set_drop_unencrypted = wpa_driver_atmel_set_drop_unencrypted,
502
 
        .scan = wpa_driver_atmel_scan,
503
 
        .get_scan_results = wpa_driver_atmel_get_scan_results,
504
 
        .deauthenticate = wpa_driver_atmel_deauthenticate,
505
 
        .disassociate = wpa_driver_atmel_disassociate,
506
 
        .associate = wpa_driver_atmel_associate,
507
 
        .set_operstate = wpa_driver_atmel_set_operstate,
508
 
};