}
+static int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
+ const char *txtaddr)
+{
+ u8 addr[ETH_ALEN];
+ struct sta_info *sta;
+ const char *pos;
+
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s", txtaddr);
+
+ if (hwaddr_aton(txtaddr, addr))
+ return -1;
+
+ pos = os_strstr(txtaddr, " test=");
+ if (pos) {
+ struct ieee80211_mgmt mgmt;
+ int encrypt;
+ if (hapd->driver->send_frame == NULL)
+ return -1;
+ pos += 6;
+ encrypt = atoi(pos);
+ os_memset(&mgmt, 0, sizeof(mgmt));
+ mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+ WLAN_FC_STYPE_DEAUTH);
+ os_memcpy(mgmt.da, addr, ETH_ALEN);
+ os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
+ os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
+ mgmt.u.deauth.reason_code =
+ host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+ if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
+ IEEE80211_HDRLEN +
+ sizeof(mgmt.u.deauth),
+ encrypt) < 0)
+ return -1;
+ return 0;
+ }
+
+ hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+ sta = ap_get_sta(hapd, addr);
+ if (sta)
+ ap_sta_deauthenticate(hapd, sta,
+ WLAN_REASON_PREV_AUTH_NOT_VALID);
+
+ return 0;
+}
+
+
+static int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
+ const char *txtaddr)
+{
+ u8 addr[ETH_ALEN];
+ struct sta_info *sta;
+ const char *pos;
+
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", txtaddr);
+
+ if (hwaddr_aton(txtaddr, addr))
+ return -1;
+
+ pos = os_strstr(txtaddr, " test=");
+ if (pos) {
+ struct ieee80211_mgmt mgmt;
+ int encrypt;
+ if (hapd->driver->send_frame == NULL)
+ return -1;
+ pos += 6;
+ encrypt = atoi(pos);
+ os_memset(&mgmt, 0, sizeof(mgmt));
+ mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+ WLAN_FC_STYPE_DISASSOC);
+ os_memcpy(mgmt.da, addr, ETH_ALEN);
+ os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
+ os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
+ mgmt.u.disassoc.reason_code =
+ host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+ if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
+ IEEE80211_HDRLEN +
+ sizeof(mgmt.u.deauth),
+ encrypt) < 0)
+ return -1;
+ return 0;
+ }
+
+ hapd->drv.sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+ sta = ap_get_sta(hapd, addr);
+ if (sta)
+ ap_sta_disassociate(hapd, sta,
+ WLAN_REASON_PREV_AUTH_NOT_VALID);
+
+ return 0;
+}
+
+
#ifdef CONFIG_IEEE80211W
#ifdef NEED_AP_MLME
static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
return hostapd_wps_start_oob(hapd, txt, path, method, name);
}
#endif /* CONFIG_WPS_OOB */
+
+
+static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
+ char *buf, size_t buflen)
+{
+ int timeout = 300;
+ char *pos;
+ const char *pin_txt;
+
+ pos = os_strchr(txt, ' ');
+ if (pos)
+ *pos++ = '\0';
+
+ if (os_strcmp(txt, "disable") == 0) {
+ hostapd_wps_ap_pin_disable(hapd);
+ return os_snprintf(buf, buflen, "OK\n");
+ }
+
+ if (os_strcmp(txt, "random") == 0) {
+ if (pos)
+ timeout = atoi(pos);
+ pin_txt = hostapd_wps_ap_pin_random(hapd, timeout);
+ if (pin_txt == NULL)
+ return -1;
+ return os_snprintf(buf, buflen, "%s", pin_txt);
+ }
+
+ if (os_strcmp(txt, "get") == 0) {
+ pin_txt = hostapd_wps_ap_pin_get(hapd);
+ if (pin_txt == NULL)
+ return -1;
+ return os_snprintf(buf, buflen, "%s", pin_txt);
+ }
+
+ if (os_strcmp(txt, "set") == 0) {
+ char *pin;
+ if (pos == NULL)
+ return -1;
+ pin = pos;
+ pos = os_strchr(pos, ' ');
+ if (pos) {
+ *pos++ = '\0';
+ timeout = atoi(pos);
+ }
+ if (os_strlen(pin) > buflen)
+ return -1;
+ if (hostapd_wps_ap_pin_set(hapd, pin, timeout) < 0)
+ return -1;
+ return os_snprintf(buf, buflen, "%s", pin);
+ }
+
+ return -1;
+}
#endif /* CONFIG_WPS */
} else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
reply_len = -1;
+ } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
+ if (hostapd_ctrl_iface_deauthenticate(hapd, buf + 15))
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
+ if (hostapd_ctrl_iface_disassociate(hapd, buf + 13))
+ reply_len = -1;
#ifdef CONFIG_IEEE80211W
#ifdef NEED_AP_MLME
} else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
if (hostapd_ctrl_iface_wps_oob(hapd, buf + 8))
reply_len = -1;
#endif /* CONFIG_WPS_OOB */
+ } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
+ reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11,
+ reply, reply_size);
#endif /* CONFIG_WPS */
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);