wlantest: Add counters for AP deauth/disassoc while asleep/awake
[mech_eap.git] / wlantest / sta.c
1 /*
2  * STA list
3  * Copyright (c) 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
15 #include "utils/includes.h"
16
17 #include "utils/common.h"
18 #include "common/defs.h"
19 #include "common/ieee802_11_common.h"
20 #include "wlantest.h"
21
22
23 struct wlantest_sta * sta_find(struct wlantest_bss *bss, const u8 *addr)
24 {
25         struct wlantest_sta *sta;
26
27         dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
28                 if (os_memcmp(sta->addr, addr, ETH_ALEN) == 0)
29                         return sta;
30         }
31
32         return NULL;
33 }
34
35
36 struct wlantest_sta * sta_get(struct wlantest_bss *bss, const u8 *addr)
37 {
38         struct wlantest_sta *sta;
39
40         if (addr[0] & 0x01)
41                 return NULL; /* Skip group addressed frames */
42
43         sta = sta_find(bss, addr);
44         if (sta)
45                 return sta;
46
47         sta = os_zalloc(sizeof(*sta));
48         if (sta == NULL)
49                 return NULL;
50         os_memset(sta->seq_ctrl_to_sta, 0xff, sizeof(sta->seq_ctrl_to_sta));
51         os_memset(sta->seq_ctrl_to_ap, 0xff, sizeof(sta->seq_ctrl_to_ap));
52         sta->bss = bss;
53         os_memcpy(sta->addr, addr, ETH_ALEN);
54         dl_list_add(&bss->sta, &sta->list);
55         wpa_printf(MSG_DEBUG, "Discovered new STA " MACSTR " in BSS " MACSTR,
56                    MAC2STR(sta->addr), MAC2STR(bss->bssid));
57         return sta;
58 }
59
60
61 void sta_deinit(struct wlantest_sta *sta)
62 {
63         dl_list_del(&sta->list);
64         os_free(sta->assocreq_ies);
65         os_free(sta);
66 }
67
68
69 void sta_update_assoc(struct wlantest_sta *sta, struct ieee802_11_elems *elems)
70 {
71         struct wpa_ie_data data;
72         struct wlantest_bss *bss = sta->bss;
73
74         if (elems->wpa_ie && elems->rsn_ie) {
75                 wpa_printf(MSG_INFO, "Both WPA IE and RSN IE included in "
76                            "Association Request frame from " MACSTR,
77                            MAC2STR(sta->addr));
78         }
79
80         if (elems->rsn_ie) {
81                 wpa_hexdump(MSG_DEBUG, "RSN IE", elems->rsn_ie - 2,
82                             elems->rsn_ie_len + 2);
83                 os_memcpy(sta->rsnie, elems->rsn_ie - 2,
84                           elems->rsn_ie_len + 2);
85                 if (wpa_parse_wpa_ie_rsn(sta->rsnie, 2 + sta->rsnie[1], &data)
86                     < 0) {
87                         wpa_printf(MSG_INFO, "Failed to parse RSN IE from "
88                                    MACSTR, MAC2STR(sta->addr));
89                 }
90         } else if (elems->wpa_ie) {
91                 wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2,
92                             elems->wpa_ie_len + 2);
93                 os_memcpy(sta->rsnie, elems->wpa_ie - 2,
94                           elems->wpa_ie_len + 2);
95                 if (wpa_parse_wpa_ie_wpa(sta->rsnie, 2 + sta->rsnie[1], &data)
96                     < 0) {
97                         wpa_printf(MSG_INFO, "Failed to parse WPA IE from "
98                                    MACSTR, MAC2STR(sta->addr));
99                 }
100         } else
101                 sta->rsnie[0] = 0;
102
103         sta->proto = data.proto;
104         sta->pairwise_cipher = data.pairwise_cipher;
105         sta->key_mgmt = data.key_mgmt;
106         sta->rsn_capab = data.capabilities;
107         if (bss->proto && (sta->proto & bss->proto) == 0) {
108                 wpa_printf(MSG_INFO, "Mismatch in WPA/WPA2 proto: STA "
109                            MACSTR " 0x%x  BSS " MACSTR " 0x%x",
110                            MAC2STR(sta->addr), sta->proto,
111                            MAC2STR(bss->bssid), bss->proto);
112         }
113         if (bss->pairwise_cipher &&
114             (sta->pairwise_cipher & bss->pairwise_cipher) == 0) {
115                 wpa_printf(MSG_INFO, "Mismatch in pairwise cipher: STA "
116                            MACSTR " 0x%x  BSS " MACSTR " 0x%x",
117                            MAC2STR(sta->addr), sta->pairwise_cipher,
118                            MAC2STR(bss->bssid), bss->pairwise_cipher);
119         }
120         if (sta->proto && data.group_cipher != bss->group_cipher) {
121                 wpa_printf(MSG_INFO, "Mismatch in group cipher: STA "
122                            MACSTR " 0x%x != BSS " MACSTR " 0x%x",
123                            MAC2STR(sta->addr), data.group_cipher,
124                            MAC2STR(bss->bssid), bss->group_cipher);
125         }
126         if ((bss->rsn_capab & WPA_CAPABILITY_MFPR) &&
127             !(sta->rsn_capab & WPA_CAPABILITY_MFPC)) {
128                 wpa_printf(MSG_INFO, "STA " MACSTR " tries to associate "
129                            "without MFP to BSS " MACSTR " that advertises "
130                            "MFPR", MAC2STR(sta->addr), MAC2STR(bss->bssid));
131         }
132
133         wpa_printf(MSG_INFO, "STA " MACSTR
134                    " proto=%s%s%s"
135                    "pairwise=%s%s%s%s"
136                    "key_mgmt=%s%s%s%s%s%s%s%s"
137                    "rsn_capab=%s%s%s%s%s",
138                    MAC2STR(sta->addr),
139                    sta->proto == 0 ? "OPEN " : "",
140                    sta->proto & WPA_PROTO_WPA ? "WPA " : "",
141                    sta->proto & WPA_PROTO_RSN ? "WPA2 " : "",
142                    sta->pairwise_cipher == 0 ? "N/A " : "",
143                    sta->pairwise_cipher & WPA_CIPHER_NONE ? "NONE " : "",
144                    sta->pairwise_cipher & WPA_CIPHER_TKIP ? "TKIP " : "",
145                    sta->pairwise_cipher & WPA_CIPHER_CCMP ? "CCMP " : "",
146                    sta->key_mgmt == 0 ? "N/A " : "",
147                    sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X ? "EAP " : "",
148                    sta->key_mgmt & WPA_KEY_MGMT_PSK ? "PSK " : "",
149                    sta->key_mgmt & WPA_KEY_MGMT_WPA_NONE ? "WPA-NONE " : "",
150                    sta->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X ? "FT-EAP " : "",
151                    sta->key_mgmt & WPA_KEY_MGMT_FT_PSK ? "FT-PSK " : "",
152                    sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256 ?
153                    "EAP-SHA256 " : "",
154                    sta->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
155                    "PSK-SHA256 " : "",
156                    sta->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
157                    sta->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
158                    "NO_PAIRWISE " : "",
159                    sta->rsn_capab & WPA_CAPABILITY_MFPR ? "MFPR " : "",
160                    sta->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "",
161                    sta->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ?
162                    "PEERKEY " : "");
163 }