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