Fix memory leak on rfkill init error path
[libeap.git] / 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          * Some drivers send the association event before the operup event--in
640          * this case, lifting operstate in wpa_driver_wext_set_operstate()
641          * fails. This will hit us when wpa_supplicant does not need to do
642          * IEEE 802.1X authentication
643          */
644         if (drv->operstate == 1 &&
645             (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
646             !(ifi->ifi_flags & IFF_RUNNING))
647                 netlink_send_oper_ifla(drv->netlink, drv->ifindex,
648                                        -1, IF_OPER_UP);
649
650         attrlen = len;
651         attr = (struct rtattr *) buf;
652
653         rta_len = RTA_ALIGN(sizeof(struct rtattr));
654         while (RTA_OK(attr, attrlen)) {
655                 if (attr->rta_type == IFLA_WIRELESS) {
656                         wpa_driver_wext_event_wireless(
657                                 drv, ((char *) attr) + rta_len,
658                                 attr->rta_len - rta_len);
659                 } else if (attr->rta_type == IFLA_IFNAME) {
660                         wpa_driver_wext_event_link(drv,
661                                                    ((char *) attr) + rta_len,
662                                                    attr->rta_len - rta_len, 0);
663                 }
664                 attr = RTA_NEXT(attr, attrlen);
665         }
666 }
667
668
669 static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi,
670                                               u8 *buf, size_t len)
671 {
672         struct wpa_driver_wext_data *drv = ctx;
673         int attrlen, rta_len;
674         struct rtattr *attr;
675
676         attrlen = len;
677         attr = (struct rtattr *) buf;
678
679         rta_len = RTA_ALIGN(sizeof(struct rtattr));
680         while (RTA_OK(attr, attrlen)) {
681                 if (attr->rta_type == IFLA_IFNAME) {
682                         wpa_driver_wext_event_link(drv,
683                                                    ((char *) attr) + rta_len,
684                                                    attr->rta_len - rta_len, 1);
685                 }
686                 attr = RTA_NEXT(attr, attrlen);
687         }
688 }
689
690
691 static void wpa_driver_wext_rfkill_blocked(void *ctx)
692 {
693         struct wpa_driver_wext_data *drv = ctx;
694         wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked");
695         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
696 }
697
698
699 static void wpa_driver_wext_rfkill_unblocked(void *ctx)
700 {
701         struct wpa_driver_wext_data *drv = ctx;
702         wpa_printf(MSG_DEBUG, "WEXT: RFKILL unblocked");
703         if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)) {
704                 wpa_printf(MSG_DEBUG, "WEXT: Could not set interface UP "
705                            "after rfkill unblock");
706                 return;
707         }
708         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
709 }
710
711
712 /**
713  * wpa_driver_wext_init - Initialize WE driver interface
714  * @ctx: context to be used when calling wpa_supplicant functions,
715  * e.g., wpa_supplicant_event()
716  * @ifname: interface name, e.g., wlan0
717  * Returns: Pointer to private data, %NULL on failure
718  */
719 void * wpa_driver_wext_init(void *ctx, const char *ifname)
720 {
721         struct wpa_driver_wext_data *drv;
722         struct netlink_config *cfg;
723         struct rfkill_config *rcfg;
724         char path[128];
725         struct stat buf;
726
727         drv = os_zalloc(sizeof(*drv));
728         if (drv == NULL)
729                 return NULL;
730         drv->ctx = ctx;
731         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
732
733         os_snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", ifname);
734         if (stat(path, &buf) == 0) {
735                 wpa_printf(MSG_DEBUG, "WEXT: cfg80211-based driver detected");
736                 drv->cfg80211 = 1;
737         }
738
739         drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
740         if (drv->ioctl_sock < 0) {
741                 perror("socket(PF_INET,SOCK_DGRAM)");
742                 goto err1;
743         }
744
745         cfg = os_zalloc(sizeof(*cfg));
746         if (cfg == NULL)
747                 goto err1;
748         cfg->ctx = drv;
749         cfg->newlink_cb = wpa_driver_wext_event_rtm_newlink;
750         cfg->dellink_cb = wpa_driver_wext_event_rtm_dellink;
751         drv->netlink = netlink_init(cfg);
752         if (drv->netlink == NULL) {
753                 os_free(cfg);
754                 goto err2;
755         }
756
757         rcfg = os_zalloc(sizeof(*rcfg));
758         if (rcfg == NULL)
759                 goto err3;
760         rcfg->ctx = drv;
761         os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
762         rcfg->blocked_cb = wpa_driver_wext_rfkill_blocked;
763         rcfg->unblocked_cb = wpa_driver_wext_rfkill_unblocked;
764         drv->rfkill = rfkill_init(rcfg);
765         if (drv->rfkill == NULL) {
766                 wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not available");
767                 os_free(rcfg);
768         }
769
770         drv->mlme_sock = -1;
771
772         if (wpa_driver_wext_finish_drv_init(drv) < 0)
773                 goto err3;
774
775         wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 1);
776
777         return drv;
778
779 err3:
780         rfkill_deinit(drv->rfkill);
781         netlink_deinit(drv->netlink);
782 err2:
783         close(drv->ioctl_sock);
784 err1:
785         os_free(drv);
786         return NULL;
787 }
788
789
790 static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx)
791 {
792         wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
793 }
794
795
796 static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
797 {
798         int send_rfkill_event = 0;
799
800         if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) {
801                 if (rfkill_is_blocked(drv->rfkill)) {
802                         wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable "
803                                    "interface '%s' due to rfkill",
804                                    drv->ifname);
805                         send_rfkill_event = 1;
806                 } else {
807                         wpa_printf(MSG_ERROR, "WEXT: Could not set "
808                                    "interface '%s' UP", drv->ifname);
809                         return -1;
810                 }
811         }
812
813         /*
814          * Make sure that the driver does not have any obsolete PMKID entries.
815          */
816         wpa_driver_wext_flush_pmkid(drv);
817
818         if (wpa_driver_wext_set_mode(drv, 0) < 0) {
819                 wpa_printf(MSG_DEBUG, "Could not configure driver to use "
820                            "managed mode");
821                 /* Try to use it anyway */
822         }
823
824         wpa_driver_wext_get_range(drv);
825
826         /*
827          * Unlock the driver's BSSID and force to a random SSID to clear any
828          * previous association the driver might have when the supplicant
829          * starts up.
830          */
831         wpa_driver_wext_disconnect(drv);
832
833         drv->ifindex = if_nametoindex(drv->ifname);
834
835         if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
836                 /*
837                  * Host AP driver may use both wlan# and wifi# interface in
838                  * wireless events. Since some of the versions included WE-18
839                  * support, let's add the alternative ifindex also from
840                  * driver_wext.c for the time being. This may be removed at
841                  * some point once it is believed that old versions of the
842                  * driver are not in use anymore.
843                  */
844                 char ifname2[IFNAMSIZ + 1];
845                 os_strlcpy(ifname2, drv->ifname, sizeof(ifname2));
846                 os_memcpy(ifname2, "wifi", 4);
847                 wpa_driver_wext_alternative_ifindex(drv, ifname2);
848         }
849
850         netlink_send_oper_ifla(drv->netlink, drv->ifindex,
851                                1, IF_OPER_DORMANT);
852
853         if (send_rfkill_event) {
854                 eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill,
855                                        drv, drv->ctx);
856         }
857
858         return 0;
859 }
860
861
862 /**
863  * wpa_driver_wext_deinit - Deinitialize WE driver interface
864  * @priv: Pointer to private wext data from wpa_driver_wext_init()
865  *
866  * Shut down driver interface and processing of driver events. Free
867  * private data buffer if one was allocated in wpa_driver_wext_init().
868  */
869 void wpa_driver_wext_deinit(void *priv)
870 {
871         struct wpa_driver_wext_data *drv = priv;
872
873         wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 0);
874
875         eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
876
877         /*
878          * Clear possibly configured driver parameters in order to make it
879          * easier to use the driver after wpa_supplicant has been terminated.
880          */
881         wpa_driver_wext_disconnect(drv);
882
883         netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP);
884         netlink_deinit(drv->netlink);
885         rfkill_deinit(drv->rfkill);
886
887         if (drv->mlme_sock >= 0)
888                 eloop_unregister_read_sock(drv->mlme_sock);
889
890         (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
891
892         close(drv->ioctl_sock);
893         if (drv->mlme_sock >= 0)
894                 close(drv->mlme_sock);
895         os_free(drv->assoc_req_ies);
896         os_free(drv->assoc_resp_ies);
897         os_free(drv);
898 }
899
900
901 /**
902  * wpa_driver_wext_scan_timeout - Scan timeout to report scan completion
903  * @eloop_ctx: Unused
904  * @timeout_ctx: ctx argument given to wpa_driver_wext_init()
905  *
906  * This function can be used as registered timeout when starting a scan to
907  * generate a scan completed event if the driver does not report this.
908  */
909 void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx)
910 {
911         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
912         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
913 }
914
915
916 /**
917  * wpa_driver_wext_scan - Request the driver to initiate scan
918  * @priv: Pointer to private wext data from wpa_driver_wext_init()
919  * @param: Scan parameters (specific SSID to scan for (ProbeReq), etc.)
920  * Returns: 0 on success, -1 on failure
921  */
922 int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params)
923 {
924         struct wpa_driver_wext_data *drv = priv;
925         struct iwreq iwr;
926         int ret = 0, timeout;
927         struct iw_scan_req req;
928         const u8 *ssid = params->ssids[0].ssid;
929         size_t ssid_len = params->ssids[0].ssid_len;
930
931         if (ssid_len > IW_ESSID_MAX_SIZE) {
932                 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
933                            __FUNCTION__, (unsigned long) ssid_len);
934                 return -1;
935         }
936
937         os_memset(&iwr, 0, sizeof(iwr));
938         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
939
940         if (ssid && ssid_len) {
941                 os_memset(&req, 0, sizeof(req));
942                 req.essid_len = ssid_len;
943                 req.bssid.sa_family = ARPHRD_ETHER;
944                 os_memset(req.bssid.sa_data, 0xff, ETH_ALEN);
945                 os_memcpy(req.essid, ssid, ssid_len);
946                 iwr.u.data.pointer = (caddr_t) &req;
947                 iwr.u.data.length = sizeof(req);
948                 iwr.u.data.flags = IW_SCAN_THIS_ESSID;
949         }
950
951         if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
952                 perror("ioctl[SIOCSIWSCAN]");
953                 ret = -1;
954         }
955
956         /* Not all drivers generate "scan completed" wireless event, so try to
957          * read results after a timeout. */
958         timeout = 5;
959         if (drv->scan_complete_events) {
960                 /*
961                  * The driver seems to deliver SIOCGIWSCAN events to notify
962                  * when scan is complete, so use longer timeout to avoid race
963                  * conditions with scanning and following association request.
964                  */
965                 timeout = 30;
966         }
967         wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
968                    "seconds", ret, timeout);
969         eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
970         eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
971                                drv->ctx);
972
973         return ret;
974 }
975
976
977 static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv,
978                                     size_t *len)
979 {
980         struct iwreq iwr;
981         u8 *res_buf;
982         size_t res_buf_len;
983
984         res_buf_len = IW_SCAN_MAX_DATA;
985         for (;;) {
986                 res_buf = os_malloc(res_buf_len);
987                 if (res_buf == NULL)
988                         return NULL;
989                 os_memset(&iwr, 0, sizeof(iwr));
990                 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
991                 iwr.u.data.pointer = res_buf;
992                 iwr.u.data.length = res_buf_len;
993
994                 if (ioctl(drv->ioctl_sock, SIOCGIWSCAN, &iwr) == 0)
995                         break;
996
997                 if (errno == E2BIG && res_buf_len < 65535) {
998                         os_free(res_buf);
999                         res_buf = NULL;
1000                         res_buf_len *= 2;
1001                         if (res_buf_len > 65535)
1002                                 res_buf_len = 65535; /* 16-bit length field */
1003                         wpa_printf(MSG_DEBUG, "Scan results did not fit - "
1004                                    "trying larger buffer (%lu bytes)",
1005                                    (unsigned long) res_buf_len);
1006                 } else {
1007                         perror("ioctl[SIOCGIWSCAN]");
1008                         os_free(res_buf);
1009                         return NULL;
1010                 }
1011         }
1012
1013         if (iwr.u.data.length > res_buf_len) {
1014                 os_free(res_buf);
1015                 return NULL;
1016         }
1017         *len = iwr.u.data.length;
1018
1019         return res_buf;
1020 }
1021
1022
1023 /*
1024  * Data structure for collecting WEXT scan results. This is needed to allow
1025  * the various methods of reporting IEs to be combined into a single IE buffer.
1026  */
1027 struct wext_scan_data {
1028         struct wpa_scan_res res;
1029         u8 *ie;
1030         size_t ie_len;
1031         u8 ssid[32];
1032         size_t ssid_len;
1033         int maxrate;
1034 };
1035
1036
1037 static void wext_get_scan_mode(struct iw_event *iwe,
1038                                struct wext_scan_data *res)
1039 {
1040         if (iwe->u.mode == IW_MODE_ADHOC)
1041                 res->res.caps |= IEEE80211_CAP_IBSS;
1042         else if (iwe->u.mode == IW_MODE_MASTER || iwe->u.mode == IW_MODE_INFRA)
1043                 res->res.caps |= IEEE80211_CAP_ESS;
1044 }
1045
1046
1047 static void wext_get_scan_ssid(struct iw_event *iwe,
1048                                struct wext_scan_data *res, char *custom,
1049                                char *end)
1050 {
1051         int ssid_len = iwe->u.essid.length;
1052         if (custom + ssid_len > end)
1053                 return;
1054         if (iwe->u.essid.flags &&
1055             ssid_len > 0 &&
1056             ssid_len <= IW_ESSID_MAX_SIZE) {
1057                 os_memcpy(res->ssid, custom, ssid_len);
1058                 res->ssid_len = ssid_len;
1059         }
1060 }
1061
1062
1063 static void wext_get_scan_freq(struct iw_event *iwe,
1064                                struct wext_scan_data *res)
1065 {
1066         int divi = 1000000, i;
1067
1068         if (iwe->u.freq.e == 0) {
1069                 /*
1070                  * Some drivers do not report frequency, but a channel.
1071                  * Try to map this to frequency by assuming they are using
1072                  * IEEE 802.11b/g.  But don't overwrite a previously parsed
1073                  * frequency if the driver sends both frequency and channel,
1074                  * since the driver may be sending an A-band channel that we
1075                  * don't handle here.
1076                  */
1077
1078                 if (res->res.freq)
1079                         return;
1080
1081                 if (iwe->u.freq.m >= 1 && iwe->u.freq.m <= 13) {
1082                         res->res.freq = 2407 + 5 * iwe->u.freq.m;
1083                         return;
1084                 } else if (iwe->u.freq.m == 14) {
1085                         res->res.freq = 2484;
1086                         return;
1087                 }
1088         }
1089
1090         if (iwe->u.freq.e > 6) {
1091                 wpa_printf(MSG_DEBUG, "Invalid freq in scan results (BSSID="
1092                            MACSTR " m=%d e=%d)",
1093                            MAC2STR(res->res.bssid), iwe->u.freq.m,
1094                            iwe->u.freq.e);
1095                 return;
1096         }
1097
1098         for (i = 0; i < iwe->u.freq.e; i++)
1099                 divi /= 10;
1100         res->res.freq = iwe->u.freq.m / divi;
1101 }
1102
1103
1104 static void wext_get_scan_qual(struct iw_event *iwe,
1105                                struct wext_scan_data *res)
1106 {
1107         res->res.qual = iwe->u.qual.qual;
1108         res->res.noise = iwe->u.qual.noise;
1109         res->res.level = iwe->u.qual.level;
1110         if (iwe->u.qual.updated & IW_QUAL_QUAL_INVALID)
1111                 res->res.flags |= WPA_SCAN_QUAL_INVALID;
1112         if (iwe->u.qual.updated & IW_QUAL_LEVEL_INVALID)
1113                 res->res.flags |= WPA_SCAN_LEVEL_INVALID;
1114         if (iwe->u.qual.updated & IW_QUAL_NOISE_INVALID)
1115                 res->res.flags |= WPA_SCAN_NOISE_INVALID;
1116         if (iwe->u.qual.updated & IW_QUAL_DBM)
1117                 res->res.flags |= WPA_SCAN_LEVEL_DBM;
1118 }
1119
1120
1121 static void wext_get_scan_encode(struct iw_event *iwe,
1122                                  struct wext_scan_data *res)
1123 {
1124         if (!(iwe->u.data.flags & IW_ENCODE_DISABLED))
1125                 res->res.caps |= IEEE80211_CAP_PRIVACY;
1126 }
1127
1128
1129 static void wext_get_scan_rate(struct iw_event *iwe,
1130                                struct wext_scan_data *res, char *pos,
1131                                char *end)
1132 {
1133         int maxrate;
1134         char *custom = pos + IW_EV_LCP_LEN;
1135         struct iw_param p;
1136         size_t clen;
1137
1138         clen = iwe->len;
1139         if (custom + clen > end)
1140                 return;
1141         maxrate = 0;
1142         while (((ssize_t) clen) >= (ssize_t) sizeof(struct iw_param)) {
1143                 /* Note: may be misaligned, make a local, aligned copy */
1144                 os_memcpy(&p, custom, sizeof(struct iw_param));
1145                 if (p.value > maxrate)
1146                         maxrate = p.value;
1147                 clen -= sizeof(struct iw_param);
1148                 custom += sizeof(struct iw_param);
1149         }
1150
1151         /* Convert the maxrate from WE-style (b/s units) to
1152          * 802.11 rates (500000 b/s units).
1153          */
1154         res->maxrate = maxrate / 500000;
1155 }
1156
1157
1158 static void wext_get_scan_iwevgenie(struct iw_event *iwe,
1159                                     struct wext_scan_data *res, char *custom,
1160                                     char *end)
1161 {
1162         char *genie, *gpos, *gend;
1163         u8 *tmp;
1164
1165         if (iwe->u.data.length == 0)
1166                 return;
1167
1168         gpos = genie = custom;
1169         gend = genie + iwe->u.data.length;
1170         if (gend > end) {
1171                 wpa_printf(MSG_INFO, "IWEVGENIE overflow");
1172                 return;
1173         }
1174
1175         tmp = os_realloc(res->ie, res->ie_len + gend - gpos);
1176         if (tmp == NULL)
1177                 return;
1178         os_memcpy(tmp + res->ie_len, gpos, gend - gpos);
1179         res->ie = tmp;
1180         res->ie_len += gend - gpos;
1181 }
1182
1183
1184 static void wext_get_scan_custom(struct iw_event *iwe,
1185                                  struct wext_scan_data *res, char *custom,
1186                                  char *end)
1187 {
1188         size_t clen;
1189         u8 *tmp;
1190
1191         clen = iwe->u.data.length;
1192         if (custom + clen > end)
1193                 return;
1194
1195         if (clen > 7 && os_strncmp(custom, "wpa_ie=", 7) == 0) {
1196                 char *spos;
1197                 int bytes;
1198                 spos = custom + 7;
1199                 bytes = custom + clen - spos;
1200                 if (bytes & 1 || bytes == 0)
1201                         return;
1202                 bytes /= 2;
1203                 tmp = os_realloc(res->ie, res->ie_len + bytes);
1204                 if (tmp == NULL)
1205                         return;
1206                 res->ie = tmp;
1207                 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0)
1208                         return;
1209                 res->ie_len += bytes;
1210         } else if (clen > 7 && os_strncmp(custom, "rsn_ie=", 7) == 0) {
1211                 char *spos;
1212                 int bytes;
1213                 spos = custom + 7;
1214                 bytes = custom + clen - spos;
1215                 if (bytes & 1 || bytes == 0)
1216                         return;
1217                 bytes /= 2;
1218                 tmp = os_realloc(res->ie, res->ie_len + bytes);
1219                 if (tmp == NULL)
1220                         return;
1221                 res->ie = tmp;
1222                 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0)
1223                         return;
1224                 res->ie_len += bytes;
1225         } else if (clen > 4 && os_strncmp(custom, "tsf=", 4) == 0) {
1226                 char *spos;
1227                 int bytes;
1228                 u8 bin[8];
1229                 spos = custom + 4;
1230                 bytes = custom + clen - spos;
1231                 if (bytes != 16) {
1232                         wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes);
1233                         return;
1234                 }
1235                 bytes /= 2;
1236                 if (hexstr2bin(spos, bin, bytes) < 0) {
1237                         wpa_printf(MSG_DEBUG, "WEXT: Invalid TSF value");
1238                         return;
1239                 }
1240                 res->res.tsf += WPA_GET_BE64(bin);
1241         }
1242 }
1243
1244
1245 static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd)
1246 {
1247         return drv->we_version_compiled > 18 &&
1248                 (cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE ||
1249                  cmd == IWEVGENIE || cmd == IWEVCUSTOM);
1250 }
1251
1252
1253 static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res,
1254                                            struct wext_scan_data *data)
1255 {
1256         struct wpa_scan_res **tmp;
1257         struct wpa_scan_res *r;
1258         size_t extra_len;
1259         u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL;
1260
1261         /* Figure out whether we need to fake any IEs */
1262         pos = data->ie;
1263         end = pos + data->ie_len;
1264         while (pos && pos + 1 < end) {
1265                 if (pos + 2 + pos[1] > end)
1266                         break;
1267                 if (pos[0] == WLAN_EID_SSID)
1268                         ssid_ie = pos;
1269                 else if (pos[0] == WLAN_EID_SUPP_RATES)
1270                         rate_ie = pos;
1271                 else if (pos[0] == WLAN_EID_EXT_SUPP_RATES)
1272                         rate_ie = pos;
1273                 pos += 2 + pos[1];
1274         }
1275
1276         extra_len = 0;
1277         if (ssid_ie == NULL)
1278                 extra_len += 2 + data->ssid_len;
1279         if (rate_ie == NULL && data->maxrate)
1280                 extra_len += 3;
1281
1282         r = os_zalloc(sizeof(*r) + extra_len + data->ie_len);
1283         if (r == NULL)
1284                 return;
1285         os_memcpy(r, &data->res, sizeof(*r));
1286         r->ie_len = extra_len + data->ie_len;
1287         pos = (u8 *) (r + 1);
1288         if (ssid_ie == NULL) {
1289                 /*
1290                  * Generate a fake SSID IE since the driver did not report
1291                  * a full IE list.
1292                  */
1293                 *pos++ = WLAN_EID_SSID;
1294                 *pos++ = data->ssid_len;
1295                 os_memcpy(pos, data->ssid, data->ssid_len);
1296                 pos += data->ssid_len;
1297         }
1298         if (rate_ie == NULL && data->maxrate) {
1299                 /*
1300                  * Generate a fake Supported Rates IE since the driver did not
1301                  * report a full IE list.
1302                  */
1303                 *pos++ = WLAN_EID_SUPP_RATES;
1304                 *pos++ = 1;
1305                 *pos++ = data->maxrate;
1306         }
1307         if (data->ie)
1308                 os_memcpy(pos, data->ie, data->ie_len);
1309
1310         tmp = os_realloc(res->res,
1311                          (res->num + 1) * sizeof(struct wpa_scan_res *));
1312         if (tmp == NULL) {
1313                 os_free(r);
1314                 return;
1315         }
1316         tmp[res->num++] = r;
1317         res->res = tmp;
1318 }
1319                                       
1320
1321 /**
1322  * wpa_driver_wext_get_scan_results - Fetch the latest scan results
1323  * @priv: Pointer to private wext data from wpa_driver_wext_init()
1324  * Returns: Scan results on success, -1 on failure
1325  */
1326 struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv)
1327 {
1328         struct wpa_driver_wext_data *drv = priv;
1329         size_t ap_num = 0, len;
1330         int first;
1331         u8 *res_buf;
1332         struct iw_event iwe_buf, *iwe = &iwe_buf;
1333         char *pos, *end, *custom;
1334         struct wpa_scan_results *res;
1335         struct wext_scan_data data;
1336
1337         res_buf = wpa_driver_wext_giwscan(drv, &len);
1338         if (res_buf == NULL)
1339                 return NULL;
1340
1341         ap_num = 0;
1342         first = 1;
1343
1344         res = os_zalloc(sizeof(*res));
1345         if (res == NULL) {
1346                 os_free(res_buf);
1347                 return NULL;
1348         }
1349
1350         pos = (char *) res_buf;
1351         end = (char *) res_buf + len;
1352         os_memset(&data, 0, sizeof(data));
1353
1354         while (pos + IW_EV_LCP_LEN <= end) {
1355                 /* Event data may be unaligned, so make a local, aligned copy
1356                  * before processing. */
1357                 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
1358                 if (iwe->len <= IW_EV_LCP_LEN)
1359                         break;
1360
1361                 custom = pos + IW_EV_POINT_LEN;
1362                 if (wext_19_iw_point(drv, iwe->cmd)) {
1363                         /* WE-19 removed the pointer from struct iw_point */
1364                         char *dpos = (char *) &iwe_buf.u.data.length;
1365                         int dlen = dpos - (char *) &iwe_buf;
1366                         os_memcpy(dpos, pos + IW_EV_LCP_LEN,
1367                                   sizeof(struct iw_event) - dlen);
1368                 } else {
1369                         os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
1370                         custom += IW_EV_POINT_OFF;
1371                 }
1372
1373                 switch (iwe->cmd) {
1374                 case SIOCGIWAP:
1375                         if (!first)
1376                                 wpa_driver_wext_add_scan_entry(res, &data);
1377                         first = 0;
1378                         os_free(data.ie);
1379                         os_memset(&data, 0, sizeof(data));
1380                         os_memcpy(data.res.bssid,
1381                                   iwe->u.ap_addr.sa_data, ETH_ALEN);
1382                         break;
1383                 case SIOCGIWMODE:
1384                         wext_get_scan_mode(iwe, &data);
1385                         break;
1386                 case SIOCGIWESSID:
1387                         wext_get_scan_ssid(iwe, &data, custom, end);
1388                         break;
1389                 case SIOCGIWFREQ:
1390                         wext_get_scan_freq(iwe, &data);
1391                         break;
1392                 case IWEVQUAL:
1393                         wext_get_scan_qual(iwe, &data);
1394                         break;
1395                 case SIOCGIWENCODE:
1396                         wext_get_scan_encode(iwe, &data);
1397                         break;
1398                 case SIOCGIWRATE:
1399                         wext_get_scan_rate(iwe, &data, pos, end);
1400                         break;
1401                 case IWEVGENIE:
1402                         wext_get_scan_iwevgenie(iwe, &data, custom, end);
1403                         break;
1404                 case IWEVCUSTOM:
1405                         wext_get_scan_custom(iwe, &data, custom, end);
1406                         break;
1407                 }
1408
1409                 pos += iwe->len;
1410         }
1411         os_free(res_buf);
1412         res_buf = NULL;
1413         if (!first)
1414                 wpa_driver_wext_add_scan_entry(res, &data);
1415         os_free(data.ie);
1416
1417         wpa_printf(MSG_DEBUG, "Received %lu bytes of scan results (%lu BSSes)",
1418                    (unsigned long) len, (unsigned long) res->num);
1419
1420         return res;
1421 }
1422
1423
1424 static int wpa_driver_wext_get_range(void *priv)
1425 {
1426         struct wpa_driver_wext_data *drv = priv;
1427         struct iw_range *range;
1428         struct iwreq iwr;
1429         int minlen;
1430         size_t buflen;
1431
1432         /*
1433          * Use larger buffer than struct iw_range in order to allow the
1434          * structure to grow in the future.
1435          */
1436         buflen = sizeof(struct iw_range) + 500;
1437         range = os_zalloc(buflen);
1438         if (range == NULL)
1439                 return -1;
1440
1441         os_memset(&iwr, 0, sizeof(iwr));
1442         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1443         iwr.u.data.pointer = (caddr_t) range;
1444         iwr.u.data.length = buflen;
1445
1446         minlen = ((char *) &range->enc_capa) - (char *) range +
1447                 sizeof(range->enc_capa);
1448
1449         if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
1450                 perror("ioctl[SIOCGIWRANGE]");
1451                 os_free(range);
1452                 return -1;
1453         } else if (iwr.u.data.length >= minlen &&
1454                    range->we_version_compiled >= 18) {
1455                 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
1456                            "WE(source)=%d enc_capa=0x%x",
1457                            range->we_version_compiled,
1458                            range->we_version_source,
1459                            range->enc_capa);
1460                 drv->has_capability = 1;
1461                 drv->we_version_compiled = range->we_version_compiled;
1462                 if (range->enc_capa & IW_ENC_CAPA_WPA) {
1463                         drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1464                                 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
1465                 }
1466                 if (range->enc_capa & IW_ENC_CAPA_WPA2) {
1467                         drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1468                                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1469                 }
1470                 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
1471                         WPA_DRIVER_CAPA_ENC_WEP104;
1472                 if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
1473                         drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
1474                 if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
1475                         drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
1476                 if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
1477                         drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
1478                 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
1479                         WPA_DRIVER_AUTH_SHARED |
1480                         WPA_DRIVER_AUTH_LEAP;
1481                 drv->capa.max_scan_ssids = 1;
1482
1483                 wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
1484                            "flags 0x%x",
1485                            drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);
1486         } else {
1487                 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "
1488                            "assuming WPA is not supported");
1489         }
1490
1491         os_free(range);
1492         return 0;
1493 }
1494
1495
1496 static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
1497                                    const u8 *psk)
1498 {
1499         struct iw_encode_ext *ext;
1500         struct iwreq iwr;
1501         int ret;
1502
1503         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1504
1505         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
1506                 return 0;
1507
1508         if (!psk)
1509                 return 0;
1510
1511         os_memset(&iwr, 0, sizeof(iwr));
1512         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1513
1514         ext = os_zalloc(sizeof(*ext) + PMK_LEN);
1515         if (ext == NULL)
1516                 return -1;
1517
1518         iwr.u.encoding.pointer = (caddr_t) ext;
1519         iwr.u.encoding.length = sizeof(*ext) + PMK_LEN;
1520         ext->key_len = PMK_LEN;
1521         os_memcpy(&ext->key, psk, ext->key_len);
1522         ext->alg = IW_ENCODE_ALG_PMK;
1523
1524         ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr);
1525         if (ret < 0)
1526                 perror("ioctl[SIOCSIWENCODEEXT] PMK");
1527         os_free(ext);
1528
1529         return ret;
1530 }
1531
1532
1533 static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg,
1534                                        const u8 *addr, int key_idx,
1535                                        int set_tx, const u8 *seq,
1536                                        size_t seq_len,
1537                                        const u8 *key, size_t key_len)
1538 {
1539         struct wpa_driver_wext_data *drv = priv;
1540         struct iwreq iwr;
1541         int ret = 0;
1542         struct iw_encode_ext *ext;
1543
1544         if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) {
1545                 wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu",
1546                            __FUNCTION__, (unsigned long) seq_len);
1547                 return -1;
1548         }
1549
1550         ext = os_zalloc(sizeof(*ext) + key_len);
1551         if (ext == NULL)
1552                 return -1;
1553         os_memset(&iwr, 0, sizeof(iwr));
1554         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1555         iwr.u.encoding.flags = key_idx + 1;
1556         iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1557         if (alg == WPA_ALG_NONE)
1558                 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1559         iwr.u.encoding.pointer = (caddr_t) ext;
1560         iwr.u.encoding.length = sizeof(*ext) + key_len;
1561
1562         if (addr == NULL ||
1563             os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
1564                 ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY;
1565         if (set_tx)
1566                 ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY;
1567
1568         ext->addr.sa_family = ARPHRD_ETHER;
1569         if (addr)
1570                 os_memcpy(ext->addr.sa_data, addr, ETH_ALEN);
1571         else
1572                 os_memset(ext->addr.sa_data, 0xff, ETH_ALEN);
1573         if (key && key_len) {
1574                 os_memcpy(ext + 1, key, key_len);
1575                 ext->key_len = key_len;
1576         }
1577         switch (alg) {
1578         case WPA_ALG_NONE:
1579                 ext->alg = IW_ENCODE_ALG_NONE;
1580                 break;
1581         case WPA_ALG_WEP:
1582                 ext->alg = IW_ENCODE_ALG_WEP;
1583                 break;
1584         case WPA_ALG_TKIP:
1585                 ext->alg = IW_ENCODE_ALG_TKIP;
1586                 break;
1587         case WPA_ALG_CCMP:
1588                 ext->alg = IW_ENCODE_ALG_CCMP;
1589                 break;
1590         case WPA_ALG_PMK:
1591                 ext->alg = IW_ENCODE_ALG_PMK;
1592                 break;
1593 #ifdef CONFIG_IEEE80211W
1594         case WPA_ALG_IGTK:
1595                 ext->alg = IW_ENCODE_ALG_AES_CMAC;
1596                 break;
1597 #endif /* CONFIG_IEEE80211W */
1598         default:
1599                 wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
1600                            __FUNCTION__, alg);
1601                 os_free(ext);
1602                 return -1;
1603         }
1604
1605         if (seq && seq_len) {
1606                 ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID;
1607                 os_memcpy(ext->rx_seq, seq, seq_len);
1608         }
1609
1610         if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) {
1611                 ret = errno == EOPNOTSUPP ? -2 : -1;
1612                 if (errno == ENODEV) {
1613                         /*
1614                          * ndiswrapper seems to be returning incorrect error
1615                          * code.. */
1616                         ret = -2;
1617                 }
1618
1619                 perror("ioctl[SIOCSIWENCODEEXT]");
1620         }
1621
1622         os_free(ext);
1623         return ret;
1624 }
1625
1626
1627 /**
1628  * wpa_driver_wext_set_key - Configure encryption key
1629  * @priv: Pointer to private wext data from wpa_driver_wext_init()
1630  * @priv: Private driver interface data
1631  * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP,
1632  *      %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key.
1633  * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for
1634  *      broadcast/default keys
1635  * @key_idx: key index (0..3), usually 0 for unicast keys
1636  * @set_tx: Configure this key as the default Tx key (only used when
1637  *      driver does not support separate unicast/individual key
1638  * @seq: Sequence number/packet number, seq_len octets, the next
1639  *      packet number to be used for in replay protection; configured
1640  *      for Rx keys (in most cases, this is only used with broadcast
1641  *      keys and set to zero for unicast keys)
1642  * @seq_len: Length of the seq, depends on the algorithm:
1643  *      TKIP: 6 octets, CCMP: 6 octets
1644  * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key,
1645  *      8-byte Rx Mic Key
1646  * @key_len: Length of the key buffer in octets (WEP: 5 or 13,
1647  *      TKIP: 32, CCMP: 16)
1648  * Returns: 0 on success, -1 on failure
1649  *
1650  * This function uses SIOCSIWENCODEEXT by default, but tries to use
1651  * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key.
1652  */
1653 int wpa_driver_wext_set_key(const char *ifname, void *priv, enum wpa_alg alg,
1654                             const u8 *addr, int key_idx,
1655                             int set_tx, const u8 *seq, size_t seq_len,
1656                             const u8 *key, size_t key_len)
1657 {
1658         struct wpa_driver_wext_data *drv = priv;
1659         struct iwreq iwr;
1660         int ret = 0;
1661
1662         wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
1663                    "key_len=%lu",
1664                    __FUNCTION__, alg, key_idx, set_tx,
1665                    (unsigned long) seq_len, (unsigned long) key_len);
1666
1667         ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx,
1668                                           seq, seq_len, key, key_len);
1669         if (ret == 0)
1670                 return 0;
1671
1672         if (ret == -2 &&
1673             (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) {
1674                 wpa_printf(MSG_DEBUG, "Driver did not support "
1675                            "SIOCSIWENCODEEXT, trying SIOCSIWENCODE");
1676                 ret = 0;
1677         } else {
1678                 wpa_printf(MSG_DEBUG, "Driver did not support "
1679                            "SIOCSIWENCODEEXT");
1680                 return ret;
1681         }
1682
1683         os_memset(&iwr, 0, sizeof(iwr));
1684         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1685         iwr.u.encoding.flags = key_idx + 1;
1686         iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1687         if (alg == WPA_ALG_NONE)
1688                 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1689         iwr.u.encoding.pointer = (caddr_t) key;
1690         iwr.u.encoding.length = key_len;
1691
1692         if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
1693                 perror("ioctl[SIOCSIWENCODE]");
1694                 ret = -1;
1695         }
1696
1697         if (set_tx && alg != WPA_ALG_NONE) {
1698                 os_memset(&iwr, 0, sizeof(iwr));
1699                 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1700                 iwr.u.encoding.flags = key_idx + 1;
1701                 iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1702                 iwr.u.encoding.pointer = (caddr_t) NULL;
1703                 iwr.u.encoding.length = 0;
1704                 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
1705                         perror("ioctl[SIOCSIWENCODE] (set_tx)");
1706                         ret = -1;
1707                 }
1708         }
1709
1710         return ret;
1711 }
1712
1713
1714 static int wpa_driver_wext_set_countermeasures(void *priv,
1715                                                int enabled)
1716 {
1717         struct wpa_driver_wext_data *drv = priv;
1718         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1719         return wpa_driver_wext_set_auth_param(drv,
1720                                               IW_AUTH_TKIP_COUNTERMEASURES,
1721                                               enabled);
1722 }
1723
1724
1725 static int wpa_driver_wext_set_drop_unencrypted(void *priv,
1726                                                 int enabled)
1727 {
1728         struct wpa_driver_wext_data *drv = priv;
1729         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1730         drv->use_crypt = enabled;
1731         return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
1732                                               enabled);
1733 }
1734
1735
1736 static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv,
1737                                 const u8 *addr, int cmd, int reason_code)
1738 {
1739         struct iwreq iwr;
1740         struct iw_mlme mlme;
1741         int ret = 0;
1742
1743         os_memset(&iwr, 0, sizeof(iwr));
1744         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1745         os_memset(&mlme, 0, sizeof(mlme));
1746         mlme.cmd = cmd;
1747         mlme.reason_code = reason_code;
1748         mlme.addr.sa_family = ARPHRD_ETHER;
1749         os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
1750         iwr.u.data.pointer = (caddr_t) &mlme;
1751         iwr.u.data.length = sizeof(mlme);
1752
1753         if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
1754                 perror("ioctl[SIOCSIWMLME]");
1755                 ret = -1;
1756         }
1757
1758         return ret;
1759 }
1760
1761
1762 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
1763 {
1764         struct iwreq iwr;
1765         const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
1766         u8 ssid[32];
1767         int i;
1768
1769         /*
1770          * Only force-disconnect when the card is in infrastructure mode,
1771          * otherwise the driver might interpret the cleared BSSID and random
1772          * SSID as an attempt to create a new ad-hoc network.
1773          */
1774         os_memset(&iwr, 0, sizeof(iwr));
1775         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1776         if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
1777                 perror("ioctl[SIOCGIWMODE]");
1778                 iwr.u.mode = IW_MODE_INFRA;
1779         }
1780
1781         if (iwr.u.mode == IW_MODE_INFRA) {
1782                 if (drv->cfg80211) {
1783                         /*
1784                          * cfg80211 supports SIOCSIWMLME commands, so there is
1785                          * no need for the random SSID hack, but clear the
1786                          * BSSID and SSID.
1787                          */
1788                         if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0 ||
1789                             wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) {
1790                                 wpa_printf(MSG_DEBUG, "WEXT: Failed to clear "
1791                                            "to disconnect");
1792                         }
1793                         return;
1794                 }
1795                 /*
1796                  * Clear the BSSID selection and set a random SSID to make sure
1797                  * the driver will not be trying to associate with something
1798                  * even if it does not understand SIOCSIWMLME commands (or
1799                  * tries to associate automatically after deauth/disassoc).
1800                  */
1801                 for (i = 0; i < 32; i++)
1802                         ssid[i] = rand() & 0xFF;
1803                 if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0 ||
1804                     wpa_driver_wext_set_ssid(drv, ssid, 32) < 0) {
1805                         wpa_printf(MSG_DEBUG, "WEXT: Failed to set bogus "
1806                                    "BSSID/SSID to disconnect");
1807                 }
1808         }
1809 }
1810
1811
1812 static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr,
1813                                           int reason_code)
1814 {
1815         struct wpa_driver_wext_data *drv = priv;
1816         int ret;
1817         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1818         ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
1819         wpa_driver_wext_disconnect(drv);
1820         return ret;
1821 }
1822
1823
1824 static int wpa_driver_wext_disassociate(void *priv, const u8 *addr,
1825                                         int reason_code)
1826 {
1827         struct wpa_driver_wext_data *drv = priv;
1828         int ret;
1829         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1830         ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
1831         wpa_driver_wext_disconnect(drv);
1832         return ret;
1833 }
1834
1835
1836 static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie,
1837                                       size_t ie_len)
1838 {
1839         struct wpa_driver_wext_data *drv = priv;
1840         struct iwreq iwr;
1841         int ret = 0;
1842
1843         os_memset(&iwr, 0, sizeof(iwr));
1844         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1845         iwr.u.data.pointer = (caddr_t) ie;
1846         iwr.u.data.length = ie_len;
1847
1848         if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
1849                 perror("ioctl[SIOCSIWGENIE]");
1850                 ret = -1;
1851         }
1852
1853         return ret;
1854 }
1855
1856
1857 int wpa_driver_wext_cipher2wext(int cipher)
1858 {
1859         switch (cipher) {
1860         case CIPHER_NONE:
1861                 return IW_AUTH_CIPHER_NONE;
1862         case CIPHER_WEP40:
1863                 return IW_AUTH_CIPHER_WEP40;
1864         case CIPHER_TKIP:
1865                 return IW_AUTH_CIPHER_TKIP;
1866         case CIPHER_CCMP:
1867                 return IW_AUTH_CIPHER_CCMP;
1868         case CIPHER_WEP104:
1869                 return IW_AUTH_CIPHER_WEP104;
1870         default:
1871                 return 0;
1872         }
1873 }
1874
1875
1876 int wpa_driver_wext_keymgmt2wext(int keymgmt)
1877 {
1878         switch (keymgmt) {
1879         case KEY_MGMT_802_1X:
1880         case KEY_MGMT_802_1X_NO_WPA:
1881                 return IW_AUTH_KEY_MGMT_802_1X;
1882         case KEY_MGMT_PSK:
1883                 return IW_AUTH_KEY_MGMT_PSK;
1884         default:
1885                 return 0;
1886         }
1887 }
1888
1889
1890 static int
1891 wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv,
1892                                   struct wpa_driver_associate_params *params)
1893 {
1894         struct iwreq iwr;
1895         int ret = 0;
1896
1897         wpa_printf(MSG_DEBUG, "WEXT: Driver did not support "
1898                    "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE");
1899
1900         os_memset(&iwr, 0, sizeof(iwr));
1901         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1902         /* Just changing mode, not actual keys */
1903         iwr.u.encoding.flags = 0;
1904         iwr.u.encoding.pointer = (caddr_t) NULL;
1905         iwr.u.encoding.length = 0;
1906
1907         /*
1908          * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two
1909          * different things. Here they are used to indicate Open System vs.
1910          * Shared Key authentication algorithm. However, some drivers may use
1911          * them to select between open/restricted WEP encrypted (open = allow
1912          * both unencrypted and encrypted frames; restricted = only allow
1913          * encrypted frames).
1914          */
1915
1916         if (!drv->use_crypt) {
1917                 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1918         } else {
1919                 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
1920                         iwr.u.encoding.flags |= IW_ENCODE_OPEN;
1921                 if (params->auth_alg & WPA_AUTH_ALG_SHARED)
1922                         iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED;
1923         }
1924
1925         if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
1926                 perror("ioctl[SIOCSIWENCODE]");
1927                 ret = -1;
1928         }
1929
1930         return ret;
1931 }
1932
1933
1934 int wpa_driver_wext_associate(void *priv,
1935                               struct wpa_driver_associate_params *params)
1936 {
1937         struct wpa_driver_wext_data *drv = priv;
1938         int ret = 0;
1939         int allow_unencrypted_eapol;
1940         int value;
1941
1942         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1943
1944         if (drv->cfg80211) {
1945                 /*
1946                  * Stop cfg80211 from trying to associate before we are done
1947                  * with all parameters.
1948                  */
1949                 wpa_driver_wext_set_ssid(drv, (u8 *) "", 0);
1950         }
1951
1952         if (wpa_driver_wext_set_drop_unencrypted(drv, params->drop_unencrypted)
1953             < 0)
1954                 ret = -1;
1955         if (wpa_driver_wext_set_auth_alg(drv, params->auth_alg) < 0)
1956                 ret = -1;
1957         if (wpa_driver_wext_set_mode(drv, params->mode) < 0)
1958                 ret = -1;
1959
1960         /*
1961          * If the driver did not support SIOCSIWAUTH, fallback to
1962          * SIOCSIWENCODE here.
1963          */
1964         if (drv->auth_alg_fallback &&
1965             wpa_driver_wext_auth_alg_fallback(drv, params) < 0)
1966                 ret = -1;
1967
1968         if (!params->bssid &&
1969             wpa_driver_wext_set_bssid(drv, NULL) < 0)
1970                 ret = -1;
1971
1972         /* TODO: should consider getting wpa version and cipher/key_mgmt suites
1973          * from configuration, not from here, where only the selected suite is
1974          * available */
1975         if (wpa_driver_wext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len)
1976             < 0)
1977                 ret = -1;
1978         if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
1979                 value = IW_AUTH_WPA_VERSION_DISABLED;
1980         else if (params->wpa_ie[0] == WLAN_EID_RSN)
1981                 value = IW_AUTH_WPA_VERSION_WPA2;
1982         else
1983                 value = IW_AUTH_WPA_VERSION_WPA;
1984         if (wpa_driver_wext_set_auth_param(drv,
1985                                            IW_AUTH_WPA_VERSION, value) < 0)
1986                 ret = -1;
1987         value = wpa_driver_wext_cipher2wext(params->pairwise_suite);
1988         if (wpa_driver_wext_set_auth_param(drv,
1989                                            IW_AUTH_CIPHER_PAIRWISE, value) < 0)
1990                 ret = -1;
1991         value = wpa_driver_wext_cipher2wext(params->group_suite);
1992         if (wpa_driver_wext_set_auth_param(drv,
1993                                            IW_AUTH_CIPHER_GROUP, value) < 0)
1994                 ret = -1;
1995         value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite);
1996         if (wpa_driver_wext_set_auth_param(drv,
1997                                            IW_AUTH_KEY_MGMT, value) < 0)
1998                 ret = -1;
1999         value = params->key_mgmt_suite != KEY_MGMT_NONE ||
2000                 params->pairwise_suite != CIPHER_NONE ||
2001                 params->group_suite != CIPHER_NONE ||
2002                 params->wpa_ie_len;
2003         if (wpa_driver_wext_set_auth_param(drv,
2004                                            IW_AUTH_PRIVACY_INVOKED, value) < 0)
2005                 ret = -1;
2006
2007         /* Allow unencrypted EAPOL messages even if pairwise keys are set when
2008          * not using WPA. IEEE 802.1X specifies that these frames are not
2009          * encrypted, but WPA encrypts them when pairwise keys are in use. */
2010         if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
2011             params->key_mgmt_suite == KEY_MGMT_PSK)
2012                 allow_unencrypted_eapol = 0;
2013         else
2014                 allow_unencrypted_eapol = 1;
2015
2016         if (wpa_driver_wext_set_psk(drv, params->psk) < 0)
2017                 ret = -1;
2018         if (wpa_driver_wext_set_auth_param(drv,
2019                                            IW_AUTH_RX_UNENCRYPTED_EAPOL,
2020                                            allow_unencrypted_eapol) < 0)
2021                 ret = -1;
2022 #ifdef CONFIG_IEEE80211W
2023         switch (params->mgmt_frame_protection) {
2024         case NO_MGMT_FRAME_PROTECTION:
2025                 value = IW_AUTH_MFP_DISABLED;
2026                 break;
2027         case MGMT_FRAME_PROTECTION_OPTIONAL:
2028                 value = IW_AUTH_MFP_OPTIONAL;
2029                 break;
2030         case MGMT_FRAME_PROTECTION_REQUIRED:
2031                 value = IW_AUTH_MFP_REQUIRED;
2032                 break;
2033         };
2034         if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0)
2035                 ret = -1;
2036 #endif /* CONFIG_IEEE80211W */
2037         if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
2038                 ret = -1;
2039         if (!drv->cfg80211 &&
2040             wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
2041                 ret = -1;
2042         if (params->bssid &&
2043             wpa_driver_wext_set_bssid(drv, params->bssid) < 0)
2044                 ret = -1;
2045         if (drv->cfg80211 &&
2046             wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
2047                 ret = -1;
2048
2049         return ret;
2050 }
2051
2052
2053 static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg)
2054 {
2055         struct wpa_driver_wext_data *drv = priv;
2056         int algs = 0, res;
2057
2058         if (auth_alg & WPA_AUTH_ALG_OPEN)
2059                 algs |= IW_AUTH_ALG_OPEN_SYSTEM;
2060         if (auth_alg & WPA_AUTH_ALG_SHARED)
2061                 algs |= IW_AUTH_ALG_SHARED_KEY;
2062         if (auth_alg & WPA_AUTH_ALG_LEAP)
2063                 algs |= IW_AUTH_ALG_LEAP;
2064         if (algs == 0) {
2065                 /* at least one algorithm should be set */
2066                 algs = IW_AUTH_ALG_OPEN_SYSTEM;
2067         }
2068
2069         res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG,
2070                                              algs);
2071         drv->auth_alg_fallback = res == -2;
2072         return res;
2073 }
2074
2075
2076 /**
2077  * wpa_driver_wext_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE
2078  * @priv: Pointer to private wext data from wpa_driver_wext_init()
2079  * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS
2080  * Returns: 0 on success, -1 on failure
2081  */
2082 int wpa_driver_wext_set_mode(void *priv, int mode)
2083 {
2084         struct wpa_driver_wext_data *drv = priv;
2085         struct iwreq iwr;
2086         int ret = -1;
2087         unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
2088
2089         os_memset(&iwr, 0, sizeof(iwr));
2090         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2091         iwr.u.mode = new_mode;
2092         if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) == 0) {
2093                 ret = 0;
2094                 goto done;
2095         }
2096
2097         if (errno != EBUSY) {
2098                 perror("ioctl[SIOCSIWMODE]");
2099                 goto done;
2100         }
2101
2102         /* mac80211 doesn't allow mode changes while the device is up, so if
2103          * the device isn't in the mode we're about to change to, take device
2104          * down, try to set the mode again, and bring it back up.
2105          */
2106         if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
2107                 perror("ioctl[SIOCGIWMODE]");
2108                 goto done;
2109         }
2110
2111         if (iwr.u.mode == new_mode) {
2112                 ret = 0;
2113                 goto done;
2114         }
2115
2116         if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) {
2117                 /* Try to set the mode again while the interface is down */
2118                 iwr.u.mode = new_mode;
2119                 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0)
2120                         perror("ioctl[SIOCSIWMODE]");
2121                 else
2122                         ret = 0;
2123
2124                 (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
2125         }
2126
2127 done:
2128         return ret;
2129 }
2130
2131
2132 static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv,
2133                                  u32 cmd, const u8 *bssid, const u8 *pmkid)
2134 {
2135         struct iwreq iwr;
2136         struct iw_pmksa pmksa;
2137         int ret = 0;
2138
2139         os_memset(&iwr, 0, sizeof(iwr));
2140         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2141         os_memset(&pmksa, 0, sizeof(pmksa));
2142         pmksa.cmd = cmd;
2143         pmksa.bssid.sa_family = ARPHRD_ETHER;
2144         if (bssid)
2145                 os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN);
2146         if (pmkid)
2147                 os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN);
2148         iwr.u.data.pointer = (caddr_t) &pmksa;
2149         iwr.u.data.length = sizeof(pmksa);
2150
2151         if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {
2152                 if (errno != EOPNOTSUPP)
2153                         perror("ioctl[SIOCSIWPMKSA]");
2154                 ret = -1;
2155         }
2156
2157         return ret;
2158 }
2159
2160
2161 static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid,
2162                                      const u8 *pmkid)
2163 {
2164         struct wpa_driver_wext_data *drv = priv;
2165         return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);
2166 }
2167
2168
2169 static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid,
2170                                         const u8 *pmkid)
2171 {
2172         struct wpa_driver_wext_data *drv = priv;
2173         return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);
2174 }
2175
2176
2177 static int wpa_driver_wext_flush_pmkid(void *priv)
2178 {
2179         struct wpa_driver_wext_data *drv = priv;
2180         return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL);
2181 }
2182
2183
2184 int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa)
2185 {
2186         struct wpa_driver_wext_data *drv = priv;
2187         if (!drv->has_capability)
2188                 return -1;
2189         os_memcpy(capa, &drv->capa, sizeof(*capa));
2190         return 0;
2191 }
2192
2193
2194 int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv,
2195                                         const char *ifname)
2196 {
2197         if (ifname == NULL) {
2198                 drv->ifindex2 = -1;
2199                 return 0;
2200         }
2201
2202         drv->ifindex2 = if_nametoindex(ifname);
2203         if (drv->ifindex2 <= 0)
2204                 return -1;
2205
2206         wpa_printf(MSG_DEBUG, "Added alternative ifindex %d (%s) for "
2207                    "wireless events", drv->ifindex2, ifname);
2208
2209         return 0;
2210 }
2211
2212
2213 int wpa_driver_wext_set_operstate(void *priv, int state)
2214 {
2215         struct wpa_driver_wext_data *drv = priv;
2216
2217         wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
2218                    __func__, drv->operstate, state, state ? "UP" : "DORMANT");
2219         drv->operstate = state;
2220         return netlink_send_oper_ifla(drv->netlink, drv->ifindex, -1,
2221                                       state ? IF_OPER_UP : IF_OPER_DORMANT);
2222 }
2223
2224
2225 int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv)
2226 {
2227         return drv->we_version_compiled;
2228 }
2229
2230
2231 const struct wpa_driver_ops wpa_driver_wext_ops = {
2232         .name = "wext",
2233         .desc = "Linux wireless extensions (generic)",
2234         .get_bssid = wpa_driver_wext_get_bssid,
2235         .get_ssid = wpa_driver_wext_get_ssid,
2236         .set_key = wpa_driver_wext_set_key,
2237         .set_countermeasures = wpa_driver_wext_set_countermeasures,
2238         .scan2 = wpa_driver_wext_scan,
2239         .get_scan_results2 = wpa_driver_wext_get_scan_results,
2240         .deauthenticate = wpa_driver_wext_deauthenticate,
2241         .disassociate = wpa_driver_wext_disassociate,
2242         .associate = wpa_driver_wext_associate,
2243         .init = wpa_driver_wext_init,
2244         .deinit = wpa_driver_wext_deinit,
2245         .add_pmkid = wpa_driver_wext_add_pmkid,
2246         .remove_pmkid = wpa_driver_wext_remove_pmkid,
2247         .flush_pmkid = wpa_driver_wext_flush_pmkid,
2248         .get_capa = wpa_driver_wext_get_capa,
2249         .set_operstate = wpa_driver_wext_set_operstate,
2250 };