automake build system
[mech_eap.orig] / src / drivers / driver_wext.c
1 /*
2  * Driver interaction with generic Linux Wireless Extensions
3  * Copyright (c) 2003-2010, 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  * This file implements a driver interface for the Linux Wireless Extensions.
15  * When used with WE-18 or newer, this interface can be used as-is with number
16  * of drivers. In addition to this, some of the common functions in this file
17  * can be used by other driver interface implementations that use generic WE
18  * ioctls, but require private ioctls for some of the functionality.
19  */
20
21 #include "includes.h"
22 #include <sys/ioctl.h>
23 #include <sys/stat.h>
24 #include <net/if_arp.h>
25
26 #include "wireless_copy.h"
27 #include "common.h"
28 #include "eloop.h"
29 #include "common/ieee802_11_defs.h"
30 #include "common/wpa_common.h"
31 #include "priv_netlink.h"
32 #include "netlink.h"
33 #include "linux_ioctl.h"
34 #include "rfkill.h"
35 #include "driver.h"
36 #include "driver_wext.h"
37
38
39 static int wpa_driver_wext_flush_pmkid(void *priv);
40 static int wpa_driver_wext_get_range(void *priv);
41 static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
42 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv);
43 static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg);
44
45
46 int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv,
47                                    int idx, u32 value)
48 {
49         struct iwreq iwr;
50         int ret = 0;
51
52         os_memset(&iwr, 0, sizeof(iwr));
53         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
54         iwr.u.param.flags = idx & IW_AUTH_INDEX;
55         iwr.u.param.value = value;
56
57         if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) {
58                 if (errno != EOPNOTSUPP) {
59                         wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d "
60                                    "value 0x%x) failed: %s)",
61                                    idx, value, strerror(errno));
62                 }
63                 ret = errno == EOPNOTSUPP ? -2 : -1;
64         }
65
66         return ret;
67 }
68
69
70 /**
71  * wpa_driver_wext_get_bssid - Get BSSID, SIOCGIWAP
72  * @priv: Pointer to private wext data from wpa_driver_wext_init()
73  * @bssid: Buffer for BSSID
74  * Returns: 0 on success, -1 on failure
75  */
76 int wpa_driver_wext_get_bssid(void *priv, u8 *bssid)
77 {
78         struct wpa_driver_wext_data *drv = priv;
79         struct iwreq iwr;
80         int ret = 0;
81
82         os_memset(&iwr, 0, sizeof(iwr));
83         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
84
85         if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) {
86                 perror("ioctl[SIOCGIWAP]");
87                 ret = -1;
88         }
89         os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN);
90
91         return ret;
92 }
93
94
95 /**
96  * wpa_driver_wext_set_bssid - Set BSSID, SIOCSIWAP
97  * @priv: Pointer to private wext data from wpa_driver_wext_init()
98  * @bssid: BSSID
99  * Returns: 0 on success, -1 on failure
100  */
101 int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid)
102 {
103         struct wpa_driver_wext_data *drv = priv;
104         struct iwreq iwr;
105         int ret = 0;
106
107         os_memset(&iwr, 0, sizeof(iwr));
108         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
109         iwr.u.ap_addr.sa_family = ARPHRD_ETHER;
110         if (bssid)
111                 os_memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN);
112         else
113                 os_memset(iwr.u.ap_addr.sa_data, 0, ETH_ALEN);
114
115         if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr) < 0) {
116                 perror("ioctl[SIOCSIWAP]");
117                 ret = -1;
118         }
119
120         return ret;
121 }
122
123
124 /**
125  * wpa_driver_wext_get_ssid - Get SSID, SIOCGIWESSID
126  * @priv: Pointer to private wext data from wpa_driver_wext_init()
127  * @ssid: Buffer for the SSID; must be at least 32 bytes long
128  * Returns: SSID length on success, -1 on failure
129  */
130 int wpa_driver_wext_get_ssid(void *priv, u8 *ssid)
131 {
132         struct wpa_driver_wext_data *drv = priv;
133         struct iwreq iwr;
134         int ret = 0;
135
136         os_memset(&iwr, 0, sizeof(iwr));
137         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
138         iwr.u.essid.pointer = (caddr_t) ssid;
139         iwr.u.essid.length = 32;
140
141         if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
142                 perror("ioctl[SIOCGIWESSID]");
143                 ret = -1;
144         } else {
145                 ret = iwr.u.essid.length;
146                 if (ret > 32)
147                         ret = 32;
148                 /* Some drivers include nul termination in the SSID, so let's
149                  * remove it here before further processing. WE-21 changes this
150                  * to explicitly require the length _not_ to include nul
151                  * termination. */
152                 if (ret > 0 && ssid[ret - 1] == '\0' &&
153                     drv->we_version_compiled < 21)
154                         ret--;
155         }
156
157         return ret;
158 }
159
160
161 /**
162  * wpa_driver_wext_set_ssid - Set SSID, SIOCSIWESSID
163  * @priv: Pointer to private wext data from wpa_driver_wext_init()
164  * @ssid: SSID
165  * @ssid_len: Length of SSID (0..32)
166  * Returns: 0 on success, -1 on failure
167  */
168 int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len)
169 {
170         struct wpa_driver_wext_data *drv = priv;
171         struct iwreq iwr;
172         int ret = 0;
173         char buf[33];
174
175         if (ssid_len > 32)
176                 return -1;
177
178         os_memset(&iwr, 0, sizeof(iwr));
179         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
180         /* flags: 1 = ESSID is active, 0 = not (promiscuous) */
181         iwr.u.essid.flags = (ssid_len != 0);
182         os_memset(buf, 0, sizeof(buf));
183         os_memcpy(buf, ssid, ssid_len);
184         iwr.u.essid.pointer = (caddr_t) buf;
185         if (drv->we_version_compiled < 21) {
186                 /* For historic reasons, set SSID length to include one extra
187                  * character, C string nul termination, even though SSID is
188                  * really an octet string that should not be presented as a C
189                  * string. Some Linux drivers decrement the length by one and
190                  * can thus end up missing the last octet of the SSID if the
191                  * length is not incremented here. WE-21 changes this to
192                  * explicitly require the length _not_ to include nul
193                  * termination. */
194                 if (ssid_len)
195                         ssid_len++;
196         }
197         iwr.u.essid.length = ssid_len;
198
199         if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
200                 perror("ioctl[SIOCSIWESSID]");
201                 ret = -1;
202         }
203
204         return ret;
205 }
206
207
208 /**
209  * wpa_driver_wext_set_freq - Set frequency/channel, SIOCSIWFREQ
210  * @priv: Pointer to private wext data from wpa_driver_wext_init()
211  * @freq: Frequency in MHz
212  * Returns: 0 on success, -1 on failure
213  */
214 int wpa_driver_wext_set_freq(void *priv, int freq)
215 {
216         struct wpa_driver_wext_data *drv = priv;
217         struct iwreq iwr;
218         int ret = 0;
219
220         os_memset(&iwr, 0, sizeof(iwr));
221         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
222         iwr.u.freq.m = freq * 100000;
223         iwr.u.freq.e = 1;
224
225         if (ioctl(drv->ioctl_sock, SIOCSIWFREQ, &iwr) < 0) {
226                 perror("ioctl[SIOCSIWFREQ]");
227                 ret = -1;
228         }
229
230         return ret;
231 }
232
233
234 static void
235 wpa_driver_wext_event_wireless_custom(void *ctx, char *custom)
236 {
237         union wpa_event_data data;
238
239         wpa_printf(MSG_MSGDUMP, "WEXT: Custom wireless event: '%s'",
240                    custom);
241
242         os_memset(&data, 0, sizeof(data));
243         /* Host AP driver */
244         if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
245                 data.michael_mic_failure.unicast =
246                         os_strstr(custom, " unicast ") != NULL;
247                 /* TODO: parse parameters(?) */
248                 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
249         } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) {
250                 char *spos;
251                 int bytes;
252                 u8 *req_ies = NULL, *resp_ies = NULL;
253
254                 spos = custom + 17;
255
256                 bytes = strspn(spos, "0123456789abcdefABCDEF");
257                 if (!bytes || (bytes & 1))
258                         return;
259                 bytes /= 2;
260
261                 req_ies = os_malloc(bytes);
262                 if (req_ies == NULL ||
263                     hexstr2bin(spos, req_ies, bytes) < 0)
264                         goto done;
265                 data.assoc_info.req_ies = req_ies;
266                 data.assoc_info.req_ies_len = bytes;
267
268                 spos += bytes * 2;
269
270                 data.assoc_info.resp_ies = NULL;
271                 data.assoc_info.resp_ies_len = 0;
272
273                 if (os_strncmp(spos, " RespIEs=", 9) == 0) {
274                         spos += 9;
275
276                         bytes = strspn(spos, "0123456789abcdefABCDEF");
277                         if (!bytes || (bytes & 1))
278                                 goto done;
279                         bytes /= 2;
280
281                         resp_ies = os_malloc(bytes);
282                         if (resp_ies == NULL ||
283                             hexstr2bin(spos, resp_ies, bytes) < 0)
284                                 goto done;
285                         data.assoc_info.resp_ies = resp_ies;
286                         data.assoc_info.resp_ies_len = bytes;
287                 }
288
289                 wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data);
290
291         done:
292                 os_free(resp_ies);
293                 os_free(req_ies);
294 #ifdef CONFIG_PEERKEY
295         } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) {
296                 if (hwaddr_aton(custom + 17, data.stkstart.peer)) {
297                         wpa_printf(MSG_DEBUG, "WEXT: unrecognized "
298                                    "STKSTART.request '%s'", custom + 17);
299                         return;
300                 }
301                 wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
302 #endif /* CONFIG_PEERKEY */
303         }
304 }
305
306
307 static int wpa_driver_wext_event_wireless_michaelmicfailure(
308         void *ctx, const char *ev, size_t len)
309 {
310         const struct iw_michaelmicfailure *mic;
311         union wpa_event_data data;
312
313         if (len < sizeof(*mic))
314                 return -1;
315
316         mic = (const struct iw_michaelmicfailure *) ev;
317
318         wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: "
319                    "flags=0x%x src_addr=" MACSTR, mic->flags,
320                    MAC2STR(mic->src_addr.sa_data));
321
322         os_memset(&data, 0, sizeof(data));
323         data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP);
324         wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
325
326         return 0;
327 }
328
329
330 static int wpa_driver_wext_event_wireless_pmkidcand(
331         struct wpa_driver_wext_data *drv, const char *ev, size_t len)
332 {
333         const struct iw_pmkid_cand *cand;
334         union wpa_event_data data;
335         const u8 *addr;
336
337         if (len < sizeof(*cand))
338                 return -1;
339
340         cand = (const struct iw_pmkid_cand *) ev;
341         addr = (const u8 *) cand->bssid.sa_data;
342
343         wpa_printf(MSG_DEBUG, "PMKID candidate wireless event: "
344                    "flags=0x%x index=%d bssid=" MACSTR, cand->flags,
345                    cand->index, MAC2STR(addr));
346
347         os_memset(&data, 0, sizeof(data));
348         os_memcpy(data.pmkid_candidate.bssid, addr, ETH_ALEN);
349         data.pmkid_candidate.index = cand->index;
350         data.pmkid_candidate.preauth = cand->flags & IW_PMKID_CAND_PREAUTH;
351         wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
352
353         return 0;
354 }
355
356
357 static int wpa_driver_wext_event_wireless_assocreqie(
358         struct wpa_driver_wext_data *drv, const char *ev, int len)
359 {
360         if (len < 0)
361                 return -1;
362
363         wpa_hexdump(MSG_DEBUG, "AssocReq IE wireless event", (const u8 *) ev,
364                     len);
365         os_free(drv->assoc_req_ies);
366         drv->assoc_req_ies = os_malloc(len);
367         if (drv->assoc_req_ies == NULL) {
368                 drv->assoc_req_ies_len = 0;
369                 return -1;
370         }
371         os_memcpy(drv->assoc_req_ies, ev, len);
372         drv->assoc_req_ies_len = len;
373
374         return 0;
375 }
376
377
378 static int wpa_driver_wext_event_wireless_assocrespie(
379         struct wpa_driver_wext_data *drv, const char *ev, int len)
380 {
381         if (len < 0)
382                 return -1;
383
384         wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev,
385                     len);
386         os_free(drv->assoc_resp_ies);
387         drv->assoc_resp_ies = os_malloc(len);
388         if (drv->assoc_resp_ies == NULL) {
389                 drv->assoc_resp_ies_len = 0;
390                 return -1;
391         }
392         os_memcpy(drv->assoc_resp_ies, ev, len);
393         drv->assoc_resp_ies_len = len;
394
395         return 0;
396 }
397
398
399 static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv)
400 {
401         union wpa_event_data data;
402
403         if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL)
404                 return;
405
406         os_memset(&data, 0, sizeof(data));
407         if (drv->assoc_req_ies) {
408                 data.assoc_info.req_ies = drv->assoc_req_ies;
409                 data.assoc_info.req_ies_len = drv->assoc_req_ies_len;
410         }
411         if (drv->assoc_resp_ies) {
412                 data.assoc_info.resp_ies = drv->assoc_resp_ies;
413                 data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len;
414         }
415
416         wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);
417
418         os_free(drv->assoc_req_ies);
419         drv->assoc_req_ies = NULL;
420         os_free(drv->assoc_resp_ies);
421         drv->assoc_resp_ies = NULL;
422 }
423
424
425 static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
426                                            char *data, int len)
427 {
428         struct iw_event iwe_buf, *iwe = &iwe_buf;
429         char *pos, *end, *custom, *buf;
430
431         pos = data;
432         end = data + len;
433
434         while (pos + IW_EV_LCP_LEN <= end) {
435                 /* Event data may be unaligned, so make a local, aligned copy
436                  * before processing. */
437                 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
438                 wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d",
439                            iwe->cmd, iwe->len);
440                 if (iwe->len <= IW_EV_LCP_LEN)
441                         return;
442
443                 custom = pos + IW_EV_POINT_LEN;
444                 if (drv->we_version_compiled > 18 &&
445                     (iwe->cmd == IWEVMICHAELMICFAILURE ||
446                      iwe->cmd == IWEVCUSTOM ||
447                      iwe->cmd == IWEVASSOCREQIE ||
448                      iwe->cmd == IWEVASSOCRESPIE ||
449                      iwe->cmd == IWEVPMKIDCAND)) {
450                         /* WE-19 removed the pointer from struct iw_point */
451                         char *dpos = (char *) &iwe_buf.u.data.length;
452                         int dlen = dpos - (char *) &iwe_buf;
453                         os_memcpy(dpos, pos + IW_EV_LCP_LEN,
454                                   sizeof(struct iw_event) - dlen);
455                 } else {
456                         os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
457                         custom += IW_EV_POINT_OFF;
458                 }
459
460                 switch (iwe->cmd) {
461                 case SIOCGIWAP:
462                         wpa_printf(MSG_DEBUG, "Wireless event: new AP: "
463                                    MACSTR,
464                                    MAC2STR((u8 *) iwe->u.ap_addr.sa_data));
465                         if (is_zero_ether_addr(
466                                     (const u8 *) iwe->u.ap_addr.sa_data) ||
467                             os_memcmp(iwe->u.ap_addr.sa_data,
468                                       "\x44\x44\x44\x44\x44\x44", ETH_ALEN) ==
469                             0) {
470                                 os_free(drv->assoc_req_ies);
471                                 drv->assoc_req_ies = NULL;
472                                 os_free(drv->assoc_resp_ies);
473                                 drv->assoc_resp_ies = NULL;
474                                 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC,
475                                                      NULL);
476                         
477                         } else {
478                                 wpa_driver_wext_event_assoc_ies(drv);
479                                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC,
480                                                      NULL);
481                         }
482                         break;
483                 case IWEVMICHAELMICFAILURE:
484                         if (custom + iwe->u.data.length > end) {
485                                 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
486                                            "IWEVMICHAELMICFAILURE length");
487                                 return;
488                         }
489                         wpa_driver_wext_event_wireless_michaelmicfailure(
490                                 drv->ctx, custom, iwe->u.data.length);
491                         break;
492                 case IWEVCUSTOM:
493                         if (custom + iwe->u.data.length > end) {
494                                 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
495                                            "IWEVCUSTOM length");
496                                 return;
497                         }
498                         buf = os_malloc(iwe->u.data.length + 1);
499                         if (buf == NULL)
500                                 return;
501                         os_memcpy(buf, custom, iwe->u.data.length);
502                         buf[iwe->u.data.length] = '\0';
503                         wpa_driver_wext_event_wireless_custom(drv->ctx, buf);
504                         os_free(buf);
505                         break;
506                 case SIOCGIWSCAN:
507                         drv->scan_complete_events = 1;
508                         eloop_cancel_timeout(wpa_driver_wext_scan_timeout,
509                                              drv, drv->ctx);
510                         wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS,
511                                              NULL);
512                         break;
513                 case IWEVASSOCREQIE:
514                         if (custom + iwe->u.data.length > end) {
515                                 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
516                                            "IWEVASSOCREQIE length");
517                                 return;
518                         }
519                         wpa_driver_wext_event_wireless_assocreqie(
520                                 drv, custom, iwe->u.data.length);
521                         break;
522                 case IWEVASSOCRESPIE:
523                         if (custom + iwe->u.data.length > end) {
524                                 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
525                                            "IWEVASSOCRESPIE length");
526                                 return;
527                         }
528                         wpa_driver_wext_event_wireless_assocrespie(
529                                 drv, custom, iwe->u.data.length);
530                         break;
531                 case IWEVPMKIDCAND:
532                         if (custom + iwe->u.data.length > end) {
533                                 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
534                                            "IWEVPMKIDCAND length");
535                                 return;
536                         }
537                         wpa_driver_wext_event_wireless_pmkidcand(
538                                 drv, custom, iwe->u.data.length);
539                         break;
540                 }
541
542                 pos += iwe->len;
543         }
544 }
545
546
547 static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv,
548                                        char *buf, size_t len, int del)
549 {
550         union wpa_event_data event;
551
552         os_memset(&event, 0, sizeof(event));
553         if (len > sizeof(event.interface_status.ifname))
554                 len = sizeof(event.interface_status.ifname) - 1;
555         os_memcpy(event.interface_status.ifname, buf, len);
556         event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
557                 EVENT_INTERFACE_ADDED;
558
559         wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
560                    del ? "DEL" : "NEW",
561                    event.interface_status.ifname,
562                    del ? "removed" : "added");
563
564         if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
565                 if (del)
566                         drv->if_removed = 1;
567                 else
568                         drv->if_removed = 0;
569         }
570
571         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
572 }
573
574
575 static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv,
576                                       u8 *buf, size_t len)
577 {
578         int attrlen, rta_len;
579         struct rtattr *attr;
580
581         attrlen = len;
582         attr = (struct rtattr *) buf;
583
584         rta_len = RTA_ALIGN(sizeof(struct rtattr));
585         while (RTA_OK(attr, attrlen)) {
586                 if (attr->rta_type == IFLA_IFNAME) {
587                         if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
588                             == 0)
589                                 return 1;
590                         else
591                                 break;
592                 }
593                 attr = RTA_NEXT(attr, attrlen);
594         }
595
596         return 0;
597 }
598
599
600 static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv,
601                                        int ifindex, u8 *buf, size_t len)
602 {
603         if (drv->ifindex == ifindex || drv->ifindex2 == ifindex)
604                 return 1;
605
606         if (drv->if_removed && wpa_driver_wext_own_ifname(drv, buf, len)) {
607                 drv->ifindex = if_nametoindex(drv->ifname);
608                 wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed "
609                            "interface");
610                 wpa_driver_wext_finish_drv_init(drv);
611                 return 1;
612         }
613
614         return 0;
615 }
616
617
618 static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
619                                               u8 *buf, size_t len)
620 {
621         struct wpa_driver_wext_data *drv = ctx;
622         int attrlen, rta_len;
623         struct rtattr *attr;
624
625         if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, buf, len)) {
626                 wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
627                            ifi->ifi_index);
628                 return;
629         }
630
631         wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
632                    "(%s%s%s%s)",
633                    drv->operstate, ifi->ifi_flags,
634                    (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
635                    (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
636                    (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
637                    (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
638
639         if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
640                 wpa_printf(MSG_DEBUG, "WEXT: Interface down");
641                 drv->if_disabled = 1;
642                 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
643         }
644
645         if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
646                 wpa_printf(MSG_DEBUG, "WEXT: Interface up");
647                 drv->if_disabled = 0;
648                 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
649         }
650
651         /*
652          * Some drivers send the association event before the operup event--in
653          * this case, lifting operstate in wpa_driver_wext_set_operstate()
654          * fails. This will hit us when wpa_supplicant does not need to do
655          * IEEE 802.1X authentication
656          */
657         if (drv->operstate == 1 &&
658             (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
659             !(ifi->ifi_flags & IFF_RUNNING))
660                 netlink_send_oper_ifla(drv->netlink, drv->ifindex,
661                                        -1, IF_OPER_UP);
662
663         attrlen = len;
664         attr = (struct rtattr *) buf;
665
666         rta_len = RTA_ALIGN(sizeof(struct rtattr));
667         while (RTA_OK(attr, attrlen)) {
668                 if (attr->rta_type == IFLA_WIRELESS) {
669                         wpa_driver_wext_event_wireless(
670                                 drv, ((char *) attr) + rta_len,
671                                 attr->rta_len - rta_len);
672                 } else if (attr->rta_type == IFLA_IFNAME) {
673                         wpa_driver_wext_event_link(drv,
674                                                    ((char *) attr) + rta_len,
675                                                    attr->rta_len - rta_len, 0);
676                 }
677                 attr = RTA_NEXT(attr, attrlen);
678         }
679 }
680
681
682 static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi,
683                                               u8 *buf, size_t len)
684 {
685         struct wpa_driver_wext_data *drv = ctx;
686         int attrlen, rta_len;
687         struct rtattr *attr;
688
689         attrlen = len;
690         attr = (struct rtattr *) buf;
691
692         rta_len = RTA_ALIGN(sizeof(struct rtattr));
693         while (RTA_OK(attr, attrlen)) {
694                 if (attr->rta_type == IFLA_IFNAME) {
695                         wpa_driver_wext_event_link(drv,
696                                                    ((char *) attr) + rta_len,
697                                                    attr->rta_len - rta_len, 1);
698                 }
699                 attr = RTA_NEXT(attr, attrlen);
700         }
701 }
702
703
704 static void wpa_driver_wext_rfkill_blocked(void *ctx)
705 {
706         wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked");
707         /*
708          * This may be for any interface; use ifdown event to disable
709          * interface.
710          */
711 }
712
713
714 static void wpa_driver_wext_rfkill_unblocked(void *ctx)
715 {
716         struct wpa_driver_wext_data *drv = ctx;
717         wpa_printf(MSG_DEBUG, "WEXT: RFKILL unblocked");
718         if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)) {
719                 wpa_printf(MSG_DEBUG, "WEXT: Could not set interface UP "
720                            "after rfkill unblock");
721                 return;
722         }
723         /* rtnetlink ifup handler will report interface as enabled */
724 }
725
726
727 /**
728  * wpa_driver_wext_init - Initialize WE driver interface
729  * @ctx: context to be used when calling wpa_supplicant functions,
730  * e.g., wpa_supplicant_event()
731  * @ifname: interface name, e.g., wlan0
732  * Returns: Pointer to private data, %NULL on failure
733  */
734 void * wpa_driver_wext_init(void *ctx, const char *ifname)
735 {
736         struct wpa_driver_wext_data *drv;
737         struct netlink_config *cfg;
738         struct rfkill_config *rcfg;
739         char path[128];
740         struct stat buf;
741
742         drv = os_zalloc(sizeof(*drv));
743         if (drv == NULL)
744                 return NULL;
745         drv->ctx = ctx;
746         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
747
748         os_snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", ifname);
749         if (stat(path, &buf) == 0) {
750                 wpa_printf(MSG_DEBUG, "WEXT: cfg80211-based driver detected");
751                 drv->cfg80211 = 1;
752         }
753
754         drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
755         if (drv->ioctl_sock < 0) {
756                 perror("socket(PF_INET,SOCK_DGRAM)");
757                 goto err1;
758         }
759
760         cfg = os_zalloc(sizeof(*cfg));
761         if (cfg == NULL)
762                 goto err1;
763         cfg->ctx = drv;
764         cfg->newlink_cb = wpa_driver_wext_event_rtm_newlink;
765         cfg->dellink_cb = wpa_driver_wext_event_rtm_dellink;
766         drv->netlink = netlink_init(cfg);
767         if (drv->netlink == NULL) {
768                 os_free(cfg);
769                 goto err2;
770         }
771
772         rcfg = os_zalloc(sizeof(*rcfg));
773         if (rcfg == NULL)
774                 goto err3;
775         rcfg->ctx = drv;
776         os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
777         rcfg->blocked_cb = wpa_driver_wext_rfkill_blocked;
778         rcfg->unblocked_cb = wpa_driver_wext_rfkill_unblocked;
779         drv->rfkill = rfkill_init(rcfg);
780         if (drv->rfkill == NULL) {
781                 wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not available");
782                 os_free(rcfg);
783         }
784
785         drv->mlme_sock = -1;
786
787         if (wpa_driver_wext_finish_drv_init(drv) < 0)
788                 goto err3;
789
790         wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 1);
791
792         return drv;
793
794 err3:
795         rfkill_deinit(drv->rfkill);
796         netlink_deinit(drv->netlink);
797 err2:
798         close(drv->ioctl_sock);
799 err1:
800         os_free(drv);
801         return NULL;
802 }
803
804
805 static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx)
806 {
807         wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
808 }
809
810
811 static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
812 {
813         int send_rfkill_event = 0;
814
815         if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) {
816                 if (rfkill_is_blocked(drv->rfkill)) {
817                         wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable "
818                                    "interface '%s' due to rfkill",
819                                    drv->ifname);
820                         drv->if_disabled = 1;
821                         send_rfkill_event = 1;
822                 } else {
823                         wpa_printf(MSG_ERROR, "WEXT: Could not set "
824                                    "interface '%s' UP", drv->ifname);
825                         return -1;
826                 }
827         }
828
829         /*
830          * Make sure that the driver does not have any obsolete PMKID entries.
831          */
832         wpa_driver_wext_flush_pmkid(drv);
833
834         if (wpa_driver_wext_set_mode(drv, 0) < 0) {
835                 wpa_printf(MSG_DEBUG, "Could not configure driver to use "
836                            "managed mode");
837                 /* Try to use it anyway */
838         }
839
840         wpa_driver_wext_get_range(drv);
841
842         /*
843          * Unlock the driver's BSSID and force to a random SSID to clear any
844          * previous association the driver might have when the supplicant
845          * starts up.
846          */
847         wpa_driver_wext_disconnect(drv);
848
849         drv->ifindex = if_nametoindex(drv->ifname);
850
851         if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
852                 /*
853                  * Host AP driver may use both wlan# and wifi# interface in
854                  * wireless events. Since some of the versions included WE-18
855                  * support, let's add the alternative ifindex also from
856                  * driver_wext.c for the time being. This may be removed at
857                  * some point once it is believed that old versions of the
858                  * driver are not in use anymore.
859                  */
860                 char ifname2[IFNAMSIZ + 1];
861                 os_strlcpy(ifname2, drv->ifname, sizeof(ifname2));
862                 os_memcpy(ifname2, "wifi", 4);
863                 wpa_driver_wext_alternative_ifindex(drv, ifname2);
864         }
865
866         netlink_send_oper_ifla(drv->netlink, drv->ifindex,
867                                1, IF_OPER_DORMANT);
868
869         if (send_rfkill_event) {
870                 eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill,
871                                        drv, drv->ctx);
872         }
873
874         return 0;
875 }
876
877
878 /**
879  * wpa_driver_wext_deinit - Deinitialize WE driver interface
880  * @priv: Pointer to private wext data from wpa_driver_wext_init()
881  *
882  * Shut down driver interface and processing of driver events. Free
883  * private data buffer if one was allocated in wpa_driver_wext_init().
884  */
885 void wpa_driver_wext_deinit(void *priv)
886 {
887         struct wpa_driver_wext_data *drv = priv;
888
889         wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 0);
890
891         eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
892
893         /*
894          * Clear possibly configured driver parameters in order to make it
895          * easier to use the driver after wpa_supplicant has been terminated.
896          */
897         wpa_driver_wext_disconnect(drv);
898
899         netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP);
900         netlink_deinit(drv->netlink);
901         rfkill_deinit(drv->rfkill);
902
903         if (drv->mlme_sock >= 0)
904                 eloop_unregister_read_sock(drv->mlme_sock);
905
906         (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
907
908         close(drv->ioctl_sock);
909         if (drv->mlme_sock >= 0)
910                 close(drv->mlme_sock);
911         os_free(drv->assoc_req_ies);
912         os_free(drv->assoc_resp_ies);
913         os_free(drv);
914 }
915
916
917 /**
918  * wpa_driver_wext_scan_timeout - Scan timeout to report scan completion
919  * @eloop_ctx: Unused
920  * @timeout_ctx: ctx argument given to wpa_driver_wext_init()
921  *
922  * This function can be used as registered timeout when starting a scan to
923  * generate a scan completed event if the driver does not report this.
924  */
925 void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx)
926 {
927         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
928         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
929 }
930
931
932 /**
933  * wpa_driver_wext_scan - Request the driver to initiate scan
934  * @priv: Pointer to private wext data from wpa_driver_wext_init()
935  * @param: Scan parameters (specific SSID to scan for (ProbeReq), etc.)
936  * Returns: 0 on success, -1 on failure
937  */
938 int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params)
939 {
940         struct wpa_driver_wext_data *drv = priv;
941         struct iwreq iwr;
942         int ret = 0, timeout;
943         struct iw_scan_req req;
944         const u8 *ssid = params->ssids[0].ssid;
945         size_t ssid_len = params->ssids[0].ssid_len;
946
947         if (ssid_len > IW_ESSID_MAX_SIZE) {
948                 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
949                            __FUNCTION__, (unsigned long) ssid_len);
950                 return -1;
951         }
952
953         os_memset(&iwr, 0, sizeof(iwr));
954         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
955
956         if (ssid && ssid_len) {
957                 os_memset(&req, 0, sizeof(req));
958                 req.essid_len = ssid_len;
959                 req.bssid.sa_family = ARPHRD_ETHER;
960                 os_memset(req.bssid.sa_data, 0xff, ETH_ALEN);
961                 os_memcpy(req.essid, ssid, ssid_len);
962                 iwr.u.data.pointer = (caddr_t) &req;
963                 iwr.u.data.length = sizeof(req);
964                 iwr.u.data.flags = IW_SCAN_THIS_ESSID;
965         }
966
967         if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
968                 perror("ioctl[SIOCSIWSCAN]");
969                 ret = -1;
970         }
971
972         /* Not all drivers generate "scan completed" wireless event, so try to
973          * read results after a timeout. */
974         timeout = 5;
975         if (drv->scan_complete_events) {
976                 /*
977                  * The driver seems to deliver SIOCGIWSCAN events to notify
978                  * when scan is complete, so use longer timeout to avoid race
979                  * conditions with scanning and following association request.
980                  */
981                 timeout = 30;
982         }
983         wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
984                    "seconds", ret, timeout);
985         eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
986         eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
987                                drv->ctx);
988
989         return ret;
990 }
991
992
993 static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv,
994                                     size_t *len)
995 {
996         struct iwreq iwr;
997         u8 *res_buf;
998         size_t res_buf_len;
999
1000         res_buf_len = IW_SCAN_MAX_DATA;
1001         for (;;) {
1002                 res_buf = os_malloc(res_buf_len);
1003                 if (res_buf == NULL)
1004                         return NULL;
1005                 os_memset(&iwr, 0, sizeof(iwr));
1006                 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1007                 iwr.u.data.pointer = res_buf;
1008                 iwr.u.data.length = res_buf_len;
1009
1010                 if (ioctl(drv->ioctl_sock, SIOCGIWSCAN, &iwr) == 0)
1011                         break;
1012
1013                 if (errno == E2BIG && res_buf_len < 65535) {
1014                         os_free(res_buf);
1015                         res_buf = NULL;
1016                         res_buf_len *= 2;
1017                         if (res_buf_len > 65535)
1018                                 res_buf_len = 65535; /* 16-bit length field */
1019                         wpa_printf(MSG_DEBUG, "Scan results did not fit - "
1020                                    "trying larger buffer (%lu bytes)",
1021                                    (unsigned long) res_buf_len);
1022                 } else {
1023                         perror("ioctl[SIOCGIWSCAN]");
1024                         os_free(res_buf);
1025                         return NULL;
1026                 }
1027         }
1028
1029         if (iwr.u.data.length > res_buf_len) {
1030                 os_free(res_buf);
1031                 return NULL;
1032         }
1033         *len = iwr.u.data.length;
1034
1035         return res_buf;
1036 }
1037
1038
1039 /*
1040  * Data structure for collecting WEXT scan results. This is needed to allow
1041  * the various methods of reporting IEs to be combined into a single IE buffer.
1042  */
1043 struct wext_scan_data {
1044         struct wpa_scan_res res;
1045         u8 *ie;
1046         size_t ie_len;
1047         u8 ssid[32];
1048         size_t ssid_len;
1049         int maxrate;
1050 };
1051
1052
1053 static void wext_get_scan_mode(struct iw_event *iwe,
1054                                struct wext_scan_data *res)
1055 {
1056         if (iwe->u.mode == IW_MODE_ADHOC)
1057                 res->res.caps |= IEEE80211_CAP_IBSS;
1058         else if (iwe->u.mode == IW_MODE_MASTER || iwe->u.mode == IW_MODE_INFRA)
1059                 res->res.caps |= IEEE80211_CAP_ESS;
1060 }
1061
1062
1063 static void wext_get_scan_ssid(struct iw_event *iwe,
1064                                struct wext_scan_data *res, char *custom,
1065                                char *end)
1066 {
1067         int ssid_len = iwe->u.essid.length;
1068         if (custom + ssid_len > end)
1069                 return;
1070         if (iwe->u.essid.flags &&
1071             ssid_len > 0 &&
1072             ssid_len <= IW_ESSID_MAX_SIZE) {
1073                 os_memcpy(res->ssid, custom, ssid_len);
1074                 res->ssid_len = ssid_len;
1075         }
1076 }
1077
1078
1079 static void wext_get_scan_freq(struct iw_event *iwe,
1080                                struct wext_scan_data *res)
1081 {
1082         int divi = 1000000, i;
1083
1084         if (iwe->u.freq.e == 0) {
1085                 /*
1086                  * Some drivers do not report frequency, but a channel.
1087                  * Try to map this to frequency by assuming they are using
1088                  * IEEE 802.11b/g.  But don't overwrite a previously parsed
1089                  * frequency if the driver sends both frequency and channel,
1090                  * since the driver may be sending an A-band channel that we
1091                  * don't handle here.
1092                  */
1093
1094                 if (res->res.freq)
1095                         return;
1096
1097                 if (iwe->u.freq.m >= 1 && iwe->u.freq.m <= 13) {
1098                         res->res.freq = 2407 + 5 * iwe->u.freq.m;
1099                         return;
1100                 } else if (iwe->u.freq.m == 14) {
1101                         res->res.freq = 2484;
1102                         return;
1103                 }
1104         }
1105
1106         if (iwe->u.freq.e > 6) {
1107                 wpa_printf(MSG_DEBUG, "Invalid freq in scan results (BSSID="
1108                            MACSTR " m=%d e=%d)",
1109                            MAC2STR(res->res.bssid), iwe->u.freq.m,
1110                            iwe->u.freq.e);
1111                 return;
1112         }
1113
1114         for (i = 0; i < iwe->u.freq.e; i++)
1115                 divi /= 10;
1116         res->res.freq = iwe->u.freq.m / divi;
1117 }
1118
1119
1120 static void wext_get_scan_qual(struct wpa_driver_wext_data *drv,
1121                                struct iw_event *iwe,
1122                                struct wext_scan_data *res)
1123 {
1124         res->res.qual = iwe->u.qual.qual;
1125         res->res.noise = iwe->u.qual.noise;
1126         res->res.level = iwe->u.qual.level;
1127         if (iwe->u.qual.updated & IW_QUAL_QUAL_INVALID)
1128                 res->res.flags |= WPA_SCAN_QUAL_INVALID;
1129         if (iwe->u.qual.updated & IW_QUAL_LEVEL_INVALID)
1130                 res->res.flags |= WPA_SCAN_LEVEL_INVALID;
1131         if (iwe->u.qual.updated & IW_QUAL_NOISE_INVALID)
1132                 res->res.flags |= WPA_SCAN_NOISE_INVALID;
1133         if (iwe->u.qual.updated & IW_QUAL_DBM)
1134                 res->res.flags |= WPA_SCAN_LEVEL_DBM;
1135         if ((iwe->u.qual.updated & IW_QUAL_DBM) ||
1136             ((iwe->u.qual.level != 0) &&
1137              (iwe->u.qual.level > drv->max_level))) {
1138                 if (iwe->u.qual.level >= 64)
1139                         res->res.level -= 0x100;
1140                 if (iwe->u.qual.noise >= 64)
1141                         res->res.noise -= 0x100;
1142         }
1143 }
1144
1145
1146 static void wext_get_scan_encode(struct iw_event *iwe,
1147                                  struct wext_scan_data *res)
1148 {
1149         if (!(iwe->u.data.flags & IW_ENCODE_DISABLED))
1150                 res->res.caps |= IEEE80211_CAP_PRIVACY;
1151 }
1152
1153
1154 static void wext_get_scan_rate(struct iw_event *iwe,
1155                                struct wext_scan_data *res, char *pos,
1156                                char *end)
1157 {
1158         int maxrate;
1159         char *custom = pos + IW_EV_LCP_LEN;
1160         struct iw_param p;
1161         size_t clen;
1162
1163         clen = iwe->len;
1164         if (custom + clen > end)
1165                 return;
1166         maxrate = 0;
1167         while (((ssize_t) clen) >= (ssize_t) sizeof(struct iw_param)) {
1168                 /* Note: may be misaligned, make a local, aligned copy */
1169                 os_memcpy(&p, custom, sizeof(struct iw_param));
1170                 if (p.value > maxrate)
1171                         maxrate = p.value;
1172                 clen -= sizeof(struct iw_param);
1173                 custom += sizeof(struct iw_param);
1174         }
1175
1176         /* Convert the maxrate from WE-style (b/s units) to
1177          * 802.11 rates (500000 b/s units).
1178          */
1179         res->maxrate = maxrate / 500000;
1180 }
1181
1182
1183 static void wext_get_scan_iwevgenie(struct iw_event *iwe,
1184                                     struct wext_scan_data *res, char *custom,
1185                                     char *end)
1186 {
1187         char *genie, *gpos, *gend;
1188         u8 *tmp;
1189
1190         if (iwe->u.data.length == 0)
1191                 return;
1192
1193         gpos = genie = custom;
1194         gend = genie + iwe->u.data.length;
1195         if (gend > end) {
1196                 wpa_printf(MSG_INFO, "IWEVGENIE overflow");
1197                 return;
1198         }
1199
1200         tmp = os_realloc(res->ie, res->ie_len + gend - gpos);
1201         if (tmp == NULL)
1202                 return;
1203         os_memcpy(tmp + res->ie_len, gpos, gend - gpos);
1204         res->ie = tmp;
1205         res->ie_len += gend - gpos;
1206 }
1207
1208
1209 static void wext_get_scan_custom(struct iw_event *iwe,
1210                                  struct wext_scan_data *res, char *custom,
1211                                  char *end)
1212 {
1213         size_t clen;
1214         u8 *tmp;
1215
1216         clen = iwe->u.data.length;
1217         if (custom + clen > end)
1218                 return;
1219
1220         if (clen > 7 && os_strncmp(custom, "wpa_ie=", 7) == 0) {
1221                 char *spos;
1222                 int bytes;
1223                 spos = custom + 7;
1224                 bytes = custom + clen - spos;
1225                 if (bytes & 1 || bytes == 0)
1226                         return;
1227                 bytes /= 2;
1228                 tmp = os_realloc(res->ie, res->ie_len + bytes);
1229                 if (tmp == NULL)
1230                         return;
1231                 res->ie = tmp;
1232                 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0)
1233                         return;
1234                 res->ie_len += bytes;
1235         } else if (clen > 7 && os_strncmp(custom, "rsn_ie=", 7) == 0) {
1236                 char *spos;
1237                 int bytes;
1238                 spos = custom + 7;
1239                 bytes = custom + clen - spos;
1240                 if (bytes & 1 || bytes == 0)
1241                         return;
1242                 bytes /= 2;
1243                 tmp = os_realloc(res->ie, res->ie_len + bytes);
1244                 if (tmp == NULL)
1245                         return;
1246                 res->ie = tmp;
1247                 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0)
1248                         return;
1249                 res->ie_len += bytes;
1250         } else if (clen > 4 && os_strncmp(custom, "tsf=", 4) == 0) {
1251                 char *spos;
1252                 int bytes;
1253                 u8 bin[8];
1254                 spos = custom + 4;
1255                 bytes = custom + clen - spos;
1256                 if (bytes != 16) {
1257                         wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes);
1258                         return;
1259                 }
1260                 bytes /= 2;
1261                 if (hexstr2bin(spos, bin, bytes) < 0) {
1262                         wpa_printf(MSG_DEBUG, "WEXT: Invalid TSF value");
1263                         return;
1264                 }
1265                 res->res.tsf += WPA_GET_BE64(bin);
1266         }
1267 }
1268
1269
1270 static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd)
1271 {
1272         return drv->we_version_compiled > 18 &&
1273                 (cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE ||
1274                  cmd == IWEVGENIE || cmd == IWEVCUSTOM);
1275 }
1276
1277
1278 static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res,
1279                                            struct wext_scan_data *data)
1280 {
1281         struct wpa_scan_res **tmp;
1282         struct wpa_scan_res *r;
1283         size_t extra_len;
1284         u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL;
1285
1286         /* Figure out whether we need to fake any IEs */
1287         pos = data->ie;
1288         end = pos + data->ie_len;
1289         while (pos && pos + 1 < end) {
1290                 if (pos + 2 + pos[1] > end)
1291                         break;
1292                 if (pos[0] == WLAN_EID_SSID)
1293                         ssid_ie = pos;
1294                 else if (pos[0] == WLAN_EID_SUPP_RATES)
1295                         rate_ie = pos;
1296                 else if (pos[0] == WLAN_EID_EXT_SUPP_RATES)
1297                         rate_ie = pos;
1298                 pos += 2 + pos[1];
1299         }
1300
1301         extra_len = 0;
1302         if (ssid_ie == NULL)
1303                 extra_len += 2 + data->ssid_len;
1304         if (rate_ie == NULL && data->maxrate)
1305                 extra_len += 3;
1306
1307         r = os_zalloc(sizeof(*r) + extra_len + data->ie_len);
1308         if (r == NULL)
1309                 return;
1310         os_memcpy(r, &data->res, sizeof(*r));
1311         r->ie_len = extra_len + data->ie_len;
1312         pos = (u8 *) (r + 1);
1313         if (ssid_ie == NULL) {
1314                 /*
1315                  * Generate a fake SSID IE since the driver did not report
1316                  * a full IE list.
1317                  */
1318                 *pos++ = WLAN_EID_SSID;
1319                 *pos++ = data->ssid_len;
1320                 os_memcpy(pos, data->ssid, data->ssid_len);
1321                 pos += data->ssid_len;
1322         }
1323         if (rate_ie == NULL && data->maxrate) {
1324                 /*
1325                  * Generate a fake Supported Rates IE since the driver did not
1326                  * report a full IE list.
1327                  */
1328                 *pos++ = WLAN_EID_SUPP_RATES;
1329                 *pos++ = 1;
1330                 *pos++ = data->maxrate;
1331         }
1332         if (data->ie)
1333                 os_memcpy(pos, data->ie, data->ie_len);
1334
1335         tmp = os_realloc(res->res,
1336                          (res->num + 1) * sizeof(struct wpa_scan_res *));
1337         if (tmp == NULL) {
1338                 os_free(r);
1339                 return;
1340         }
1341         tmp[res->num++] = r;
1342         res->res = tmp;
1343 }
1344                                       
1345
1346 /**
1347  * wpa_driver_wext_get_scan_results - Fetch the latest scan results
1348  * @priv: Pointer to private wext data from wpa_driver_wext_init()
1349  * Returns: Scan results on success, -1 on failure
1350  */
1351 struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv)
1352 {
1353         struct wpa_driver_wext_data *drv = priv;
1354         size_t ap_num = 0, len;
1355         int first;
1356         u8 *res_buf;
1357         struct iw_event iwe_buf, *iwe = &iwe_buf;
1358         char *pos, *end, *custom;
1359         struct wpa_scan_results *res;
1360         struct wext_scan_data data;
1361
1362         res_buf = wpa_driver_wext_giwscan(drv, &len);
1363         if (res_buf == NULL)
1364                 return NULL;
1365
1366         ap_num = 0;
1367         first = 1;
1368
1369         res = os_zalloc(sizeof(*res));
1370         if (res == NULL) {
1371                 os_free(res_buf);
1372                 return NULL;
1373         }
1374
1375         pos = (char *) res_buf;
1376         end = (char *) res_buf + len;
1377         os_memset(&data, 0, sizeof(data));
1378
1379         while (pos + IW_EV_LCP_LEN <= end) {
1380                 /* Event data may be unaligned, so make a local, aligned copy
1381                  * before processing. */
1382                 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
1383                 if (iwe->len <= IW_EV_LCP_LEN)
1384                         break;
1385
1386                 custom = pos + IW_EV_POINT_LEN;
1387                 if (wext_19_iw_point(drv, iwe->cmd)) {
1388                         /* WE-19 removed the pointer from struct iw_point */
1389                         char *dpos = (char *) &iwe_buf.u.data.length;
1390                         int dlen = dpos - (char *) &iwe_buf;
1391                         os_memcpy(dpos, pos + IW_EV_LCP_LEN,
1392                                   sizeof(struct iw_event) - dlen);
1393                 } else {
1394                         os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
1395                         custom += IW_EV_POINT_OFF;
1396                 }
1397
1398                 switch (iwe->cmd) {
1399                 case SIOCGIWAP:
1400                         if (!first)
1401                                 wpa_driver_wext_add_scan_entry(res, &data);
1402                         first = 0;
1403                         os_free(data.ie);
1404                         os_memset(&data, 0, sizeof(data));
1405                         os_memcpy(data.res.bssid,
1406                                   iwe->u.ap_addr.sa_data, ETH_ALEN);
1407                         break;
1408                 case SIOCGIWMODE:
1409                         wext_get_scan_mode(iwe, &data);
1410                         break;
1411                 case SIOCGIWESSID:
1412                         wext_get_scan_ssid(iwe, &data, custom, end);
1413                         break;
1414                 case SIOCGIWFREQ:
1415                         wext_get_scan_freq(iwe, &data);
1416                         break;
1417                 case IWEVQUAL:
1418                         wext_get_scan_qual(drv, iwe, &data);
1419                         break;
1420                 case SIOCGIWENCODE:
1421                         wext_get_scan_encode(iwe, &data);
1422                         break;
1423                 case SIOCGIWRATE:
1424                         wext_get_scan_rate(iwe, &data, pos, end);
1425                         break;
1426                 case IWEVGENIE:
1427                         wext_get_scan_iwevgenie(iwe, &data, custom, end);
1428                         break;
1429                 case IWEVCUSTOM:
1430                         wext_get_scan_custom(iwe, &data, custom, end);
1431                         break;
1432                 }
1433
1434                 pos += iwe->len;
1435         }
1436         os_free(res_buf);
1437         res_buf = NULL;
1438         if (!first)
1439                 wpa_driver_wext_add_scan_entry(res, &data);
1440         os_free(data.ie);
1441
1442         wpa_printf(MSG_DEBUG, "Received %lu bytes of scan results (%lu BSSes)",
1443                    (unsigned long) len, (unsigned long) res->num);
1444
1445         return res;
1446 }
1447
1448
1449 static int wpa_driver_wext_get_range(void *priv)
1450 {
1451         struct wpa_driver_wext_data *drv = priv;
1452         struct iw_range *range;
1453         struct iwreq iwr;
1454         int minlen;
1455         size_t buflen;
1456
1457         /*
1458          * Use larger buffer than struct iw_range in order to allow the
1459          * structure to grow in the future.
1460          */
1461         buflen = sizeof(struct iw_range) + 500;
1462         range = os_zalloc(buflen);
1463         if (range == NULL)
1464                 return -1;
1465
1466         os_memset(&iwr, 0, sizeof(iwr));
1467         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1468         iwr.u.data.pointer = (caddr_t) range;
1469         iwr.u.data.length = buflen;
1470
1471         minlen = ((char *) &range->enc_capa) - (char *) range +
1472                 sizeof(range->enc_capa);
1473
1474         if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
1475                 perror("ioctl[SIOCGIWRANGE]");
1476                 os_free(range);
1477                 return -1;
1478         } else if (iwr.u.data.length >= minlen &&
1479                    range->we_version_compiled >= 18) {
1480                 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
1481                            "WE(source)=%d enc_capa=0x%x",
1482                            range->we_version_compiled,
1483                            range->we_version_source,
1484                            range->enc_capa);
1485                 drv->has_capability = 1;
1486                 drv->we_version_compiled = range->we_version_compiled;
1487                 if (range->enc_capa & IW_ENC_CAPA_WPA) {
1488                         drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1489                                 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
1490                 }
1491                 if (range->enc_capa & IW_ENC_CAPA_WPA2) {
1492                         drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1493                                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1494                 }
1495                 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
1496                         WPA_DRIVER_CAPA_ENC_WEP104;
1497                 if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
1498                         drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
1499                 if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
1500                         drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
1501                 if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
1502                         drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
1503                 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
1504                         WPA_DRIVER_AUTH_SHARED |
1505                         WPA_DRIVER_AUTH_LEAP;
1506                 drv->capa.max_scan_ssids = 1;
1507
1508                 wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
1509                            "flags 0x%x",
1510                            drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);
1511         } else {
1512                 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "
1513                            "assuming WPA is not supported");
1514         }
1515
1516         drv->max_level = range->max_qual.level;
1517
1518         os_free(range);
1519         return 0;
1520 }
1521
1522
1523 static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
1524                                    const u8 *psk)
1525 {
1526         struct iw_encode_ext *ext;
1527         struct iwreq iwr;
1528         int ret;
1529
1530         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1531
1532         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
1533                 return 0;
1534
1535         if (!psk)
1536                 return 0;
1537
1538         os_memset(&iwr, 0, sizeof(iwr));
1539         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1540
1541         ext = os_zalloc(sizeof(*ext) + PMK_LEN);
1542         if (ext == NULL)
1543                 return -1;
1544
1545         iwr.u.encoding.pointer = (caddr_t) ext;
1546         iwr.u.encoding.length = sizeof(*ext) + PMK_LEN;
1547         ext->key_len = PMK_LEN;
1548         os_memcpy(&ext->key, psk, ext->key_len);
1549         ext->alg = IW_ENCODE_ALG_PMK;
1550
1551         ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr);
1552         if (ret < 0)
1553                 perror("ioctl[SIOCSIWENCODEEXT] PMK");
1554         os_free(ext);
1555
1556         return ret;
1557 }
1558
1559
1560 static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg,
1561                                        const u8 *addr, int key_idx,
1562                                        int set_tx, const u8 *seq,
1563                                        size_t seq_len,
1564                                        const u8 *key, size_t key_len)
1565 {
1566         struct wpa_driver_wext_data *drv = priv;
1567         struct iwreq iwr;
1568         int ret = 0;
1569         struct iw_encode_ext *ext;
1570
1571         if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) {
1572                 wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu",
1573                            __FUNCTION__, (unsigned long) seq_len);
1574                 return -1;
1575         }
1576
1577         ext = os_zalloc(sizeof(*ext) + key_len);
1578         if (ext == NULL)
1579                 return -1;
1580         os_memset(&iwr, 0, sizeof(iwr));
1581         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1582         iwr.u.encoding.flags = key_idx + 1;
1583         iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1584         if (alg == WPA_ALG_NONE)
1585                 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1586         iwr.u.encoding.pointer = (caddr_t) ext;
1587         iwr.u.encoding.length = sizeof(*ext) + key_len;
1588
1589         if (addr == NULL ||
1590             os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
1591                 ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY;
1592         if (set_tx)
1593                 ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY;
1594
1595         ext->addr.sa_family = ARPHRD_ETHER;
1596         if (addr)
1597                 os_memcpy(ext->addr.sa_data, addr, ETH_ALEN);
1598         else
1599                 os_memset(ext->addr.sa_data, 0xff, ETH_ALEN);
1600         if (key && key_len) {
1601                 os_memcpy(ext + 1, key, key_len);
1602                 ext->key_len = key_len;
1603         }
1604         switch (alg) {
1605         case WPA_ALG_NONE:
1606                 ext->alg = IW_ENCODE_ALG_NONE;
1607                 break;
1608         case WPA_ALG_WEP:
1609                 ext->alg = IW_ENCODE_ALG_WEP;
1610                 break;
1611         case WPA_ALG_TKIP:
1612                 ext->alg = IW_ENCODE_ALG_TKIP;
1613                 break;
1614         case WPA_ALG_CCMP:
1615                 ext->alg = IW_ENCODE_ALG_CCMP;
1616                 break;
1617         case WPA_ALG_PMK:
1618                 ext->alg = IW_ENCODE_ALG_PMK;
1619                 break;
1620 #ifdef CONFIG_IEEE80211W
1621         case WPA_ALG_IGTK:
1622                 ext->alg = IW_ENCODE_ALG_AES_CMAC;
1623                 break;
1624 #endif /* CONFIG_IEEE80211W */
1625         default:
1626                 wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
1627                            __FUNCTION__, alg);
1628                 os_free(ext);
1629                 return -1;
1630         }
1631
1632         if (seq && seq_len) {
1633                 ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID;
1634                 os_memcpy(ext->rx_seq, seq, seq_len);
1635         }
1636
1637         if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) {
1638                 ret = errno == EOPNOTSUPP ? -2 : -1;
1639                 if (errno == ENODEV) {
1640                         /*
1641                          * ndiswrapper seems to be returning incorrect error
1642                          * code.. */
1643                         ret = -2;
1644                 }
1645
1646                 perror("ioctl[SIOCSIWENCODEEXT]");
1647         }
1648
1649         os_free(ext);
1650         return ret;
1651 }
1652
1653
1654 /**
1655  * wpa_driver_wext_set_key - Configure encryption key
1656  * @priv: Pointer to private wext data from wpa_driver_wext_init()
1657  * @priv: Private driver interface data
1658  * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP,
1659  *      %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key.
1660  * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for
1661  *      broadcast/default keys
1662  * @key_idx: key index (0..3), usually 0 for unicast keys
1663  * @set_tx: Configure this key as the default Tx key (only used when
1664  *      driver does not support separate unicast/individual key
1665  * @seq: Sequence number/packet number, seq_len octets, the next
1666  *      packet number to be used for in replay protection; configured
1667  *      for Rx keys (in most cases, this is only used with broadcast
1668  *      keys and set to zero for unicast keys)
1669  * @seq_len: Length of the seq, depends on the algorithm:
1670  *      TKIP: 6 octets, CCMP: 6 octets
1671  * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key,
1672  *      8-byte Rx Mic Key
1673  * @key_len: Length of the key buffer in octets (WEP: 5 or 13,
1674  *      TKIP: 32, CCMP: 16)
1675  * Returns: 0 on success, -1 on failure
1676  *
1677  * This function uses SIOCSIWENCODEEXT by default, but tries to use
1678  * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key.
1679  */
1680 int wpa_driver_wext_set_key(const char *ifname, void *priv, enum wpa_alg alg,
1681                             const u8 *addr, int key_idx,
1682                             int set_tx, const u8 *seq, size_t seq_len,
1683                             const u8 *key, size_t key_len)
1684 {
1685         struct wpa_driver_wext_data *drv = priv;
1686         struct iwreq iwr;
1687         int ret = 0;
1688
1689         wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
1690                    "key_len=%lu",
1691                    __FUNCTION__, alg, key_idx, set_tx,
1692                    (unsigned long) seq_len, (unsigned long) key_len);
1693
1694         ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx,
1695                                           seq, seq_len, key, key_len);
1696         if (ret == 0)
1697                 return 0;
1698
1699         if (ret == -2 &&
1700             (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) {
1701                 wpa_printf(MSG_DEBUG, "Driver did not support "
1702                            "SIOCSIWENCODEEXT, trying SIOCSIWENCODE");
1703                 ret = 0;
1704         } else {
1705                 wpa_printf(MSG_DEBUG, "Driver did not support "
1706                            "SIOCSIWENCODEEXT");
1707                 return ret;
1708         }
1709
1710         os_memset(&iwr, 0, sizeof(iwr));
1711         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1712         iwr.u.encoding.flags = key_idx + 1;
1713         iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1714         if (alg == WPA_ALG_NONE)
1715                 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1716         iwr.u.encoding.pointer = (caddr_t) key;
1717         iwr.u.encoding.length = key_len;
1718
1719         if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
1720                 perror("ioctl[SIOCSIWENCODE]");
1721                 ret = -1;
1722         }
1723
1724         if (set_tx && alg != WPA_ALG_NONE) {
1725                 os_memset(&iwr, 0, sizeof(iwr));
1726                 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1727                 iwr.u.encoding.flags = key_idx + 1;
1728                 iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1729                 iwr.u.encoding.pointer = (caddr_t) NULL;
1730                 iwr.u.encoding.length = 0;
1731                 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
1732                         perror("ioctl[SIOCSIWENCODE] (set_tx)");
1733                         ret = -1;
1734                 }
1735         }
1736
1737         return ret;
1738 }
1739
1740
1741 static int wpa_driver_wext_set_countermeasures(void *priv,
1742                                                int enabled)
1743 {
1744         struct wpa_driver_wext_data *drv = priv;
1745         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1746         return wpa_driver_wext_set_auth_param(drv,
1747                                               IW_AUTH_TKIP_COUNTERMEASURES,
1748                                               enabled);
1749 }
1750
1751
1752 static int wpa_driver_wext_set_drop_unencrypted(void *priv,
1753                                                 int enabled)
1754 {
1755         struct wpa_driver_wext_data *drv = priv;
1756         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1757         drv->use_crypt = enabled;
1758         return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
1759                                               enabled);
1760 }
1761
1762
1763 static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv,
1764                                 const u8 *addr, int cmd, int reason_code)
1765 {
1766         struct iwreq iwr;
1767         struct iw_mlme mlme;
1768         int ret = 0;
1769
1770         os_memset(&iwr, 0, sizeof(iwr));
1771         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1772         os_memset(&mlme, 0, sizeof(mlme));
1773         mlme.cmd = cmd;
1774         mlme.reason_code = reason_code;
1775         mlme.addr.sa_family = ARPHRD_ETHER;
1776         os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
1777         iwr.u.data.pointer = (caddr_t) &mlme;
1778         iwr.u.data.length = sizeof(mlme);
1779
1780         if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
1781                 perror("ioctl[SIOCSIWMLME]");
1782                 ret = -1;
1783         }
1784
1785         return ret;
1786 }
1787
1788
1789 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
1790 {
1791         struct iwreq iwr;
1792         const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
1793         u8 ssid[32];
1794         int i;
1795
1796         /*
1797          * Only force-disconnect when the card is in infrastructure mode,
1798          * otherwise the driver might interpret the cleared BSSID and random
1799          * SSID as an attempt to create a new ad-hoc network.
1800          */
1801         os_memset(&iwr, 0, sizeof(iwr));
1802         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1803         if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
1804                 perror("ioctl[SIOCGIWMODE]");
1805                 iwr.u.mode = IW_MODE_INFRA;
1806         }
1807
1808         if (iwr.u.mode == IW_MODE_INFRA) {
1809                 if (drv->cfg80211) {
1810                         /*
1811                          * cfg80211 supports SIOCSIWMLME commands, so there is
1812                          * no need for the random SSID hack, but clear the
1813                          * BSSID and SSID.
1814                          */
1815                         if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0 ||
1816                             wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) {
1817                                 wpa_printf(MSG_DEBUG, "WEXT: Failed to clear "
1818                                            "to disconnect");
1819                         }
1820                         return;
1821                 }
1822                 /*
1823                  * Clear the BSSID selection and set a random SSID to make sure
1824                  * the driver will not be trying to associate with something
1825                  * even if it does not understand SIOCSIWMLME commands (or
1826                  * tries to associate automatically after deauth/disassoc).
1827                  */
1828                 for (i = 0; i < 32; i++)
1829                         ssid[i] = rand() & 0xFF;
1830                 if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0 ||
1831                     wpa_driver_wext_set_ssid(drv, ssid, 32) < 0) {
1832                         wpa_printf(MSG_DEBUG, "WEXT: Failed to set bogus "
1833                                    "BSSID/SSID to disconnect");
1834                 }
1835         }
1836 }
1837
1838
1839 static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr,
1840                                           int reason_code)
1841 {
1842         struct wpa_driver_wext_data *drv = priv;
1843         int ret;
1844         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1845         ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
1846         wpa_driver_wext_disconnect(drv);
1847         return ret;
1848 }
1849
1850
1851 static int wpa_driver_wext_disassociate(void *priv, const u8 *addr,
1852                                         int reason_code)
1853 {
1854         struct wpa_driver_wext_data *drv = priv;
1855         int ret;
1856         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1857         ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
1858         wpa_driver_wext_disconnect(drv);
1859         return ret;
1860 }
1861
1862
1863 static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie,
1864                                       size_t ie_len)
1865 {
1866         struct wpa_driver_wext_data *drv = priv;
1867         struct iwreq iwr;
1868         int ret = 0;
1869
1870         os_memset(&iwr, 0, sizeof(iwr));
1871         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1872         iwr.u.data.pointer = (caddr_t) ie;
1873         iwr.u.data.length = ie_len;
1874
1875         if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
1876                 perror("ioctl[SIOCSIWGENIE]");
1877                 ret = -1;
1878         }
1879
1880         return ret;
1881 }
1882
1883
1884 int wpa_driver_wext_cipher2wext(int cipher)
1885 {
1886         switch (cipher) {
1887         case CIPHER_NONE:
1888                 return IW_AUTH_CIPHER_NONE;
1889         case CIPHER_WEP40:
1890                 return IW_AUTH_CIPHER_WEP40;
1891         case CIPHER_TKIP:
1892                 return IW_AUTH_CIPHER_TKIP;
1893         case CIPHER_CCMP:
1894                 return IW_AUTH_CIPHER_CCMP;
1895         case CIPHER_WEP104:
1896                 return IW_AUTH_CIPHER_WEP104;
1897         default:
1898                 return 0;
1899         }
1900 }
1901
1902
1903 int wpa_driver_wext_keymgmt2wext(int keymgmt)
1904 {
1905         switch (keymgmt) {
1906         case KEY_MGMT_802_1X:
1907         case KEY_MGMT_802_1X_NO_WPA:
1908                 return IW_AUTH_KEY_MGMT_802_1X;
1909         case KEY_MGMT_PSK:
1910                 return IW_AUTH_KEY_MGMT_PSK;
1911         default:
1912                 return 0;
1913         }
1914 }
1915
1916
1917 static int
1918 wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv,
1919                                   struct wpa_driver_associate_params *params)
1920 {
1921         struct iwreq iwr;
1922         int ret = 0;
1923
1924         wpa_printf(MSG_DEBUG, "WEXT: Driver did not support "
1925                    "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE");
1926
1927         os_memset(&iwr, 0, sizeof(iwr));
1928         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1929         /* Just changing mode, not actual keys */
1930         iwr.u.encoding.flags = 0;
1931         iwr.u.encoding.pointer = (caddr_t) NULL;
1932         iwr.u.encoding.length = 0;
1933
1934         /*
1935          * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two
1936          * different things. Here they are used to indicate Open System vs.
1937          * Shared Key authentication algorithm. However, some drivers may use
1938          * them to select between open/restricted WEP encrypted (open = allow
1939          * both unencrypted and encrypted frames; restricted = only allow
1940          * encrypted frames).
1941          */
1942
1943         if (!drv->use_crypt) {
1944                 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1945         } else {
1946                 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
1947                         iwr.u.encoding.flags |= IW_ENCODE_OPEN;
1948                 if (params->auth_alg & WPA_AUTH_ALG_SHARED)
1949                         iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED;
1950         }
1951
1952         if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
1953                 perror("ioctl[SIOCSIWENCODE]");
1954                 ret = -1;
1955         }
1956
1957         return ret;
1958 }
1959
1960
1961 int wpa_driver_wext_associate(void *priv,
1962                               struct wpa_driver_associate_params *params)
1963 {
1964         struct wpa_driver_wext_data *drv = priv;
1965         int ret = 0;
1966         int allow_unencrypted_eapol;
1967         int value;
1968
1969         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1970
1971         if (drv->cfg80211) {
1972                 /*
1973                  * Stop cfg80211 from trying to associate before we are done
1974                  * with all parameters.
1975                  */
1976                 wpa_driver_wext_set_ssid(drv, (u8 *) "", 0);
1977         }
1978
1979         if (wpa_driver_wext_set_drop_unencrypted(drv, params->drop_unencrypted)
1980             < 0)
1981                 ret = -1;
1982         if (wpa_driver_wext_set_auth_alg(drv, params->auth_alg) < 0)
1983                 ret = -1;
1984         if (wpa_driver_wext_set_mode(drv, params->mode) < 0)
1985                 ret = -1;
1986
1987         /*
1988          * If the driver did not support SIOCSIWAUTH, fallback to
1989          * SIOCSIWENCODE here.
1990          */
1991         if (drv->auth_alg_fallback &&
1992             wpa_driver_wext_auth_alg_fallback(drv, params) < 0)
1993                 ret = -1;
1994
1995         if (!params->bssid &&
1996             wpa_driver_wext_set_bssid(drv, NULL) < 0)
1997                 ret = -1;
1998
1999         /* TODO: should consider getting wpa version and cipher/key_mgmt suites
2000          * from configuration, not from here, where only the selected suite is
2001          * available */
2002         if (wpa_driver_wext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len)
2003             < 0)
2004                 ret = -1;
2005         if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
2006                 value = IW_AUTH_WPA_VERSION_DISABLED;
2007         else if (params->wpa_ie[0] == WLAN_EID_RSN)
2008                 value = IW_AUTH_WPA_VERSION_WPA2;
2009         else
2010                 value = IW_AUTH_WPA_VERSION_WPA;
2011         if (wpa_driver_wext_set_auth_param(drv,
2012                                            IW_AUTH_WPA_VERSION, value) < 0)
2013                 ret = -1;
2014         value = wpa_driver_wext_cipher2wext(params->pairwise_suite);
2015         if (wpa_driver_wext_set_auth_param(drv,
2016                                            IW_AUTH_CIPHER_PAIRWISE, value) < 0)
2017                 ret = -1;
2018         value = wpa_driver_wext_cipher2wext(params->group_suite);
2019         if (wpa_driver_wext_set_auth_param(drv,
2020                                            IW_AUTH_CIPHER_GROUP, value) < 0)
2021                 ret = -1;
2022         value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite);
2023         if (wpa_driver_wext_set_auth_param(drv,
2024                                            IW_AUTH_KEY_MGMT, value) < 0)
2025                 ret = -1;
2026         value = params->key_mgmt_suite != KEY_MGMT_NONE ||
2027                 params->pairwise_suite != CIPHER_NONE ||
2028                 params->group_suite != CIPHER_NONE ||
2029                 params->wpa_ie_len;
2030         if (wpa_driver_wext_set_auth_param(drv,
2031                                            IW_AUTH_PRIVACY_INVOKED, value) < 0)
2032                 ret = -1;
2033
2034         /* Allow unencrypted EAPOL messages even if pairwise keys are set when
2035          * not using WPA. IEEE 802.1X specifies that these frames are not
2036          * encrypted, but WPA encrypts them when pairwise keys are in use. */
2037         if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
2038             params->key_mgmt_suite == KEY_MGMT_PSK)
2039                 allow_unencrypted_eapol = 0;
2040         else
2041                 allow_unencrypted_eapol = 1;
2042
2043         if (wpa_driver_wext_set_psk(drv, params->psk) < 0)
2044                 ret = -1;
2045         if (wpa_driver_wext_set_auth_param(drv,
2046                                            IW_AUTH_RX_UNENCRYPTED_EAPOL,
2047                                            allow_unencrypted_eapol) < 0)
2048                 ret = -1;
2049 #ifdef CONFIG_IEEE80211W
2050         switch (params->mgmt_frame_protection) {
2051         case NO_MGMT_FRAME_PROTECTION:
2052                 value = IW_AUTH_MFP_DISABLED;
2053                 break;
2054         case MGMT_FRAME_PROTECTION_OPTIONAL:
2055                 value = IW_AUTH_MFP_OPTIONAL;
2056                 break;
2057         case MGMT_FRAME_PROTECTION_REQUIRED:
2058                 value = IW_AUTH_MFP_REQUIRED;
2059                 break;
2060         };
2061         if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0)
2062                 ret = -1;
2063 #endif /* CONFIG_IEEE80211W */
2064         if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
2065                 ret = -1;
2066         if (!drv->cfg80211 &&
2067             wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
2068                 ret = -1;
2069         if (params->bssid &&
2070             wpa_driver_wext_set_bssid(drv, params->bssid) < 0)
2071                 ret = -1;
2072         if (drv->cfg80211 &&
2073             wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
2074                 ret = -1;
2075
2076         return ret;
2077 }
2078
2079
2080 static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg)
2081 {
2082         struct wpa_driver_wext_data *drv = priv;
2083         int algs = 0, res;
2084
2085         if (auth_alg & WPA_AUTH_ALG_OPEN)
2086                 algs |= IW_AUTH_ALG_OPEN_SYSTEM;
2087         if (auth_alg & WPA_AUTH_ALG_SHARED)
2088                 algs |= IW_AUTH_ALG_SHARED_KEY;
2089         if (auth_alg & WPA_AUTH_ALG_LEAP)
2090                 algs |= IW_AUTH_ALG_LEAP;
2091         if (algs == 0) {
2092                 /* at least one algorithm should be set */
2093                 algs = IW_AUTH_ALG_OPEN_SYSTEM;
2094         }
2095
2096         res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG,
2097                                              algs);
2098         drv->auth_alg_fallback = res == -2;
2099         return res;
2100 }
2101
2102
2103 /**
2104  * wpa_driver_wext_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE
2105  * @priv: Pointer to private wext data from wpa_driver_wext_init()
2106  * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS
2107  * Returns: 0 on success, -1 on failure
2108  */
2109 int wpa_driver_wext_set_mode(void *priv, int mode)
2110 {
2111         struct wpa_driver_wext_data *drv = priv;
2112         struct iwreq iwr;
2113         int ret = -1;
2114         unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
2115
2116         os_memset(&iwr, 0, sizeof(iwr));
2117         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2118         iwr.u.mode = new_mode;
2119         if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) == 0) {
2120                 ret = 0;
2121                 goto done;
2122         }
2123
2124         if (errno != EBUSY) {
2125                 perror("ioctl[SIOCSIWMODE]");
2126                 goto done;
2127         }
2128
2129         /* mac80211 doesn't allow mode changes while the device is up, so if
2130          * the device isn't in the mode we're about to change to, take device
2131          * down, try to set the mode again, and bring it back up.
2132          */
2133         if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
2134                 perror("ioctl[SIOCGIWMODE]");
2135                 goto done;
2136         }
2137
2138         if (iwr.u.mode == new_mode) {
2139                 ret = 0;
2140                 goto done;
2141         }
2142
2143         if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) {
2144                 /* Try to set the mode again while the interface is down */
2145                 iwr.u.mode = new_mode;
2146                 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0)
2147                         perror("ioctl[SIOCSIWMODE]");
2148                 else
2149                         ret = 0;
2150
2151                 (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
2152         }
2153
2154 done:
2155         return ret;
2156 }
2157
2158
2159 static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv,
2160                                  u32 cmd, const u8 *bssid, const u8 *pmkid)
2161 {
2162         struct iwreq iwr;
2163         struct iw_pmksa pmksa;
2164         int ret = 0;
2165
2166         os_memset(&iwr, 0, sizeof(iwr));
2167         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2168         os_memset(&pmksa, 0, sizeof(pmksa));
2169         pmksa.cmd = cmd;
2170         pmksa.bssid.sa_family = ARPHRD_ETHER;
2171         if (bssid)
2172                 os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN);
2173         if (pmkid)
2174                 os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN);
2175         iwr.u.data.pointer = (caddr_t) &pmksa;
2176         iwr.u.data.length = sizeof(pmksa);
2177
2178         if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {
2179                 if (errno != EOPNOTSUPP)
2180                         perror("ioctl[SIOCSIWPMKSA]");
2181                 ret = -1;
2182         }
2183
2184         return ret;
2185 }
2186
2187
2188 static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid,
2189                                      const u8 *pmkid)
2190 {
2191         struct wpa_driver_wext_data *drv = priv;
2192         return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);
2193 }
2194
2195
2196 static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid,
2197                                         const u8 *pmkid)
2198 {
2199         struct wpa_driver_wext_data *drv = priv;
2200         return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);
2201 }
2202
2203
2204 static int wpa_driver_wext_flush_pmkid(void *priv)
2205 {
2206         struct wpa_driver_wext_data *drv = priv;
2207         return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL);
2208 }
2209
2210
2211 int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa)
2212 {
2213         struct wpa_driver_wext_data *drv = priv;
2214         if (!drv->has_capability)
2215                 return -1;
2216         os_memcpy(capa, &drv->capa, sizeof(*capa));
2217         return 0;
2218 }
2219
2220
2221 int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv,
2222                                         const char *ifname)
2223 {
2224         if (ifname == NULL) {
2225                 drv->ifindex2 = -1;
2226                 return 0;
2227         }
2228
2229         drv->ifindex2 = if_nametoindex(ifname);
2230         if (drv->ifindex2 <= 0)
2231                 return -1;
2232
2233         wpa_printf(MSG_DEBUG, "Added alternative ifindex %d (%s) for "
2234                    "wireless events", drv->ifindex2, ifname);
2235
2236         return 0;
2237 }
2238
2239
2240 int wpa_driver_wext_set_operstate(void *priv, int state)
2241 {
2242         struct wpa_driver_wext_data *drv = priv;
2243
2244         wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
2245                    __func__, drv->operstate, state, state ? "UP" : "DORMANT");
2246         drv->operstate = state;
2247         return netlink_send_oper_ifla(drv->netlink, drv->ifindex, -1,
2248                                       state ? IF_OPER_UP : IF_OPER_DORMANT);
2249 }
2250
2251
2252 int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv)
2253 {
2254         return drv->we_version_compiled;
2255 }
2256
2257
2258 const struct wpa_driver_ops wpa_driver_wext_ops = {
2259         .name = "wext",
2260         .desc = "Linux wireless extensions (generic)",
2261         .get_bssid = wpa_driver_wext_get_bssid,
2262         .get_ssid = wpa_driver_wext_get_ssid,
2263         .set_key = wpa_driver_wext_set_key,
2264         .set_countermeasures = wpa_driver_wext_set_countermeasures,
2265         .scan2 = wpa_driver_wext_scan,
2266         .get_scan_results2 = wpa_driver_wext_get_scan_results,
2267         .deauthenticate = wpa_driver_wext_deauthenticate,
2268         .disassociate = wpa_driver_wext_disassociate,
2269         .associate = wpa_driver_wext_associate,
2270         .init = wpa_driver_wext_init,
2271         .deinit = wpa_driver_wext_deinit,
2272         .add_pmkid = wpa_driver_wext_add_pmkid,
2273         .remove_pmkid = wpa_driver_wext_remove_pmkid,
2274         .flush_pmkid = wpa_driver_wext_flush_pmkid,
2275         .get_capa = wpa_driver_wext_get_capa,
2276         .set_operstate = wpa_driver_wext_set_operstate,
2277 };