driver_bsd.c (209139) | driver_bsd.c (214501) |
---|---|
1/* 2 * WPA Supplicant - driver interaction with BSD net80211 layer 3 * Copyright (c) 2004, Sam Leffler <sam@errno.com> | 1/* 2 * WPA Supplicant - driver interaction with BSD net80211 layer 3 * Copyright (c) 2004, Sam Leffler <sam@errno.com> |
4 * Copyright (c) 2004, 2Wire, Inc |
|
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 15#include "includes.h" 16#include <sys/ioctl.h> 17 18#include "common.h" 19#include "driver.h" 20#include "eloop.h" | 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Alternatively, this software may be distributed under the terms of BSD 11 * license. 12 * 13 * See README and COPYING for more details. 14 */ 15 16#include "includes.h" 17#include <sys/ioctl.h> 18 19#include "common.h" 20#include "driver.h" 21#include "eloop.h" |
21#include "ieee802_11_defs.h" | 22#include "common/ieee802_11_defs.h" |
22 23#include <net/if.h> | 23 24#include <net/if.h> |
25#include <net/if_media.h> |
|
24 25#ifdef __NetBSD__ 26#include <net/if_ether.h> | 26 27#ifdef __NetBSD__ 28#include <net/if_ether.h> |
27#define COMPAT_FREEBSD_NET80211 | |
28#else 29#include <net/ethernet.h> 30#endif | 29#else 30#include <net/ethernet.h> 31#endif |
32#include <net/route.h> |
|
31 | 33 |
34#ifdef __DragonFly__ 35#include <netproto/802_11/ieee80211_ioctl.h> 36#include <netproto/802_11/ieee80211_dragonfly.h> 37#else /* __DragonFly__ */ 38#ifdef __GLIBC__ 39#include <netinet/ether.h> 40#endif /* __GLIBC__ */ |
|
32#include <net80211/ieee80211.h> | 41#include <net80211/ieee80211.h> |
33#include <net80211/ieee80211_crypto.h> | |
34#include <net80211/ieee80211_ioctl.h> | 42#include <net80211/ieee80211_ioctl.h> |
43#include <net80211/ieee80211_crypto.h> 44#endif /* __DragonFly__ || __GLIBC__ */ 45#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 46#include <net80211/ieee80211_freebsd.h> 47#endif 48#if __NetBSD__ 49#include <net80211/ieee80211_netbsd.h> 50#endif |
|
35 | 51 |
36struct wpa_driver_bsd_data { | 52#include "l2_packet/l2_packet.h" 53 54struct bsd_driver_data { 55 struct hostapd_data *hapd; /* back pointer */ 56 |
37 int sock; /* open socket for 802.11 ioctls */ | 57 int sock; /* open socket for 802.11 ioctls */ |
58 struct l2_packet_data *sock_xmit;/* raw packet xmit socket */ |
|
38 int route; /* routing socket for events */ 39 char ifname[IFNAMSIZ+1]; /* interface name */ 40 unsigned int ifindex; /* interface index */ 41 void *ctx; | 59 int route; /* routing socket for events */ 60 char ifname[IFNAMSIZ+1]; /* interface name */ 61 unsigned int ifindex; /* interface index */ 62 void *ctx; |
42 int prev_roaming; /* roaming state to restore on deinit */ 43 int prev_privacy; /* privacy state to restore on deinit */ 44 int prev_wpa; /* wpa state to restore on deinit */ | 63 struct wpa_driver_capa capa; /* driver capability */ 64 int is_ap; /* Access point mode */ 65 int prev_roaming; /* roaming state to restore on deinit */ 66 int prev_privacy; /* privacy state to restore on deinit */ 67 int prev_wpa; /* wpa state to restore on deinit */ |
45}; 46 | 68}; 69 |
70/* Generic functions for hostapd and wpa_supplicant */ 71 |
|
47static int | 72static int |
48set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len) | 73bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len) |
49{ | 74{ |
75 struct bsd_driver_data *drv = priv; |
|
50 struct ieee80211req ireq; 51 52 os_memset(&ireq, 0, sizeof(ireq)); | 76 struct ieee80211req ireq; 77 78 os_memset(&ireq, 0, sizeof(ireq)); |
53 os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); | 79 os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name)); |
54 ireq.i_type = op; | 80 ireq.i_type = op; |
55 ireq.i_len = arg_len; | 81 ireq.i_val = val; |
56 ireq.i_data = (void *) arg; | 82 ireq.i_data = (void *) arg; |
83 ireq.i_len = arg_len; |
|
57 58 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { | 84 85 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { |
59 fprintf(stderr, "ioctl[SIOCS80211, op %u, len %u]: %s\n", 60 op, arg_len, strerror(errno)); | 86 wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, val=%u, " 87 "arg_len=%u]: %s", op, val, arg_len, 88 strerror(errno)); |
61 return -1; 62 } 63 return 0; 64} 65 66static int | 89 return -1; 90 } 91 return 0; 92} 93 94static int |
67get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len) | 95bsd_get80211(void *priv, struct ieee80211req *ireq, int op, void *arg, 96 int arg_len) |
68{ | 97{ |
69 struct ieee80211req ireq; | 98 struct bsd_driver_data *drv = priv; |
70 | 99 |
71 os_memset(&ireq, 0, sizeof(ireq)); 72 os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); 73 ireq.i_type = op; 74 ireq.i_len = arg_len; 75 ireq.i_data = arg; | 100 os_memset(ireq, 0, sizeof(*ireq)); 101 os_strlcpy(ireq->i_name, drv->ifname, sizeof(ireq->i_name)); 102 ireq->i_type = op; 103 ireq->i_len = arg_len; 104 ireq->i_data = arg; |
76 | 105 |
77 if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { 78 fprintf(stderr, "ioctl[SIOCG80211, op %u, len %u]: %s\n", 79 op, arg_len, strerror(errno)); | 106 if (ioctl(drv->sock, SIOCG80211, ireq) < 0) { 107 wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, " 108 "arg_len=%u]: %s", op, arg_len, strerror(errno)); |
80 return -1; 81 } | 109 return -1; 110 } |
82 return ireq.i_len; | 111 return 0; |
83} 84 85static int | 112} 113 114static int |
86set80211param(struct wpa_driver_bsd_data *drv, int op, int arg) | 115get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len) |
87{ 88 struct ieee80211req ireq; 89 | 116{ 117 struct ieee80211req ireq; 118 |
90 os_memset(&ireq, 0, sizeof(ireq)); 91 os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); 92 ireq.i_type = op; 93 ireq.i_val = arg; 94 95 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { 96 fprintf(stderr, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n", 97 op, arg, strerror(errno)); | 119 if (bsd_get80211(drv, &ireq, op, arg, arg_len) < 0) |
98 return -1; | 120 return -1; |
99 } 100 return 0; | 121 return ireq.i_len; |
101} 102 103static int | 122} 123 124static int |
104get80211param(struct wpa_driver_bsd_data *drv, int op) | 125set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len) |
105{ | 126{ |
106 struct ieee80211req ireq; | 127 return bsd_set80211(drv, op, 0, arg, arg_len); 128} |
107 | 129 |
108 os_memset(&ireq, 0, sizeof(ireq)); 109 os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); 110 ireq.i_type = op; 111 112 if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { 113 fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n", 114 op, strerror(errno)); 115 return -1; 116 } 117 return ireq.i_val; | 130static int 131set80211param(struct bsd_driver_data *drv, int op, int arg) 132{ 133 return bsd_set80211(drv, op, arg, NULL, 0); |
118} 119 120static int | 134} 135 136static int |
121getifflags(struct wpa_driver_bsd_data *drv, int *flags) | 137bsd_get_ssid(void *priv, u8 *ssid, int len) |
122{ | 138{ |
139 struct bsd_driver_data *drv = priv; 140#ifdef SIOCG80211NWID 141 struct ieee80211_nwid nwid; |
|
123 struct ifreq ifr; 124 125 os_memset(&ifr, 0, sizeof(ifr)); 126 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); | 142 struct ifreq ifr; 143 144 os_memset(&ifr, 0, sizeof(ifr)); 145 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); |
127 if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 128 perror("SIOCGIFFLAGS"); 129 return errno; 130 } 131 *flags = ifr.ifr_flags & 0xffff; 132 return 0; | 146 ifr.ifr_data = (void *)&nwid; 147 if (ioctl(drv->sock, SIOCG80211NWID, &ifr) < 0 || 148 nwid.i_len > IEEE80211_NWID_LEN) 149 return -1; 150 os_memcpy(ssid, nwid.i_nwid, nwid.i_len); 151 return nwid.i_len; 152#else 153 return get80211var(drv, IEEE80211_IOC_SSID, ssid, IEEE80211_NWID_LEN); 154#endif |
133} 134 135static int | 155} 156 157static int |
136setifflags(struct wpa_driver_bsd_data *drv, int flags) | 158bsd_set_ssid(void *priv, const u8 *ssid, int ssid_len) |
137{ | 159{ |
160 struct bsd_driver_data *drv = priv; 161#ifdef SIOCS80211NWID 162 struct ieee80211_nwid nwid; |
|
138 struct ifreq ifr; 139 | 163 struct ifreq ifr; 164 |
165 os_memcpy(nwid.i_nwid, ssid, ssid_len); 166 nwid.i_len = ssid_len; |
|
140 os_memset(&ifr, 0, sizeof(ifr)); 141 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); | 167 os_memset(&ifr, 0, sizeof(ifr)); 168 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); |
142 ifr.ifr_flags = flags & 0xffff; 143 if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) { 144 perror("SIOCSIFFLAGS"); 145 return errno; 146 } 147 return 0; | 169 ifr.ifr_data = (void *)&nwid; 170 return ioctl(drv->sock, SIOCS80211NWID, &ifr); 171#else 172 return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len); 173#endif |
148} 149 150static int | 174} 175 176static int |
151wpa_driver_bsd_get_bssid(void *priv, u8 *bssid) | 177bsd_get_if_media(void *priv) |
152{ | 178{ |
153 struct wpa_driver_bsd_data *drv = priv; | 179 struct bsd_driver_data *drv = priv; 180 struct ifmediareq ifmr; |
154 | 181 |
155 return get80211var(drv, IEEE80211_IOC_BSSID, 156 bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0; 157} | 182 os_memset(&ifmr, 0, sizeof(ifmr)); 183 os_strlcpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name)); |
158 | 184 |
159#if 0 160static int 161wpa_driver_bsd_set_bssid(void *priv, const char *bssid) 162{ 163 struct wpa_driver_bsd_data *drv = priv; | 185 if (ioctl(drv->sock, SIOCGIFMEDIA, &ifmr) < 0) { 186 wpa_printf(MSG_ERROR, "%s: SIOCGIFMEDIA %s", __func__, 187 strerror(errno)); 188 return -1; 189 } |
164 | 190 |
165 return set80211var(drv, IEEE80211_IOC_BSSID, 166 bssid, IEEE80211_ADDR_LEN); | 191 return ifmr.ifm_current; |
167} | 192} |
168#endif | |
169 170static int | 193 194static int |
171wpa_driver_bsd_get_ssid(void *priv, u8 *ssid) | 195bsd_set_if_media(void *priv, int media) |
172{ | 196{ |
173 struct wpa_driver_bsd_data *drv = priv; | 197 struct bsd_driver_data *drv = priv; 198 struct ifreq ifr; |
174 | 199 |
175 return get80211var(drv, IEEE80211_IOC_SSID, 176 ssid, IEEE80211_NWID_LEN); 177} | 200 os_memset(&ifr, 0, sizeof(ifr)); 201 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); 202 ifr.ifr_media = media; |
178 | 203 |
179static int 180wpa_driver_bsd_set_ssid(void *priv, const u8 *ssid, 181 size_t ssid_len) 182{ 183 struct wpa_driver_bsd_data *drv = priv; | 204 if (ioctl(drv->sock, SIOCSIFMEDIA, &ifr) < 0) { 205 wpa_printf(MSG_ERROR, "%s: SIOCSIFMEDIA %s", __func__, 206 strerror(errno)); 207 return -1; 208 } |
184 | 209 |
185 return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len); | 210 return 0; |
186} 187 188static int | 211} 212 213static int |
189wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv, 190 const u8 *wpa_ie, size_t wpa_ie_len) | 214bsd_set_mediaopt(void *priv, uint32_t mask, uint32_t mode) |
191{ | 215{ |
192 return set80211var(drv, IEEE80211_IOC_OPTIE, wpa_ie, wpa_ie_len); | 216 int media = bsd_get_if_media(priv); 217 218 if (media < 0) 219 return -1; 220 media &= ~mask; 221 media |= mode; 222 if (bsd_set_if_media(priv, media) < 0) 223 return -1; 224 return 0; |
193} 194 195static int | 225} 226 227static int |
196wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy) | 228bsd_del_key(void *priv, const u8 *addr, int key_idx) |
197{ | 229{ |
198 struct wpa_driver_bsd_data *drv = priv; 199 int ret = 0; | 230 struct ieee80211req_del_key wk; |
200 | 231 |
201 wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d", 202 __FUNCTION__, wpa, privacy); | 232 os_memset(&wk, 0, sizeof(wk)); 233 if (addr == NULL) { 234 wpa_printf(MSG_DEBUG, "%s: key_idx=%d", __func__, key_idx); 235 wk.idk_keyix = key_idx; 236 } else { 237 wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, 238 MAC2STR(addr)); 239 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 240 wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */ 241 } |
203 | 242 |
204 if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0) 205 ret = -1; 206 if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) 207 ret = -1; 208 if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0) 209 ret = -1; 210 211 return ret; | 243 return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); |
212} 213 214static int | 244} 245 246static int |
215wpa_driver_bsd_set_wpa(void *priv, int enabled) | 247bsd_send_mlme_param(void *priv, const u8 op, const u16 reason, const u8 *addr) |
216{ | 248{ |
217 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); | 249 struct ieee80211req_mlme mlme; |
218 | 250 |
219 return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled); | 251 os_memset(&mlme, 0, sizeof(mlme)); 252 mlme.im_op = op; 253 mlme.im_reason = reason; 254 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 255 return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); |
220} 221 222static int | 256} 257 258static int |
223wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx, 224 const unsigned char *addr) | 259bsd_ctrl_iface(void *priv, int enable) |
225{ | 260{ |
226 struct ieee80211req_del_key wk; | 261 struct bsd_driver_data *drv = priv; 262 struct ifreq ifr; |
227 | 263 |
228 os_memset(&wk, 0, sizeof(wk)); 229 if (addr != NULL && 230 bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) { 231 struct ether_addr ea; | 264 os_memset(&ifr, 0, sizeof(ifr)); 265 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); |
232 | 266 |
233 os_memcpy(&ea, addr, IEEE80211_ADDR_LEN); 234 wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d", 235 __func__, ether_ntoa(&ea), key_idx); 236 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 237 wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE; 238 } else { 239 wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx); 240 wk.idk_keyix = key_idx; | 267 if (ioctl(drv->sock, SIOCGIFFLAGS, &ifr) < 0) { 268 perror("ioctl[SIOCGIFFLAGS]"); 269 return -1; |
241 } | 270 } |
242 return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); | 271 272 if (enable) 273 ifr.ifr_flags |= IFF_UP; 274 else 275 ifr.ifr_flags &= ~IFF_UP; 276 277 if (ioctl(drv->sock, SIOCSIFFLAGS, &ifr) < 0) { 278 perror("ioctl[SIOCSIFFLAGS]"); 279 return -1; 280 } 281 282 return 0; |
243} 244 245static int | 283} 284 285static int |
246wpa_driver_bsd_set_key(void *priv, wpa_alg alg, 247 const unsigned char *addr, int key_idx, int set_tx, 248 const u8 *seq, size_t seq_len, 249 const u8 *key, size_t key_len) | 286bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, 287 const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, 288 size_t seq_len, const u8 *key, size_t key_len) |
250{ | 289{ |
251 struct wpa_driver_bsd_data *drv = priv; | |
252 struct ieee80211req_key wk; | 290 struct ieee80211req_key wk; |
253 struct ether_addr ea; 254 char *alg_name; 255 u_int8_t cipher; | |
256 | 291 |
257 if (alg == WPA_ALG_NONE) 258 return wpa_driver_bsd_del_key(drv, key_idx, addr); | 292 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d " 293 "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx, 294 set_tx, seq_len, key_len); |
259 | 295 |
296 if (alg == WPA_ALG_NONE) { 297#ifndef HOSTAPD 298 if (addr == NULL || 299 os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", 300 IEEE80211_ADDR_LEN) == 0) 301 return bsd_del_key(priv, NULL, key_idx); 302 else 303#endif /* HOSTAPD */ 304 return bsd_del_key(priv, addr, key_idx); 305 } 306 307 os_memset(&wk, 0, sizeof(wk)); |
|
260 switch (alg) { 261 case WPA_ALG_WEP: | 308 switch (alg) { 309 case WPA_ALG_WEP: |
262 alg_name = "WEP"; 263 cipher = IEEE80211_CIPHER_WEP; | 310 wk.ik_type = IEEE80211_CIPHER_WEP; |
264 break; 265 case WPA_ALG_TKIP: | 311 break; 312 case WPA_ALG_TKIP: |
266 alg_name = "TKIP"; 267 cipher = IEEE80211_CIPHER_TKIP; | 313 wk.ik_type = IEEE80211_CIPHER_TKIP; |
268 break; 269 case WPA_ALG_CCMP: | 314 break; 315 case WPA_ALG_CCMP: |
270 alg_name = "CCMP"; 271 cipher = IEEE80211_CIPHER_AES_CCM; | 316 wk.ik_type = IEEE80211_CIPHER_AES_CCM; |
272 break; 273 default: | 317 break; 318 default: |
274 wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d", 275 __func__, alg); | 319 wpa_printf(MSG_ERROR, "%s: unknown alg=%d", __func__, alg); |
276 return -1; 277 } 278 | 320 return -1; 321 } 322 |
279 os_memcpy(&ea, addr, IEEE80211_ADDR_LEN); 280 wpa_printf(MSG_DEBUG, 281 "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu", 282 __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx, 283 seq_len, key_len); 284 285 if (seq_len > sizeof(u_int64_t)) { 286 wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big", 287 __func__, seq_len); 288 return -2; 289 } 290 if (key_len > sizeof(wk.ik_keydata)) { 291 wpa_printf(MSG_DEBUG, "%s: key length %zu too big", 292 __func__, key_len); 293 return -3; 294 } 295 296 os_memset(&wk, 0, sizeof(wk)); 297 wk.ik_type = cipher; | |
298 wk.ik_flags = IEEE80211_KEY_RECV; 299 if (set_tx) 300 wk.ik_flags |= IEEE80211_KEY_XMIT; | 323 wk.ik_flags = IEEE80211_KEY_RECV; 324 if (set_tx) 325 wk.ik_flags |= IEEE80211_KEY_XMIT; |
301 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 302 /* 303 * Deduce whether group/global or unicast key by checking 304 * the address (yech). Note also that we can only mark global 305 * keys default; doing this for a unicast key is an error. 306 */ 307 if (bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) == 0) { 308 wk.ik_flags |= IEEE80211_KEY_GROUP; | 326 327 if (addr == NULL) { 328 os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); |
309 wk.ik_keyix = key_idx; 310 } else { | 329 wk.ik_keyix = key_idx; 330 } else { |
311 wk.ik_keyix = (key_idx == 0 ? IEEE80211_KEYIX_NONE : key_idx); | 331 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 332 /* 333 * Deduce whether group/global or unicast key by checking 334 * the address (yech). Note also that we can only mark global 335 * keys default; doing this for a unicast key is an error. 336 */ 337 if (os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", 338 IEEE80211_ADDR_LEN) == 0) { 339 wk.ik_flags |= IEEE80211_KEY_GROUP; 340 wk.ik_keyix = key_idx; 341 } else { 342 wk.ik_keyix = key_idx == 0 ? IEEE80211_KEYIX_NONE : 343 key_idx; 344 } |
312 } 313 if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) 314 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 315 wk.ik_keylen = key_len; 316 os_memcpy(&wk.ik_keyrsc, seq, seq_len); 317 os_memcpy(wk.ik_keydata, key, key_len); 318 | 345 } 346 if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) 347 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 348 wk.ik_keylen = key_len; 349 os_memcpy(&wk.ik_keyrsc, seq, seq_len); 350 os_memcpy(wk.ik_keydata, key, key_len); 351 |
319 return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); | 352 return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); |
320} 321 322static int | 353} 354 355static int |
323wpa_driver_bsd_set_countermeasures(void *priv, int enabled) | 356bsd_configure_wpa(void *priv, struct wpa_bss_params *params) |
324{ | 357{ |
325 struct wpa_driver_bsd_data *drv = priv; | 358#ifndef IEEE80211_IOC_APPIE 359 static const char *ciphernames[] = 360 { "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" }; 361 int v; |
326 | 362 |
363 switch (params->wpa_group) { 364 case WPA_CIPHER_CCMP: 365 v = IEEE80211_CIPHER_AES_CCM; 366 break; 367 case WPA_CIPHER_TKIP: 368 v = IEEE80211_CIPHER_TKIP; 369 break; 370 case WPA_CIPHER_WEP104: 371 v = IEEE80211_CIPHER_WEP; 372 break; 373 case WPA_CIPHER_WEP40: 374 v = IEEE80211_CIPHER_WEP; 375 break; 376 case WPA_CIPHER_NONE: 377 v = IEEE80211_CIPHER_NONE; 378 break; 379 default: 380 printf("Unknown group key cipher %u\n", 381 params->wpa_group); 382 return -1; 383 } 384 wpa_printf(MSG_DEBUG, "%s: group key cipher=%s (%u)", 385 __func__, ciphernames[v], v); 386 if (set80211param(priv, IEEE80211_IOC_MCASTCIPHER, v)) { 387 printf("Unable to set group key cipher to %u (%s)\n", 388 v, ciphernames[v]); 389 return -1; 390 } 391 if (v == IEEE80211_CIPHER_WEP) { 392 /* key length is done only for specific ciphers */ 393 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); 394 if (set80211param(priv, IEEE80211_IOC_MCASTKEYLEN, v)) { 395 printf("Unable to set group key length to %u\n", v); 396 return -1; 397 } 398 } 399 400 v = 0; 401 if (params->wpa_pairwise & WPA_CIPHER_CCMP) 402 v |= 1<<IEEE80211_CIPHER_AES_CCM; 403 if (params->wpa_pairwise & WPA_CIPHER_TKIP) 404 v |= 1<<IEEE80211_CIPHER_TKIP; 405 if (params->wpa_pairwise & WPA_CIPHER_NONE) 406 v |= 1<<IEEE80211_CIPHER_NONE; 407 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v); 408 if (set80211param(priv, IEEE80211_IOC_UCASTCIPHERS, v)) { 409 printf("Unable to set pairwise key ciphers to 0x%x\n", v); 410 return -1; 411 } 412 413 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x", 414 __func__, params->wpa_key_mgmt); 415 if (set80211param(priv, IEEE80211_IOC_KEYMGTALGS, 416 params->wpa_key_mgmt)) { 417 printf("Unable to set key management algorithms to 0x%x\n", 418 params->wpa_key_mgmt); 419 return -1; 420 } 421 422 v = 0; 423 if (params->rsn_preauth) 424 v |= BIT(0); 425 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", 426 __func__, params->rsn_preauth); 427 if (set80211param(priv, IEEE80211_IOC_RSNCAPS, v)) { 428 printf("Unable to set RSN capabilities to 0x%x\n", v); 429 return -1; 430 } 431#endif /* IEEE80211_IOC_APPIE */ 432 433 wpa_printf(MSG_DEBUG, "%s: enable WPA= 0x%x", __func__, params->wpa); 434 if (set80211param(priv, IEEE80211_IOC_WPA, params->wpa)) { 435 printf("Unable to set WPA to %u\n", params->wpa); 436 return -1; 437 } 438 return 0; 439} 440 441static int 442bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params) 443{ 444 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 445 446 if (!params->enabled) { 447 /* XXX restore state */ 448 return set80211param(priv, IEEE80211_IOC_AUTHMODE, 449 IEEE80211_AUTH_AUTO); 450 } 451 if (!params->wpa && !params->ieee802_1x) { 452 wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled", 453 __func__); 454 return -1; 455 } 456 if (params->wpa && bsd_configure_wpa(priv, params) != 0) { 457 wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state", 458 __func__); 459 return -1; 460 } 461 if (set80211param(priv, IEEE80211_IOC_AUTHMODE, 462 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 463 wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X", 464 __func__); 465 return -1; 466 } 467 return bsd_ctrl_iface(priv, 1); 468} 469 470static int 471bsd_set_sta_authorized(void *priv, const u8 *addr, 472 int total_flags, int flags_or, int flags_and) 473{ 474 int authorized = -1; 475 476 /* For now, only support setting Authorized flag */ 477 if (flags_or & WPA_STA_AUTHORIZED) 478 authorized = 1; 479 if (!(flags_and & WPA_STA_AUTHORIZED)) 480 authorized = 0; 481 482 if (authorized < 0) 483 return 0; 484 485 return bsd_send_mlme_param(priv, authorized ? 486 IEEE80211_MLME_AUTHORIZE : 487 IEEE80211_MLME_UNAUTHORIZE, 0, addr); 488} 489 490static void 491bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN]) 492{ 493 struct ieee80211req_wpaie ie; 494 int ielen = 0; 495 u8 *iebuf = NULL; 496 497 /* 498 * Fetch and validate any negotiated WPA/RSN parameters. 499 */ 500 memset(&ie, 0, sizeof(ie)); 501 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 502 if (get80211var(priv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) { 503 printf("Failed to get WPA/RSN information element.\n"); 504 goto no_ie; 505 } 506 iebuf = ie.wpa_ie; 507 ielen = ie.wpa_ie[1]; 508 if (ielen == 0) 509 iebuf = NULL; 510 else 511 ielen += 2; 512 513no_ie: 514 drv_event_assoc(ctx, addr, iebuf, ielen); 515} 516 517static int 518bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, 519 int encrypt, const u8 *own_addr) 520{ 521 struct bsd_driver_data *drv = priv; 522 523 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", data, data_len); 524 525 return l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, data, 526 data_len); 527} 528 529static int 530bsd_set_freq(void *priv, u16 channel) 531{ 532 struct bsd_driver_data *drv = priv; 533#ifdef SIOCS80211CHANNEL 534 struct ieee80211chanreq creq; 535#endif /* SIOCS80211CHANNEL */ 536 u32 mode; 537 538 if (channel < 14) 539 mode = IFM_IEEE80211_11G; 540 else if (channel == 14) 541 mode = IFM_IEEE80211_11B; 542 else 543 mode = IFM_IEEE80211_11A; 544 if (bsd_set_mediaopt(drv, IFM_MMASK, mode) < 0) { 545 wpa_printf(MSG_ERROR, "%s: failed to set modulation mode", 546 __func__); 547 return -1; 548 } 549 550#ifdef SIOCS80211CHANNEL 551 os_memset(&creq, 0, sizeof(creq)); 552 os_strlcpy(creq.i_name, drv->ifname, sizeof(creq.i_name)); 553 creq.i_channel = channel; 554 return ioctl(drv->sock, SIOCS80211CHANNEL, &creq); 555#else /* SIOCS80211CHANNEL */ 556 return set80211param(priv, IEEE80211_IOC_CHANNEL, channel); 557#endif /* SIOCS80211CHANNEL */ 558} 559 560static int 561bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 562{ 563#ifdef IEEE80211_IOC_APPIE 564 wpa_printf(MSG_DEBUG, "%s: set WPA+RSN ie (len %lu)", __func__, 565 (unsigned long)ie_len); 566 return bsd_set80211(priv, IEEE80211_IOC_APPIE, IEEE80211_APPIE_WPA, 567 ie, ie_len); 568#endif /* IEEE80211_IOC_APPIE */ 569 return 0; 570} 571 572 573#ifdef HOSTAPD 574 575/* 576 * Avoid conflicts with hostapd definitions by undefining couple of defines 577 * from net80211 header files. 578 */ 579#undef RSN_VERSION 580#undef WPA_VERSION 581#undef WPA_OUI_TYPE 582 583static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 584 int reason_code); 585 586static const char * 587ether_sprintf(const u8 *addr) 588{ 589 static char buf[sizeof(MACSTR)]; 590 591 if (addr != NULL) 592 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 593 else 594 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); 595 return buf; 596} 597 598static int 599bsd_set_privacy(void *priv, int enabled) 600{ |
|
327 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); | 601 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); |
328 return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled); | 602 603 return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled); |
329} 330 | 604} 605 |
606static int 607bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 608 u8 *seq) 609{ 610 struct ieee80211req_key wk; |
|
331 | 611 |
612 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 613 __func__, ether_sprintf(addr), idx); 614 615 memset(&wk, 0, sizeof(wk)); 616 if (addr == NULL) 617 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 618 else 619 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 620 wk.ik_keyix = idx; 621 622 if (get80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) { 623 printf("Failed to get encryption.\n"); 624 return -1; 625 } 626 627#ifdef WORDS_BIGENDIAN 628 { 629 /* 630 * wk.ik_keytsc is in host byte order (big endian), need to 631 * swap it to match with the byte order used in WPA. 632 */ 633 int i; 634 u8 tmp[WPA_KEY_RSC_LEN]; 635 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 636 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 637 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 638 } 639 } 640#else /* WORDS_BIGENDIAN */ 641 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 642#endif /* WORDS_BIGENDIAN */ 643 return 0; 644} 645 646 647static int 648bsd_flush(void *priv) 649{ 650 u8 allsta[IEEE80211_ADDR_LEN]; 651 652 memset(allsta, 0xff, IEEE80211_ADDR_LEN); 653 return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE); 654} 655 656 |
|
332static int | 657static int |
333wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled) | 658bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 659 const u8 *addr) |
334{ | 660{ |
335 struct wpa_driver_bsd_data *drv = priv; | 661 struct ieee80211req_sta_stats stats; |
336 | 662 |
663 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 664 if (get80211var(priv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) 665 > 0) { 666 /* XXX? do packets counts include non-data frames? */ 667 data->rx_packets = stats.is_stats.ns_rx_data; 668 data->rx_bytes = stats.is_stats.ns_rx_bytes; 669 data->tx_packets = stats.is_stats.ns_tx_data; 670 data->tx_bytes = stats.is_stats.ns_tx_bytes; 671 } 672 return 0; 673} 674 675static int 676bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code) 677{ 678 return bsd_send_mlme_param(priv, IEEE80211_MLME_DEAUTH, reason_code, 679 addr); 680} 681 682static int 683bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 684 int reason_code) 685{ 686 return bsd_send_mlme_param(priv, IEEE80211_MLME_DISASSOC, reason_code, 687 addr); 688} 689 690static void 691bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx) 692{ 693 struct bsd_driver_data *drv = ctx; 694 char buf[2048]; 695 struct if_announcemsghdr *ifan; 696 struct rt_msghdr *rtm; 697 struct ieee80211_michael_event *mic; 698 struct ieee80211_join_event *join; 699 struct ieee80211_leave_event *leave; 700 int n; 701 union wpa_event_data data; 702 703 n = read(sock, buf, sizeof(buf)); 704 if (n < 0) { 705 if (errno != EINTR && errno != EAGAIN) 706 perror("read(PF_ROUTE)"); 707 return; 708 } 709 710 rtm = (struct rt_msghdr *) buf; 711 if (rtm->rtm_version != RTM_VERSION) { 712 wpa_printf(MSG_DEBUG, "Routing message version %d not " 713 "understood\n", rtm->rtm_version); 714 return; 715 } 716 ifan = (struct if_announcemsghdr *) rtm; 717 switch (rtm->rtm_type) { 718 case RTM_IEEE80211: 719 switch (ifan->ifan_what) { 720 case RTM_IEEE80211_ASSOC: 721 case RTM_IEEE80211_REASSOC: 722 case RTM_IEEE80211_DISASSOC: 723 case RTM_IEEE80211_SCAN: 724 break; 725 case RTM_IEEE80211_LEAVE: 726 leave = (struct ieee80211_leave_event *) &ifan[1]; 727 drv_event_disassoc(drv->hapd, leave->iev_addr); 728 break; 729 case RTM_IEEE80211_JOIN: 730#ifdef RTM_IEEE80211_REJOIN 731 case RTM_IEEE80211_REJOIN: 732#endif 733 join = (struct ieee80211_join_event *) &ifan[1]; 734 bsd_new_sta(drv, drv->hapd, join->iev_addr); 735 break; 736 case RTM_IEEE80211_REPLAY: 737 /* ignore */ 738 break; 739 case RTM_IEEE80211_MICHAEL: 740 mic = (struct ieee80211_michael_event *) &ifan[1]; 741 wpa_printf(MSG_DEBUG, 742 "Michael MIC failure wireless event: " 743 "keyix=%u src_addr=" MACSTR, mic->iev_keyix, 744 MAC2STR(mic->iev_src)); 745 os_memset(&data, 0, sizeof(data)); 746 data.michael_mic_failure.unicast = 1; 747 data.michael_mic_failure.src = mic->iev_src; 748 wpa_supplicant_event(drv->hapd, 749 EVENT_MICHAEL_MIC_FAILURE, &data); 750 break; 751 } 752 break; 753 } 754} 755 756static void 757handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 758{ 759 struct bsd_driver_data *drv = ctx; 760 drv_event_eapol_rx(drv->hapd, src_addr, buf, len); 761} 762 763static int 764hostapd_bsd_set_freq(void *priv, struct hostapd_freq_params *freq) 765{ 766 return bsd_set_freq(priv, freq->channel); 767} 768 769static void * 770bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) 771{ 772 struct bsd_driver_data *drv; 773 774 drv = os_zalloc(sizeof(struct bsd_driver_data)); 775 if (drv == NULL) { 776 printf("Could not allocate memory for bsd driver data\n"); 777 goto bad; 778 } 779 780 drv->hapd = hapd; 781 drv->sock = socket(PF_INET, SOCK_DGRAM, 0); 782 if (drv->sock < 0) { 783 perror("socket[PF_INET,SOCK_DGRAM]"); 784 goto bad; 785 } 786 os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname)); 787 788 drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, 789 handle_read, drv, 0); 790 if (drv->sock_xmit == NULL) 791 goto bad; 792 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) 793 goto bad; 794 795 /* mark down during setup */ 796 if (bsd_ctrl_iface(drv, 0) < 0) 797 goto bad; 798 799 drv->route = socket(PF_ROUTE, SOCK_RAW, 0); 800 if (drv->route < 0) { 801 perror("socket(PF_ROUTE,SOCK_RAW)"); 802 goto bad; 803 } 804 eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv, 805 NULL); 806 807 if (bsd_set_mediaopt(drv, IFM_OMASK, IFM_IEEE80211_HOSTAP) < 0) { 808 wpa_printf(MSG_ERROR, "%s: failed to set operation mode", 809 __func__); 810 goto bad; 811 } 812 813 return drv; 814bad: 815 if (drv->sock_xmit != NULL) 816 l2_packet_deinit(drv->sock_xmit); 817 if (drv->sock >= 0) 818 close(drv->sock); 819 if (drv != NULL) 820 os_free(drv); 821 return NULL; 822} 823 824 825static void 826bsd_deinit(void *priv) 827{ 828 struct bsd_driver_data *drv = priv; 829 830 if (drv->route >= 0) { 831 eloop_unregister_read_sock(drv->route); 832 close(drv->route); 833 } 834 bsd_ctrl_iface(drv, 0); 835 if (drv->sock >= 0) 836 close(drv->sock); 837 if (drv->sock_xmit != NULL) 838 l2_packet_deinit(drv->sock_xmit); 839 os_free(drv); 840} 841 842#else /* HOSTAPD */ 843 844static int 845get80211param(struct bsd_driver_data *drv, int op) 846{ 847 struct ieee80211req ireq; 848 849 if (bsd_get80211(drv, &ireq, op, NULL, 0) < 0) 850 return -1; 851 return ireq.i_val; 852} 853 854static int 855wpa_driver_bsd_get_bssid(void *priv, u8 *bssid) 856{ 857 struct bsd_driver_data *drv = priv; 858#ifdef SIOCG80211BSSID 859 struct ieee80211_bssid bs; 860 861 os_strlcpy(bs.i_name, drv->ifname, sizeof(bs.i_name)); 862 if (ioctl(drv->sock, SIOCG80211BSSID, &bs) < 0) 863 return -1; 864 os_memcpy(bssid, bs.i_bssid, sizeof(bs.i_bssid)); 865 return 0; 866#else 867 return get80211var(drv, IEEE80211_IOC_BSSID, 868 bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0; 869#endif 870} 871 872static int 873wpa_driver_bsd_get_ssid(void *priv, u8 *ssid) 874{ 875 struct bsd_driver_data *drv = priv; 876 return bsd_get_ssid(drv, ssid, 0); 877} 878 879static int 880wpa_driver_bsd_set_wpa_ie(struct bsd_driver_data *drv, const u8 *wpa_ie, 881 size_t wpa_ie_len) 882{ 883#ifdef IEEE80211_IOC_APPIE 884 return bsd_set_opt_ie(drv, wpa_ie, wpa_ie_len); 885#else /* IEEE80211_IOC_APPIE */ 886 return set80211var(drv, IEEE80211_IOC_OPTIE, wpa_ie, wpa_ie_len); 887#endif /* IEEE80211_IOC_APPIE */ 888} 889 890static int 891wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy) 892{ 893 int ret = 0; 894 895 wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d", 896 __FUNCTION__, wpa, privacy); 897 898 if (!wpa && wpa_driver_bsd_set_wpa_ie(priv, NULL, 0) < 0) 899 ret = -1; 900 if (set80211param(priv, IEEE80211_IOC_PRIVACY, privacy) < 0) 901 ret = -1; 902 if (set80211param(priv, IEEE80211_IOC_WPA, wpa) < 0) 903 ret = -1; 904 905 return ret; 906} 907 908static int 909wpa_driver_bsd_set_wpa(void *priv, int enabled) 910{ 911 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 912 913 return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled); 914} 915 916static int 917wpa_driver_bsd_set_countermeasures(void *priv, int enabled) 918{ |
|
337 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); | 919 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); |
338 return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled); | 920 return set80211param(priv, IEEE80211_IOC_COUNTERMEASURES, enabled); |
339} 340 | 921} 922 |
923 |
|
341static int | 924static int |
342wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code) | 925wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled) |
343{ | 926{ |
344 struct wpa_driver_bsd_data *drv = priv; 345 struct ieee80211req_mlme mlme; | 927 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 928 return set80211param(priv, IEEE80211_IOC_DROPUNENCRYPTED, enabled); 929} |
346 | 930 |
347 wpa_printf(MSG_DEBUG, "%s", __func__); 348 os_memset(&mlme, 0, sizeof(mlme)); 349 mlme.im_op = IEEE80211_MLME_DEAUTH; 350 mlme.im_reason = reason_code; 351 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 352 return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); | 931static int 932wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code) 933{ 934 return bsd_send_mlme_param(priv, IEEE80211_MLME_DEAUTH, reason_code, 935 addr); |
353} 354 355static int 356wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code) 357{ | 936} 937 938static int 939wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code) 940{ |
358 struct wpa_driver_bsd_data *drv = priv; 359 struct ieee80211req_mlme mlme; | 941 return bsd_send_mlme_param(priv, IEEE80211_MLME_DISASSOC, reason_code, 942 addr); 943} |
360 | 944 |
361 wpa_printf(MSG_DEBUG, "%s", __func__); 362 os_memset(&mlme, 0, sizeof(mlme)); 363 mlme.im_op = IEEE80211_MLME_DISASSOC; 364 mlme.im_reason = reason_code; 365 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 366 return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); | 945static int 946wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg) 947{ 948 int authmode; 949 950 if ((auth_alg & WPA_AUTH_ALG_OPEN) && 951 (auth_alg & WPA_AUTH_ALG_SHARED)) 952 authmode = IEEE80211_AUTH_AUTO; 953 else if (auth_alg & WPA_AUTH_ALG_SHARED) 954 authmode = IEEE80211_AUTH_SHARED; 955 else 956 authmode = IEEE80211_AUTH_OPEN; 957 958 return set80211param(priv, IEEE80211_IOC_AUTHMODE, authmode); |
367} 368 | 959} 960 |
961static void 962handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 963{ 964 struct bsd_driver_data *drv = ctx; 965 966 drv_event_eapol_rx(drv->ctx, src_addr, buf, len); 967} 968 |
|
369static int 370wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) 371{ | 969static int 970wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) 971{ |
372 struct wpa_driver_bsd_data *drv = priv; | 972 struct bsd_driver_data *drv = priv; |
373 struct ieee80211req_mlme mlme; | 973 struct ieee80211req_mlme mlme; |
974 u32 mode; 975 u16 channel; |
|
374 int privacy; | 976 int privacy; |
977 int ret = 0; |
|
375 376 wpa_printf(MSG_DEBUG, 377 "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u" 378 , __func__ | 978 979 wpa_printf(MSG_DEBUG, 980 "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u" 981 , __func__ |
379 , params->ssid_len, params->ssid 380 , params->wpa_ie_len | 982 , (unsigned int) params->ssid_len, params->ssid 983 , (unsigned int) params->wpa_ie_len |
381 , params->pairwise_suite 382 , params->group_suite 383 , params->key_mgmt_suite 384 ); 385 | 984 , params->pairwise_suite 985 , params->group_suite 986 , params->key_mgmt_suite 987 ); 988 |
989 switch (params->mode) { 990 case IEEE80211_MODE_INFRA: 991 mode = 0 /* STA */; 992 break; 993 case IEEE80211_MODE_IBSS: 994 mode = IFM_IEEE80211_IBSS; 995 break; 996 case IEEE80211_MODE_AP: 997 mode = IFM_IEEE80211_HOSTAP; 998 break; 999 default: 1000 wpa_printf(MSG_ERROR, "%s: unknown operation mode", __func__); 1001 return -1; 1002 } 1003 if (bsd_set_mediaopt(drv, IFM_OMASK, mode) < 0) { 1004 wpa_printf(MSG_ERROR, "%s: failed to set operation mode", 1005 __func__); 1006 return -1; 1007 } 1008 1009 if (params->mode == IEEE80211_MODE_AP) { 1010 if (params->freq >= 2412 && params->freq <= 2472) 1011 channel = (params->freq - 2407) / 5; 1012 else if (params->freq == 2484) 1013 channel = 14; 1014 else if ((params->freq >= 5180 && params->freq <= 5240) || 1015 (params->freq >= 5745 && params->freq <= 5825)) 1016 channel = (params->freq - 5000) / 5; 1017 else 1018 channel = 0; 1019 if (bsd_set_freq(drv, channel) < 0) 1020 return -1; 1021 1022 drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, 1023 handle_read, drv, 0); 1024 if (drv->sock_xmit == NULL) 1025 return -1; 1026 drv->is_ap = 1; 1027 return 0; 1028 } 1029 1030 if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted) 1031 < 0) 1032 ret = -1; 1033 if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0) 1034 ret = -1; |
|
386 /* XXX error handling is wrong but unclear what to do... */ 387 if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) 388 return -1; 389 390 privacy = !(params->pairwise_suite == CIPHER_NONE && 391 params->group_suite == CIPHER_NONE && 392 params->key_mgmt_suite == KEY_MGMT_NONE && 393 params->wpa_ie_len == 0); --- 11 unchanged lines hidden (view full) --- 405 mlme.im_op = IEEE80211_MLME_ASSOC; 406 if (params->ssid != NULL) 407 os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len); 408 mlme.im_ssid_len = params->ssid_len; 409 if (params->bssid != NULL) 410 os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); 411 if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) 412 return -1; | 1035 /* XXX error handling is wrong but unclear what to do... */ 1036 if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) 1037 return -1; 1038 1039 privacy = !(params->pairwise_suite == CIPHER_NONE && 1040 params->group_suite == CIPHER_NONE && 1041 params->key_mgmt_suite == KEY_MGMT_NONE && 1042 params->wpa_ie_len == 0); --- 11 unchanged lines hidden (view full) --- 1054 mlme.im_op = IEEE80211_MLME_ASSOC; 1055 if (params->ssid != NULL) 1056 os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len); 1057 mlme.im_ssid_len = params->ssid_len; 1058 if (params->bssid != NULL) 1059 os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); 1060 if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) 1061 return -1; |
413 return 0; | 1062 return ret; |
414} 415 416static int | 1063} 1064 1065static int |
417wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg) | 1066wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params) |
418{ | 1067{ |
419 struct wpa_driver_bsd_data *drv = priv; 420 int authmode; | 1068 struct bsd_driver_data *drv = priv; 1069#ifdef IEEE80211_IOC_SCAN_MAX_SSID 1070 struct ieee80211_scan_req sr; 1071 int i; 1072#endif /* IEEE80211_IOC_SCAN_MAX_SSID */ |
421 | 1073 |
422 if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) && 423 (auth_alg & AUTH_ALG_SHARED_KEY)) 424 authmode = IEEE80211_AUTH_AUTO; 425 else if (auth_alg & AUTH_ALG_SHARED_KEY) 426 authmode = IEEE80211_AUTH_SHARED; 427 else 428 authmode = IEEE80211_AUTH_OPEN; | 1074 if (bsd_set_mediaopt(drv, IFM_OMASK, 0 /* STA */) < 0) { 1075 wpa_printf(MSG_ERROR, "%s: failed to set operation mode", 1076 __func__); 1077 return -1; 1078 } |
429 | 1079 |
430 return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode); 431} | 1080 if (set80211param(drv, IEEE80211_IOC_ROAMING, 1081 IEEE80211_ROAMING_MANUAL) < 0) { 1082 wpa_printf(MSG_ERROR, "%s: failed to set " 1083 "wpa_supplicant-based roaming: %s", __func__, 1084 strerror(errno)); 1085 return -1; 1086 } |
432 | 1087 |
433static int 434wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len) 435{ 436 struct wpa_driver_bsd_data *drv = priv; 437 int flags; | 1088 if (wpa_driver_bsd_set_wpa(drv, 1) < 0) { 1089 wpa_printf(MSG_ERROR, "%s: failed to set wpa: %s", __func__, 1090 strerror(errno)); 1091 return -1; 1092 } |
438 439 /* NB: interface must be marked UP to do a scan */ | 1093 1094 /* NB: interface must be marked UP to do a scan */ |
440 if (getifflags(drv, &flags) != 0 || setifflags(drv, flags | IFF_UP) != 0) | 1095 if (bsd_ctrl_iface(drv, 1) < 0) |
441 return -1; 442 | 1096 return -1; 1097 |
1098#ifdef IEEE80211_IOC_SCAN_MAX_SSID 1099 os_memset(&sr, 0, sizeof(sr)); 1100 sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE | 1101 IEEE80211_IOC_SCAN_NOJOIN; 1102 sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER; 1103 if (params->num_ssids > 0) { 1104 sr.sr_nssid = params->num_ssids; 1105#if 0 1106 /* Boundary check is done by upper layer */ 1107 if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID) 1108 sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID; 1109#endif 1110 1111 /* NB: check scan cache first */ 1112 sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK; 1113 } 1114 for (i = 0; i < sr.sr_nssid; i++) { 1115 sr.sr_ssid[i].len = params->ssids[i].ssid_len; 1116 os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid, 1117 sr.sr_ssid[i].len); 1118 } 1119 1120 /* NB: net80211 delivers a scan complete event so no need to poll */ 1121 return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr)); 1122#else /* IEEE80211_IOC_SCAN_MAX_SSID */ |
|
443 /* set desired ssid before scan */ | 1123 /* set desired ssid before scan */ |
444 if (wpa_driver_bsd_set_ssid(drv, ssid, ssid_len) < 0) | 1124 if (bsd_set_ssid(drv, params->ssids[0].ssid, 1125 params->ssids[0].ssid_len) < 0) |
445 return -1; 446 447 /* NB: net80211 delivers a scan complete event so no need to poll */ 448 return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0); | 1126 return -1; 1127 1128 /* NB: net80211 delivers a scan complete event so no need to poll */ 1129 return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0); |
1130#endif /* IEEE80211_IOC_SCAN_MAX_SSID */ |
|
449} 450 | 1131} 1132 |
451#include <net/route.h> 452#if __FreeBSD__ 453#include <net80211/ieee80211_freebsd.h> 454#endif 455#if __NetBSD__ 456#include <net80211/ieee80211_netbsd.h> 457#endif 458 | |
459static void 460wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx) 461{ | 1133static void 1134wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx) 1135{ |
462 struct wpa_driver_bsd_data *drv = sock_ctx; | 1136 struct bsd_driver_data *drv = sock_ctx; |
463 char buf[2048]; 464 struct if_announcemsghdr *ifan; 465 struct if_msghdr *ifm; 466 struct rt_msghdr *rtm; 467 union wpa_event_data event; 468 struct ieee80211_michael_event *mic; | 1137 char buf[2048]; 1138 struct if_announcemsghdr *ifan; 1139 struct if_msghdr *ifm; 1140 struct rt_msghdr *rtm; 1141 union wpa_event_data event; 1142 struct ieee80211_michael_event *mic; |
1143 struct ieee80211_leave_event *leave; 1144 struct ieee80211_join_event *join; |
|
469 int n; 470 471 n = read(sock, buf, sizeof(buf)); 472 if (n < 0) { 473 if (errno != EINTR && errno != EAGAIN) 474 perror("read(PF_ROUTE)"); 475 return; 476 } --- 5 unchanged lines hidden (view full) --- 482 return; 483 } 484 os_memset(&event, 0, sizeof(event)); 485 switch (rtm->rtm_type) { 486 case RTM_IFANNOUNCE: 487 ifan = (struct if_announcemsghdr *) rtm; 488 if (ifan->ifan_index != drv->ifindex) 489 break; | 1145 int n; 1146 1147 n = read(sock, buf, sizeof(buf)); 1148 if (n < 0) { 1149 if (errno != EINTR && errno != EAGAIN) 1150 perror("read(PF_ROUTE)"); 1151 return; 1152 } --- 5 unchanged lines hidden (view full) --- 1158 return; 1159 } 1160 os_memset(&event, 0, sizeof(event)); 1161 switch (rtm->rtm_type) { 1162 case RTM_IFANNOUNCE: 1163 ifan = (struct if_announcemsghdr *) rtm; 1164 if (ifan->ifan_index != drv->ifindex) 1165 break; |
490 strlcpy(event.interface_status.ifname, drv->ifname, 491 sizeof(event.interface_status.ifname)); | 1166 os_strlcpy(event.interface_status.ifname, drv->ifname, 1167 sizeof(event.interface_status.ifname)); |
492 switch (ifan->ifan_what) { 493 case IFAN_DEPARTURE: 494 event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 495 default: 496 return; 497 } 498 wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s", 499 event.interface_status.ifname, 500 ifan->ifan_what == IFAN_DEPARTURE ? 501 "removed" : "added"); 502 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); 503 break; 504 case RTM_IEEE80211: 505 ifan = (struct if_announcemsghdr *) rtm; 506 if (ifan->ifan_index != drv->ifindex) 507 break; 508 switch (ifan->ifan_what) { 509 case RTM_IEEE80211_ASSOC: 510 case RTM_IEEE80211_REASSOC: | 1168 switch (ifan->ifan_what) { 1169 case IFAN_DEPARTURE: 1170 event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 1171 default: 1172 return; 1173 } 1174 wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s", 1175 event.interface_status.ifname, 1176 ifan->ifan_what == IFAN_DEPARTURE ? 1177 "removed" : "added"); 1178 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); 1179 break; 1180 case RTM_IEEE80211: 1181 ifan = (struct if_announcemsghdr *) rtm; 1182 if (ifan->ifan_index != drv->ifindex) 1183 break; 1184 switch (ifan->ifan_what) { 1185 case RTM_IEEE80211_ASSOC: 1186 case RTM_IEEE80211_REASSOC: |
1187 if (drv->is_ap) 1188 break; |
|
511 wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); 512 break; 513 case RTM_IEEE80211_DISASSOC: | 1189 wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); 1190 break; 1191 case RTM_IEEE80211_DISASSOC: |
1192 if (drv->is_ap) 1193 break; |
|
514 wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); 515 break; 516 case RTM_IEEE80211_SCAN: | 1194 wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); 1195 break; 1196 case RTM_IEEE80211_SCAN: |
1197 if (drv->is_ap) 1198 break; |
|
517 wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL); 518 break; | 1199 wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL); 1200 break; |
1201 case RTM_IEEE80211_LEAVE: 1202 leave = (struct ieee80211_leave_event *) &ifan[1]; 1203 drv_event_disassoc(ctx, leave->iev_addr); 1204 break; 1205 case RTM_IEEE80211_JOIN: 1206#ifdef RTM_IEEE80211_REJOIN 1207 case RTM_IEEE80211_REJOIN: 1208#endif 1209 join = (struct ieee80211_join_event *) &ifan[1]; 1210 bsd_new_sta(drv, ctx, join->iev_addr); 1211 break; |
|
519 case RTM_IEEE80211_REPLAY: 520 /* ignore */ 521 break; 522 case RTM_IEEE80211_MICHAEL: 523 mic = (struct ieee80211_michael_event *) &ifan[1]; 524 wpa_printf(MSG_DEBUG, 525 "Michael MIC failure wireless event: " 526 "keyix=%u src_addr=" MACSTR, mic->iev_keyix, --- 7 unchanged lines hidden (view full) --- 534 break; 535 } 536 break; 537 case RTM_IFINFO: 538 ifm = (struct if_msghdr *) rtm; 539 if (ifm->ifm_index != drv->ifindex) 540 break; 541 if ((rtm->rtm_flags & RTF_UP) == 0) { | 1212 case RTM_IEEE80211_REPLAY: 1213 /* ignore */ 1214 break; 1215 case RTM_IEEE80211_MICHAEL: 1216 mic = (struct ieee80211_michael_event *) &ifan[1]; 1217 wpa_printf(MSG_DEBUG, 1218 "Michael MIC failure wireless event: " 1219 "keyix=%u src_addr=" MACSTR, mic->iev_keyix, --- 7 unchanged lines hidden (view full) --- 1227 break; 1228 } 1229 break; 1230 case RTM_IFINFO: 1231 ifm = (struct if_msghdr *) rtm; 1232 if (ifm->ifm_index != drv->ifindex) 1233 break; 1234 if ((rtm->rtm_flags & RTF_UP) == 0) { |
542 strlcpy(event.interface_status.ifname, drv->ifname, 543 sizeof(event.interface_status.ifname)); | 1235 os_strlcpy(event.interface_status.ifname, drv->ifname, 1236 sizeof(event.interface_status.ifname)); |
544 event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 545 wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN", 546 event.interface_status.ifname); 547 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); 548 } 549 break; 550 } 551} 552 | 1237 event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 1238 wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN", 1239 event.interface_status.ifname); 1240 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); 1241 } 1242 break; 1243 } 1244} 1245 |
553/* Compare function for sorting scan results. Return >0 if @b is consider 554 * better. */ 555static int 556wpa_scan_result_compar(const void *a, const void *b) | 1246static void 1247wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res, 1248 struct ieee80211req_scan_result *sr) |
557{ | 1249{ |
558 const struct wpa_scan_result *wa = a; 559 const struct wpa_scan_result *wb = b; | 1250 struct wpa_scan_res *result, **tmp; 1251 size_t extra_len; 1252 u8 *pos; |
560 | 1253 |
561 /* WPA/WPA2 support preferred */ 562 if ((wb->wpa_ie_len || wb->rsn_ie_len) && 563 !(wa->wpa_ie_len || wa->rsn_ie_len)) 564 return 1; 565 if (!(wb->wpa_ie_len || wb->rsn_ie_len) && 566 (wa->wpa_ie_len || wa->rsn_ie_len)) 567 return -1; | 1254 extra_len = 2 + sr->isr_ssid_len; 1255 extra_len += 2 + sr->isr_nrates; 1256 extra_len += 3; /* ERP IE */ 1257 extra_len += sr->isr_ie_len; |
568 | 1258 |
569 /* privacy support preferred */ 570 if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) && 571 (wb->caps & IEEE80211_CAPINFO_PRIVACY) == 0) 572 return 1; 573 if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) == 0 && 574 (wb->caps & IEEE80211_CAPINFO_PRIVACY)) 575 return -1; | 1259 result = os_zalloc(sizeof(*result) + extra_len); 1260 if (result == NULL) 1261 return; 1262 os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN); 1263 result->freq = sr->isr_freq; 1264 result->beacon_int = sr->isr_intval; 1265 result->caps = sr->isr_capinfo; 1266 result->qual = sr->isr_rssi; 1267 result->noise = sr->isr_noise; |
576 | 1268 |
577 /* best/max rate preferred if signal level close enough XXX */ 578 if (wa->maxrate != wb->maxrate && abs(wb->level - wa->level) < 5) 579 return wb->maxrate - wa->maxrate; | 1269 pos = (u8 *)(result + 1); |
580 | 1270 |
581 /* use freq for channel preference */ | 1271 *pos++ = WLAN_EID_SSID; 1272 *pos++ = sr->isr_ssid_len; 1273 os_memcpy(pos, sr + 1, sr->isr_ssid_len); 1274 pos += sr->isr_ssid_len; |
582 | 1275 |
583 /* all things being equal, use signal level */ 584 return wb->level - wa->level; | 1276 /* 1277 * Deal all rates as supported rate. 1278 * Because net80211 doesn't report extended supported rate or not. 1279 */ 1280 *pos++ = WLAN_EID_SUPP_RATES; 1281 *pos++ = sr->isr_nrates; 1282 os_memcpy(pos, sr->isr_rates, sr->isr_nrates); 1283 pos += sr->isr_nrates; 1284 1285 *pos++ = WLAN_EID_ERP_INFO; 1286 *pos++ = 1; 1287 *pos++ = sr->isr_erp; 1288 1289 os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len); 1290 pos += sr->isr_ie_len; 1291 1292 result->ie_len = pos - (u8 *)(result + 1); 1293 1294 tmp = os_realloc(res->res, 1295 (res->num + 1) * sizeof(struct wpa_scan_res *)); 1296 if (tmp == NULL) { 1297 os_free(result); 1298 return; 1299 } 1300 tmp[res->num++] = result; 1301 res->res = tmp; |
585} 586 | 1302} 1303 |
587static int 588getmaxrate(uint8_t rates[15], uint8_t nrates) | 1304struct wpa_scan_results * 1305wpa_driver_bsd_get_scan_results2(void *priv) |
589{ | 1306{ |
590 int i, maxrate = -1; | 1307 struct ieee80211req_scan_result *sr; 1308 struct wpa_scan_results *res; 1309 int len, rest; 1310 uint8_t buf[24*1024], *pos; |
591 | 1311 |
592 for (i = 0; i < nrates; i++) { 593 int rate = rates[i] & IEEE80211_RATE_VAL; 594 if (rate > maxrate) 595 rate = maxrate; | 1312 len = get80211var(priv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024); 1313 if (len < 0) 1314 return NULL; 1315 1316 res = os_zalloc(sizeof(*res)); 1317 if (res == NULL) 1318 return NULL; 1319 1320 pos = buf; 1321 rest = len; 1322 while (rest >= sizeof(struct ieee80211req_scan_result)) { 1323 sr = (struct ieee80211req_scan_result *)pos; 1324 wpa_driver_bsd_add_scan_entry(res, sr); 1325 pos += sr->isr_len; 1326 rest -= sr->isr_len; |
596 } | 1327 } |
597 return maxrate; 598} | |
599 | 1328 |
600/* unalligned little endian access */ 601#define LE_READ_4(p) \ 602 ((u_int32_t) \ 603 ((((const u_int8_t *)(p))[0] ) | \ 604 (((const u_int8_t *)(p))[1] << 8) | \ 605 (((const u_int8_t *)(p))[2] << 16) | \ 606 (((const u_int8_t *)(p))[3] << 24))) | 1329 wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)", 1330 len, (unsigned long)res->num); |
607 | 1331 |
608static int __inline 609iswpaoui(const u_int8_t *frm) 610{ 611 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); | 1332 return res; |
612} 613 | 1333} 1334 |
614static int 615wpa_driver_bsd_get_scan_results(void *priv, 616 struct wpa_scan_result *results, 617 size_t max_size) | 1335static int wpa_driver_bsd_capa(struct bsd_driver_data *drv) |
618{ | 1336{ |
619#define min(a,b) ((a)>(b)?(b):(a)) 620 struct wpa_driver_bsd_data *drv = priv; 621 uint8_t buf[24*1024]; 622 uint8_t *cp, *vp; 623 struct ieee80211req_scan_result *sr; 624 struct wpa_scan_result *wsr; 625 int len, ielen; | 1337#ifdef IEEE80211_IOC_DEVCAPS 1338/* kernel definitions copied from net80211/ieee80211_var.h */ 1339#define IEEE80211_CIPHER_WEP 0 1340#define IEEE80211_CIPHER_TKIP 1 1341#define IEEE80211_CIPHER_AES_CCM 3 1342#define IEEE80211_CRYPTO_WEP (1<<IEEE80211_CIPHER_WEP) 1343#define IEEE80211_CRYPTO_TKIP (1<<IEEE80211_CIPHER_TKIP) 1344#define IEEE80211_CRYPTO_AES_CCM (1<<IEEE80211_CIPHER_AES_CCM) 1345#define IEEE80211_C_HOSTAP 0x00000400 /* CAPABILITY: HOSTAP avail */ 1346#define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */ 1347#define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */ 1348 struct ieee80211_devcaps_req devcaps; |
626 | 1349 |
627 os_memset(results, 0, max_size * sizeof(struct wpa_scan_result)); 628 629 len = get80211var(drv, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf)); 630 if (len < 0) | 1350 if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps, 1351 sizeof(devcaps)) < 0) { 1352 wpa_printf(MSG_ERROR, "failed to IEEE80211_IOC_DEVCAPS: %s", 1353 strerror(errno)); |
631 return -1; | 1354 return -1; |
632 cp = buf; 633 wsr = results; 634 while (len >= sizeof(struct ieee80211req_scan_result)) { 635 sr = (struct ieee80211req_scan_result *) cp; 636 os_memcpy(wsr->bssid, sr->isr_bssid, IEEE80211_ADDR_LEN); 637 wsr->ssid_len = sr->isr_ssid_len; 638 wsr->freq = sr->isr_freq; 639 wsr->noise = sr->isr_noise; 640 wsr->qual = sr->isr_rssi; 641 wsr->level = 0; /* XXX? */ 642 wsr->caps = sr->isr_capinfo; 643 wsr->maxrate = getmaxrate(sr->isr_rates, sr->isr_nrates); 644 vp = (u_int8_t *)(sr+1); 645 os_memcpy(wsr->ssid, vp, sr->isr_ssid_len); 646 if (sr->isr_ie_len > 0) { 647 vp += sr->isr_ssid_len; 648 ielen = sr->isr_ie_len; 649 while (ielen > 0) { 650 switch (vp[0]) { 651 case IEEE80211_ELEMID_VENDOR: 652 if (!iswpaoui(vp)) 653 break; 654 wsr->wpa_ie_len = 655 min(2+vp[1], SSID_MAX_WPA_IE_LEN); 656 os_memcpy(wsr->wpa_ie, vp, 657 wsr->wpa_ie_len); 658 break; 659 case IEEE80211_ELEMID_RSN: 660 wsr->rsn_ie_len = 661 min(2+vp[1], SSID_MAX_WPA_IE_LEN); 662 os_memcpy(wsr->rsn_ie, vp, 663 wsr->rsn_ie_len); 664 break; 665 } 666 ielen -= 2+vp[1]; 667 vp += 2+vp[1]; 668 } 669 } 670 671 cp += sr->isr_len, len -= sr->isr_len; 672 wsr++; | |
673 } | 1355 } |
674 qsort(results, wsr - results, sizeof(struct wpa_scan_result), 675 wpa_scan_result_compar); | |
676 | 1356 |
677 wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%d BSSes)", 678 len, wsr - results); | 1357 wpa_printf(MSG_DEBUG, "%s: drivercaps=0x%08x,cryptocaps=0x%08x", 1358 __func__, devcaps.dc_drivercaps, devcaps.dc_cryptocaps); |
679 | 1359 |
680 return wsr - results; 681#undef min | 1360 if (devcaps.dc_drivercaps & IEEE80211_C_WPA1) 1361 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1362 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; 1363 if (devcaps.dc_drivercaps & IEEE80211_C_WPA2) 1364 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 1365 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; 1366 1367 if (devcaps.dc_cryptocaps & IEEE80211_CRYPTO_WEP) 1368 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | 1369 WPA_DRIVER_CAPA_ENC_WEP104; 1370 if (devcaps.dc_cryptocaps & IEEE80211_CRYPTO_TKIP) 1371 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; 1372 if (devcaps.dc_cryptocaps & IEEE80211_CRYPTO_AES_CCM) 1373 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; 1374 1375 if (devcaps.dc_drivercaps & IEEE80211_C_HOSTAP) 1376 drv->capa.flags |= WPA_DRIVER_FLAGS_AP; 1377#undef IEEE80211_CIPHER_WEP 1378#undef IEEE80211_CIPHER_TKIP 1379#undef IEEE80211_CIPHER_AES_CCM 1380#undef IEEE80211_CRYPTO_WEP 1381#undef IEEE80211_CRYPTO_TKIP 1382#undef IEEE80211_CRYPTO_AES_CCM 1383#undef IEEE80211_C_HOSTAP 1384#undef IEEE80211_C_WPA1 1385#undef IEEE80211_C_WPA2 1386#else /* IEEE80211_IOC_DEVCAPS */ 1387 /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */ 1388 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1389 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 1390 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 1391 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; 1392 drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 | 1393 WPA_DRIVER_CAPA_ENC_WEP104 | 1394 WPA_DRIVER_CAPA_ENC_TKIP | 1395 WPA_DRIVER_CAPA_ENC_CCMP; 1396 drv->capa.flags |= WPA_DRIVER_FLAGS_AP; 1397#endif /* IEEE80211_IOC_DEVCAPS */ 1398#ifdef IEEE80211_IOC_SCAN_MAX_SSID 1399 drv->capa.max_scan_ssids = IEEE80211_IOC_SCAN_MAX_SSID; 1400#else /* IEEE80211_IOC_SCAN_MAX_SSID */ 1401 drv->capa.max_scan_ssids = 1; 1402#endif /* IEEE80211_IOC_SCAN_MAX_SSID */ 1403 drv->capa.auth = WPA_DRIVER_AUTH_OPEN | 1404 WPA_DRIVER_AUTH_SHARED | 1405 WPA_DRIVER_AUTH_LEAP; 1406 return 0; |
682} 683 684static void * 685wpa_driver_bsd_init(void *ctx, const char *ifname) 686{ 687#define GETPARAM(drv, param, v) \ 688 (((v) = get80211param(drv, param)) != -1) | 1407} 1408 1409static void * 1410wpa_driver_bsd_init(void *ctx, const char *ifname) 1411{ 1412#define GETPARAM(drv, param, v) \ 1413 (((v) = get80211param(drv, param)) != -1) |
689 struct wpa_driver_bsd_data *drv; | 1414 struct bsd_driver_data *drv; |
690 691 drv = os_zalloc(sizeof(*drv)); 692 if (drv == NULL) 693 return NULL; 694 /* 695 * NB: We require the interface name be mappable to an index. 696 * This implies we do not support having wpa_supplicant 697 * wait for an interface to appear. This seems ok; that --- 12 unchanged lines hidden (view full) --- 710 if (drv->route < 0) 711 goto fail; 712 eloop_register_read_sock(drv->route, 713 wpa_driver_bsd_event_receive, ctx, drv); 714 715 drv->ctx = ctx; 716 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 717 | 1415 1416 drv = os_zalloc(sizeof(*drv)); 1417 if (drv == NULL) 1418 return NULL; 1419 /* 1420 * NB: We require the interface name be mappable to an index. 1421 * This implies we do not support having wpa_supplicant 1422 * wait for an interface to appear. This seems ok; that --- 12 unchanged lines hidden (view full) --- 1435 if (drv->route < 0) 1436 goto fail; 1437 eloop_register_read_sock(drv->route, 1438 wpa_driver_bsd_event_receive, ctx, drv); 1439 1440 drv->ctx = ctx; 1441 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 1442 |
1443 /* Down interface during setup. */ 1444 if (bsd_ctrl_iface(drv, 0) < 0) 1445 goto fail; 1446 |
|
718 if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { 719 wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", 720 __func__, strerror(errno)); 721 goto fail; 722 } 723 if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) { 724 wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s", 725 __func__, strerror(errno)); 726 goto fail; 727 } 728 if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) { 729 wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s", 730 __func__, strerror(errno)); 731 goto fail; 732 } | 1447 if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { 1448 wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", 1449 __func__, strerror(errno)); 1450 goto fail; 1451 } 1452 if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) { 1453 wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s", 1454 __func__, strerror(errno)); 1455 goto fail; 1456 } 1457 if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) { 1458 wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s", 1459 __func__, strerror(errno)); 1460 goto fail; 1461 } |
733 if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) { 734 wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " 735 "roaming: %s", __func__, strerror(errno)); 736 goto fail; 737 } | |
738 | 1462 |
739 if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) { 740 wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s", 741 __func__, strerror(errno)); | 1463 if (wpa_driver_bsd_capa(drv)) |
742 goto fail; | 1464 goto fail; |
743 } | |
744 745 return drv; 746fail: 747 close(drv->sock); 748fail1: 749 os_free(drv); 750 return NULL; 751#undef GETPARAM 752} 753 754static void 755wpa_driver_bsd_deinit(void *priv) 756{ | 1465 1466 return drv; 1467fail: 1468 close(drv->sock); 1469fail1: 1470 os_free(drv); 1471 return NULL; 1472#undef GETPARAM 1473} 1474 1475static void 1476wpa_driver_bsd_deinit(void *priv) 1477{ |
757 struct wpa_driver_bsd_data *drv = priv; 758 int flags; | 1478 struct bsd_driver_data *drv = priv; |
759 | 1479 |
1480 wpa_driver_bsd_set_wpa(drv, 0); |
|
760 eloop_unregister_read_sock(drv->route); 761 762 /* NB: mark interface down */ | 1481 eloop_unregister_read_sock(drv->route); 1482 1483 /* NB: mark interface down */ |
763 if (getifflags(drv, &flags) == 0) 764 (void) setifflags(drv, flags &~ IFF_UP); | 1484 bsd_ctrl_iface(drv, 0); |
765 766 wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); 767 if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) 768 wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state", 769 __func__); 770 | 1485 1486 wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); 1487 if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) 1488 wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state", 1489 __func__); 1490 |
1491 if (drv->sock_xmit != NULL) 1492 l2_packet_deinit(drv->sock_xmit); |
|
771 (void) close(drv->route); /* ioctl socket */ 772 (void) close(drv->sock); /* event socket */ 773 os_free(drv); 774} 775 | 1493 (void) close(drv->route); /* ioctl socket */ 1494 (void) close(drv->sock); /* event socket */ 1495 os_free(drv); 1496} 1497 |
1498static int 1499wpa_driver_bsd_get_capa(void *priv, struct wpa_driver_capa *capa) 1500{ 1501 struct bsd_driver_data *drv = priv; |
|
776 | 1502 |
1503 os_memcpy(capa, &drv->capa, sizeof(*capa)); 1504 return 0; 1505} 1506#endif /* HOSTAPD */ 1507 1508 |
|
777const struct wpa_driver_ops wpa_driver_bsd_ops = { 778 .name = "bsd", | 1509const struct wpa_driver_ops wpa_driver_bsd_ops = { 1510 .name = "bsd", |
779 .desc = "BSD 802.11 support (Atheros, etc.)", | 1511 .desc = "BSD 802.11 support", 1512#ifdef HOSTAPD 1513 .hapd_init = bsd_init, 1514 .hapd_deinit = bsd_deinit, 1515 .set_privacy = bsd_set_privacy, 1516 .get_seqnum = bsd_get_seqnum, 1517 .flush = bsd_flush, 1518 .read_sta_data = bsd_read_sta_driver_data, 1519 .sta_disassoc = bsd_sta_disassoc, 1520 .sta_deauth = bsd_sta_deauth, 1521 .set_freq = hostapd_bsd_set_freq, 1522#else /* HOSTAPD */ |
780 .init = wpa_driver_bsd_init, 781 .deinit = wpa_driver_bsd_deinit, 782 .get_bssid = wpa_driver_bsd_get_bssid, 783 .get_ssid = wpa_driver_bsd_get_ssid, | 1523 .init = wpa_driver_bsd_init, 1524 .deinit = wpa_driver_bsd_deinit, 1525 .get_bssid = wpa_driver_bsd_get_bssid, 1526 .get_ssid = wpa_driver_bsd_get_ssid, |
784 .set_wpa = wpa_driver_bsd_set_wpa, 785 .set_key = wpa_driver_bsd_set_key, | |
786 .set_countermeasures = wpa_driver_bsd_set_countermeasures, | 1527 .set_countermeasures = wpa_driver_bsd_set_countermeasures, |
787 .set_drop_unencrypted = wpa_driver_bsd_set_drop_unencrypted, 788 .scan = wpa_driver_bsd_scan, 789 .get_scan_results = wpa_driver_bsd_get_scan_results, | 1528 .scan2 = wpa_driver_bsd_scan, 1529 .get_scan_results2 = wpa_driver_bsd_get_scan_results2, |
790 .deauthenticate = wpa_driver_bsd_deauthenticate, 791 .disassociate = wpa_driver_bsd_disassociate, 792 .associate = wpa_driver_bsd_associate, | 1530 .deauthenticate = wpa_driver_bsd_deauthenticate, 1531 .disassociate = wpa_driver_bsd_disassociate, 1532 .associate = wpa_driver_bsd_associate, |
793 .set_auth_alg = wpa_driver_bsd_set_auth_alg, | 1533 .get_capa = wpa_driver_bsd_get_capa, 1534#endif /* HOSTAPD */ 1535 .set_key = bsd_set_key, 1536 .set_ieee8021x = bsd_set_ieee8021x, 1537 .hapd_set_ssid = bsd_set_ssid, 1538 .hapd_get_ssid = bsd_get_ssid, 1539 .hapd_send_eapol = bsd_send_eapol, 1540 .sta_set_flags = bsd_set_sta_authorized, 1541 .set_generic_elem = bsd_set_opt_ie, |
794}; | 1542}; |