2 * Control interface for shared AP commands
3 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "common/ieee802_11_defs.h"
14 #include "ieee802_1x.h"
16 #include "ieee802_11.h"
18 #include "wps_hostapd.h"
19 #include "p2p_hostapd.h"
20 #include "ctrl_iface_ap.h"
21 #include "ap_drv_ops.h"
24 static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
26 char *buf, size_t buflen)
31 ret = os_snprintf(buf, buflen, "FAIL\n");
32 if (ret < 0 || (size_t) ret >= buflen)
38 ret = os_snprintf(buf + len, buflen - len, MACSTR "\n",
40 if (ret < 0 || (size_t) ret >= buflen - len)
44 res = ieee802_11_get_mib_sta(hapd, sta, buf + len, buflen - len);
47 res = wpa_get_mib_sta(sta->wpa_sm, buf + len, buflen - len);
50 res = ieee802_1x_get_mib_sta(hapd, sta, buf + len, buflen - len);
53 res = hostapd_wps_get_mib_sta(hapd, sta->addr, buf + len,
57 res = hostapd_p2p_get_mib_sta(hapd, sta, buf + len, buflen - len);
65 int hostapd_ctrl_iface_sta_first(struct hostapd_data *hapd,
66 char *buf, size_t buflen)
68 return hostapd_ctrl_iface_sta_mib(hapd, hapd->sta_list, buf, buflen);
72 int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr,
73 char *buf, size_t buflen)
78 if (hwaddr_aton(txtaddr, addr)) {
79 ret = os_snprintf(buf, buflen, "FAIL\n");
80 if (ret < 0 || (size_t) ret >= buflen)
84 return hostapd_ctrl_iface_sta_mib(hapd, ap_get_sta(hapd, addr),
89 int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
90 char *buf, size_t buflen)
96 if (hwaddr_aton(txtaddr, addr) ||
97 (sta = ap_get_sta(hapd, addr)) == NULL) {
98 ret = os_snprintf(buf, buflen, "FAIL\n");
99 if (ret < 0 || (size_t) ret >= buflen)
103 return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
107 #ifdef CONFIG_P2P_MANAGER
108 static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
109 u8 minor_reason_code, const u8 *addr)
111 struct ieee80211_mgmt *mgmt;
115 if (hapd->driver->send_frame == NULL)
118 mgmt = os_zalloc(sizeof(*mgmt) + 100);
122 wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "P2P: Disconnect STA " MACSTR
123 " with minor reason code %u (stype=%u)",
124 MAC2STR(addr), minor_reason_code, stype);
126 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
127 os_memcpy(mgmt->da, addr, ETH_ALEN);
128 os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
129 os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
130 if (stype == WLAN_FC_STYPE_DEAUTH) {
131 mgmt->u.deauth.reason_code =
132 host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
133 pos = (u8 *) (&mgmt->u.deauth.reason_code + 1);
135 mgmt->u.disassoc.reason_code =
136 host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
137 pos = (u8 *) (&mgmt->u.disassoc.reason_code + 1);
140 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
142 WPA_PUT_BE24(pos, OUI_WFA);
144 *pos++ = P2P_OUI_TYPE;
146 *pos++ = P2P_ATTR_MINOR_REASON_CODE;
147 WPA_PUT_LE16(pos, 1);
149 *pos++ = minor_reason_code;
151 ret = hapd->driver->send_frame(hapd->drv_priv, (u8 *) mgmt,
152 pos - (u8 *) mgmt, 1);
155 return ret < 0 ? -1 : 0;
157 #endif /* CONFIG_P2P_MANAGER */
160 int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
164 struct sta_info *sta;
167 wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s",
170 if (hwaddr_aton(txtaddr, addr))
173 pos = os_strstr(txtaddr, " test=");
175 struct ieee80211_mgmt mgmt;
177 if (hapd->driver->send_frame == NULL)
181 os_memset(&mgmt, 0, sizeof(mgmt));
182 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
183 WLAN_FC_STYPE_DEAUTH);
184 os_memcpy(mgmt.da, addr, ETH_ALEN);
185 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
186 os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
187 mgmt.u.deauth.reason_code =
188 host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
189 if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
191 sizeof(mgmt.u.deauth),
197 #ifdef CONFIG_P2P_MANAGER
198 pos = os_strstr(txtaddr, " p2p=");
200 return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DEAUTH,
201 atoi(pos + 5), addr);
203 #endif /* CONFIG_P2P_MANAGER */
205 hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
206 sta = ap_get_sta(hapd, addr);
208 ap_sta_deauthenticate(hapd, sta,
209 WLAN_REASON_PREV_AUTH_NOT_VALID);
210 else if (addr[0] == 0xff)
211 hostapd_free_stas(hapd);
217 int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
221 struct sta_info *sta;
224 wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s",
227 if (hwaddr_aton(txtaddr, addr))
230 pos = os_strstr(txtaddr, " test=");
232 struct ieee80211_mgmt mgmt;
234 if (hapd->driver->send_frame == NULL)
238 os_memset(&mgmt, 0, sizeof(mgmt));
239 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
240 WLAN_FC_STYPE_DISASSOC);
241 os_memcpy(mgmt.da, addr, ETH_ALEN);
242 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
243 os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
244 mgmt.u.disassoc.reason_code =
245 host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
246 if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
248 sizeof(mgmt.u.deauth),
254 #ifdef CONFIG_P2P_MANAGER
255 pos = os_strstr(txtaddr, " p2p=");
257 return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DISASSOC,
258 atoi(pos + 5), addr);
260 #endif /* CONFIG_P2P_MANAGER */
262 hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
263 sta = ap_get_sta(hapd, addr);
265 ap_sta_disassociate(hapd, sta,
266 WLAN_REASON_PREV_AUTH_NOT_VALID);
267 else if (addr[0] == 0xff)
268 hostapd_free_stas(hapd);