2 * Received Management frame processing
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "common/ieee802_11_defs.h"
19 #include "common/ieee802_11_common.h"
23 static const char * mgmt_stype(u16 stype)
26 case WLAN_FC_STYPE_ASSOC_REQ:
28 case WLAN_FC_STYPE_ASSOC_RESP:
30 case WLAN_FC_STYPE_REASSOC_REQ:
32 case WLAN_FC_STYPE_REASSOC_RESP:
33 return "REASSOC-RESP";
34 case WLAN_FC_STYPE_PROBE_REQ:
36 case WLAN_FC_STYPE_PROBE_RESP:
38 case WLAN_FC_STYPE_BEACON:
40 case WLAN_FC_STYPE_ATIM:
42 case WLAN_FC_STYPE_DISASSOC:
44 case WLAN_FC_STYPE_AUTH:
46 case WLAN_FC_STYPE_DEAUTH:
48 case WLAN_FC_STYPE_ACTION:
55 static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
57 const struct ieee80211_mgmt *mgmt;
58 struct wlantest_bss *bss;
59 struct ieee802_11_elems elems;
61 mgmt = (const struct ieee80211_mgmt *) data;
62 bss = bss_get(wt, mgmt->bssid);
65 if (bss->proberesp_seen)
66 return; /* do not override with Beacon data */
67 bss->capab_info = le_to_host16(mgmt->u.beacon.capab_info);
68 if (ieee802_11_parse_elems(mgmt->u.beacon.variable,
69 len - (mgmt->u.beacon.variable - data),
70 &elems, 0) == ParseFailed) {
71 if (bss->parse_error_reported)
73 wpa_printf(MSG_INFO, "Invalid IEs in a Beacon frame from "
74 MACSTR, MAC2STR(mgmt->sa));
75 bss->parse_error_reported = 1;
79 bss_update(bss, &elems);
83 static void rx_mgmt_probe_resp(struct wlantest *wt, const u8 *data, size_t len)
85 const struct ieee80211_mgmt *mgmt;
86 struct wlantest_bss *bss;
87 struct ieee802_11_elems elems;
89 mgmt = (const struct ieee80211_mgmt *) data;
90 bss = bss_get(wt, mgmt->bssid);
94 bss->capab_info = le_to_host16(mgmt->u.probe_resp.capab_info);
95 if (ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
96 len - (mgmt->u.probe_resp.variable - data),
97 &elems, 0) == ParseFailed) {
98 if (bss->parse_error_reported)
100 wpa_printf(MSG_INFO, "Invalid IEs in a Probe Response frame "
101 "from " MACSTR, MAC2STR(mgmt->sa));
102 bss->parse_error_reported = 1;
106 bss_update(bss, &elems);
110 static void rx_mgmt_auth(struct wlantest *wt, const u8 *data, size_t len)
112 const struct ieee80211_mgmt *mgmt;
113 struct wlantest_bss *bss;
114 struct wlantest_sta *sta;
115 u16 alg, trans, status;
117 mgmt = (const struct ieee80211_mgmt *) data;
118 bss = bss_get(wt, mgmt->bssid);
121 if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
122 sta = sta_get(bss, mgmt->da);
124 sta = sta_get(bss, mgmt->sa);
129 wpa_printf(MSG_INFO, "Too short Authentication frame from "
130 MACSTR, MAC2STR(mgmt->sa));
134 alg = le_to_host16(mgmt->u.auth.auth_alg);
135 trans = le_to_host16(mgmt->u.auth.auth_transaction);
136 status = le_to_host16(mgmt->u.auth.status_code);
138 wpa_printf(MSG_DEBUG, "AUTH " MACSTR " -> " MACSTR
139 " (alg=%u trans=%u status=%u)",
140 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), alg, trans, status);
142 if (alg == 0 && trans == 2 && status == 0) {
143 if (sta->state == STATE1) {
144 wpa_printf(MSG_DEBUG, "STA " MACSTR
145 " moved to State 2 with " MACSTR,
146 MAC2STR(sta->addr), MAC2STR(bss->bssid));
153 static void rx_mgmt_deauth(struct wlantest *wt, const u8 *data, size_t len)
155 const struct ieee80211_mgmt *mgmt;
156 struct wlantest_bss *bss;
157 struct wlantest_sta *sta;
159 mgmt = (const struct ieee80211_mgmt *) data;
160 bss = bss_get(wt, mgmt->bssid);
163 if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
164 sta = sta_get(bss, mgmt->da);
166 sta = sta_get(bss, mgmt->sa);
171 wpa_printf(MSG_INFO, "Too short Deauthentication frame from "
172 MACSTR, MAC2STR(mgmt->sa));
176 wpa_printf(MSG_DEBUG, "DEAUTH " MACSTR " -> " MACSTR
178 MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
179 le_to_host16(mgmt->u.deauth.reason_code));
181 if (sta->state != STATE1) {
182 wpa_printf(MSG_DEBUG, "STA " MACSTR
183 " moved to State 1 with " MACSTR,
184 MAC2STR(sta->addr), MAC2STR(bss->bssid));
190 static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
192 const struct ieee80211_mgmt *mgmt;
193 struct wlantest_bss *bss;
194 struct wlantest_sta *sta;
195 struct ieee802_11_elems elems;
197 mgmt = (const struct ieee80211_mgmt *) data;
198 bss = bss_get(wt, mgmt->bssid);
201 sta = sta_get(bss, mgmt->sa);
206 wpa_printf(MSG_INFO, "Too short Association Request frame "
207 "from " MACSTR, MAC2STR(mgmt->sa));
211 wpa_printf(MSG_DEBUG, "ASSOCREQ " MACSTR " -> " MACSTR
212 " (capab=0x%x listen_int=%u)",
213 MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
214 le_to_host16(mgmt->u.assoc_req.capab_info),
215 le_to_host16(mgmt->u.assoc_req.listen_interval));
217 if (ieee802_11_parse_elems(mgmt->u.assoc_req.variable,
218 len - (mgmt->u.assoc_req.variable - data),
219 &elems, 0) == ParseFailed) {
220 wpa_printf(MSG_INFO, "Invalid IEs in Association Request "
221 "frame from " MACSTR, MAC2STR(mgmt->sa));
225 sta_update_assoc(sta, &elems);
229 static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
231 const struct ieee80211_mgmt *mgmt;
232 struct wlantest_bss *bss;
233 struct wlantest_sta *sta;
234 u16 capab, status, aid;
236 mgmt = (const struct ieee80211_mgmt *) data;
237 bss = bss_get(wt, mgmt->bssid);
240 sta = sta_get(bss, mgmt->da);
245 wpa_printf(MSG_INFO, "Too short Association Response frame "
246 "from " MACSTR, MAC2STR(mgmt->sa));
250 capab = le_to_host16(mgmt->u.assoc_resp.capab_info);
251 status = le_to_host16(mgmt->u.assoc_resp.status_code);
252 aid = le_to_host16(mgmt->u.assoc_resp.aid);
254 wpa_printf(MSG_DEBUG, "ASSOCRESP " MACSTR " -> " MACSTR
255 " (capab=0x%x status=%u aid=%u)",
256 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
262 if ((aid & 0xc000) != 0xc000) {
263 wpa_printf(MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
264 "in Association Response from " MACSTR,
267 sta->aid = aid & 0xc000;
269 if (sta->state < STATE2) {
270 wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 when "
271 "getting associated", MAC2STR(sta->addr));
274 if (sta->state < STATE3) {
275 wpa_printf(MSG_DEBUG, "STA " MACSTR
276 " moved to State 3 with " MACSTR,
277 MAC2STR(sta->addr), MAC2STR(bss->bssid));
283 static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
286 const struct ieee80211_mgmt *mgmt;
287 struct wlantest_bss *bss;
288 struct wlantest_sta *sta;
289 struct ieee802_11_elems elems;
291 mgmt = (const struct ieee80211_mgmt *) data;
292 bss = bss_get(wt, mgmt->bssid);
295 sta = sta_get(bss, mgmt->sa);
299 if (len < 24 + 4 + ETH_ALEN) {
300 wpa_printf(MSG_INFO, "Too short Reassociation Request frame "
301 "from " MACSTR, MAC2STR(mgmt->sa));
305 wpa_printf(MSG_DEBUG, "REASSOCREQ " MACSTR " -> " MACSTR
306 " (capab=0x%x listen_int=%u current_ap=" MACSTR ")",
307 MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
308 le_to_host16(mgmt->u.reassoc_req.capab_info),
309 le_to_host16(mgmt->u.reassoc_req.listen_interval),
310 MAC2STR(mgmt->u.reassoc_req.current_ap));
312 if (ieee802_11_parse_elems(mgmt->u.reassoc_req.variable,
313 len - (mgmt->u.reassoc_req.variable - data),
314 &elems, 0) == ParseFailed) {
315 wpa_printf(MSG_INFO, "Invalid IEs in Reassociation Request "
316 "frame from " MACSTR, MAC2STR(mgmt->sa));
320 sta_update_assoc(sta, &elems);
324 static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
327 const struct ieee80211_mgmt *mgmt;
328 struct wlantest_bss *bss;
329 struct wlantest_sta *sta;
330 u16 capab, status, aid;
332 mgmt = (const struct ieee80211_mgmt *) data;
333 bss = bss_get(wt, mgmt->bssid);
336 sta = sta_get(bss, mgmt->da);
341 wpa_printf(MSG_INFO, "Too short Reassociation Response frame "
342 "from " MACSTR, MAC2STR(mgmt->sa));
346 capab = le_to_host16(mgmt->u.reassoc_resp.capab_info);
347 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
348 aid = le_to_host16(mgmt->u.reassoc_resp.aid);
350 wpa_printf(MSG_DEBUG, "REASSOCRESP " MACSTR " -> " MACSTR
351 " (capab=0x%x status=%u aid=%u)",
352 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
358 if ((aid & 0xc000) != 0xc000) {
359 wpa_printf(MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
360 "in Reassociation Response from " MACSTR,
363 sta->aid = aid & 0xc000;
365 if (sta->state < STATE2) {
366 wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 when "
367 "getting associated", MAC2STR(sta->addr));
370 if (sta->state < STATE3) {
371 wpa_printf(MSG_DEBUG, "STA " MACSTR
372 " moved to State 3 with " MACSTR,
373 MAC2STR(sta->addr), MAC2STR(bss->bssid));
379 static void rx_mgmt_disassoc(struct wlantest *wt, const u8 *data, size_t len)
381 const struct ieee80211_mgmt *mgmt;
382 struct wlantest_bss *bss;
383 struct wlantest_sta *sta;
385 mgmt = (const struct ieee80211_mgmt *) data;
386 bss = bss_get(wt, mgmt->bssid);
389 if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
390 sta = sta_get(bss, mgmt->da);
392 sta = sta_get(bss, mgmt->sa);
397 wpa_printf(MSG_INFO, "Too short Disassociation frame from "
398 MACSTR, MAC2STR(mgmt->sa));
402 wpa_printf(MSG_DEBUG, "DISASSOC " MACSTR " -> " MACSTR
404 MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
405 le_to_host16(mgmt->u.disassoc.reason_code));
407 if (sta->state < STATE2) {
408 wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 or 3 "
409 "when getting disassociated", MAC2STR(sta->addr));
412 if (sta->state > STATE2) {
413 wpa_printf(MSG_DEBUG, "STA " MACSTR
414 " moved to State 2 with " MACSTR,
415 MAC2STR(sta->addr), MAC2STR(bss->bssid));
421 void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len)
423 const struct ieee80211_hdr *hdr;
429 hdr = (const struct ieee80211_hdr *) data;
430 fc = le_to_host16(hdr->frame_control);
432 stype = WLAN_FC_GET_STYPE(fc);
434 wpa_printf((stype == WLAN_FC_STYPE_BEACON ||
435 stype == WLAN_FC_STYPE_PROBE_RESP ||
436 stype == WLAN_FC_STYPE_PROBE_REQ) ?
437 MSG_EXCESSIVE : MSG_MSGDUMP,
438 "MGMT %s%s%s DA=" MACSTR " SA=" MACSTR " BSSID=" MACSTR,
440 fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
441 fc & WLAN_FC_ISWEP ? " Prot" : "",
442 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
443 MAC2STR(hdr->addr3));
446 case WLAN_FC_STYPE_BEACON:
447 rx_mgmt_beacon(wt, data, len);
449 case WLAN_FC_STYPE_PROBE_RESP:
450 rx_mgmt_probe_resp(wt, data, len);
452 case WLAN_FC_STYPE_AUTH:
453 rx_mgmt_auth(wt, data, len);
455 case WLAN_FC_STYPE_DEAUTH:
456 rx_mgmt_deauth(wt, data, len);
458 case WLAN_FC_STYPE_ASSOC_REQ:
459 rx_mgmt_assoc_req(wt, data, len);
461 case WLAN_FC_STYPE_ASSOC_RESP:
462 rx_mgmt_assoc_resp(wt, data, len);
464 case WLAN_FC_STYPE_REASSOC_REQ:
465 rx_mgmt_reassoc_req(wt, data, len);
467 case WLAN_FC_STYPE_REASSOC_RESP:
468 rx_mgmt_reassoc_resp(wt, data, len);
470 case WLAN_FC_STYPE_DISASSOC:
471 rx_mgmt_disassoc(wt, data, len);