18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Control interface for shared AP commands 3cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 1204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common/ieee802_11_defs.h" 13fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#include "eapol_auth/eapol_auth_sm.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_hostapd.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface_ap.h" 2204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "ap_drv_ops.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int hostapd_get_sta_tx_rx(struct hostapd_data *hapd, 26fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct sta_info *sta, 27fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt char *buf, size_t buflen) 28fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 29fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct hostap_sta_driver_data data; 30fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int ret; 31fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 32fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0) 33fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 34fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 35fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = os_snprintf(buf, buflen, "rx_packets=%lu\ntx_packets=%lu\n" 36fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt "rx_bytes=%lu\ntx_bytes=%lu\n", 37fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt data.rx_packets, data.tx_packets, 38fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt data.rx_bytes, data.tx_bytes); 39fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen) 40fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 41fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return ret; 42fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 43fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 44fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 45d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int hostapd_get_sta_conn_time(struct sta_info *sta, 46d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char *buf, size_t buflen) 47d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 4804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt struct os_reltime age; 49fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int ret; 50d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 51d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!sta->connected_time.sec) 52d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 53d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_reltime_age(&sta->connected_time, &age); 55d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 56fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = os_snprintf(buf, buflen, "connected_time=%u\n", 57d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (unsigned int) age.sec); 58fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen) 59fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 60fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return ret; 61fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 62d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 63fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 64fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic const char * timeout_next_str(int val) 65fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 66fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt switch (val) { 67fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case STA_NULLFUNC: 68fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "NULLFUNC POLL"; 69fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case STA_DISASSOC: 70fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "DISASSOC"; 71fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case STA_DEAUTH: 72fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "DEAUTH"; 73fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case STA_REMOVE: 74fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "REMOVE"; 75fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case STA_DISASSOC_FROM_CLI: 76fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "DISASSOC_FROM_CLI"; 77fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 78fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 79fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return "?"; 80d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 81d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 82d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd, 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 87fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int len, res, ret, i; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 891846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (!sta) 901846323989242844f0e857458a8939fa5836429cDmitry Shmidt return 0; 911846323989242844f0e857458a8939fa5836429cDmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 0; 93fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, MACSTR "\nflags=", 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr)); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 99fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = ap_sta_flags_txt(sta->flags, buf + len, buflen - len); 100fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret < 0) 101fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return len; 102fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len += ret; 103fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 104fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, "\naid=%d\ncapability=0x%x\n" 105fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt "listen_interval=%d\nsupported_rates=", 106fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sta->aid, sta->capability, sta->listen_interval); 107fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 108fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return len; 109fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len += ret; 110fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 111fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (i = 0; i < sta->supported_rates_len; i++) { 112fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, "%02x%s", 113fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sta->supported_rates[i], 114fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt i + 1 < sta->supported_rates_len ? " " : ""); 115fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 116fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return len; 117fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len += ret; 118fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 119fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 120fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, "\ntimeout_next=%s\n", 121fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt timeout_next_str(sta->timeout_next)); 122fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 123fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return len; 124fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len += ret; 125fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ieee802_11_get_mib_sta(hapd, sta, buf + len, buflen - len); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += res; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_get_mib_sta(sta->wpa_sm, buf + len, buflen - len); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += res; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ieee802_1x_get_mib_sta(hapd, sta, buf + len, buflen - len); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += res; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = hostapd_wps_get_mib_sta(hapd, sta->addr, buf + len, 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen - len); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += res; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = hostapd_p2p_get_mib_sta(hapd, sta, buf + len, buflen - len); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += res; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 143fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len += hostapd_get_sta_tx_rx(hapd, sta, buf + len, buflen - len); 144fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len += hostapd_get_sta_conn_time(sta, buf + len, buflen - len); 145d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_ctrl_iface_sta_first(struct hostapd_data *hapd, 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_ctrl_iface_sta_mib(hapd, hapd->sta_list, buf, buflen); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr, 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 162fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const char *pos; 163fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct sta_info *sta; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(txtaddr, addr)) { 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf, buflen, "FAIL\n"); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 171fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 172fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sta = ap_get_sta(hapd, addr); 173fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sta == NULL) 174fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 175fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 176fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt pos = os_strchr(txtaddr, ' '); 177fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (pos) { 178fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt pos++; 179fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 180fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef HOSTAPD_DUMP_STATE 181fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (os_strcmp(pos, "eapol") == 0) { 182fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sta->eapol_sm == NULL) 183fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 184fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return eapol_auth_dump_state(sta->eapol_sm, buf, 185fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt buflen); 186fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 187fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* HOSTAPD_DUMP_STATE */ 188fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 189fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 190fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 191fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 192fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return hostapd_ctrl_iface_sta_mib(hapd, sta, buf, buflen); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr, 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(txtaddr, addr) || 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sta = ap_get_sta(hapd, addr)) == NULL) { 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf, buflen, "FAIL\n"); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen) 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2091846323989242844f0e857458a8939fa5836429cDmitry Shmidt } 2101846323989242844f0e857458a8939fa5836429cDmitry Shmidt 2111846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (!sta->next) 2121846323989242844f0e857458a8939fa5836429cDmitry Shmidt return 0; 2131846323989242844f0e857458a8939fa5836429cDmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_P2P_MANAGER 21904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, 22004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 minor_reason_code, const u8 *addr) 22104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 22204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_mgmt *mgmt; 22304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 22404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *pos; 22504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 22604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->driver->send_frame == NULL) 22704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 22804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 22904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mgmt = os_zalloc(sizeof(*mgmt) + 100); 23004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (mgmt == NULL) 23104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 23204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2332271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype); 23404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "P2P: Disconnect STA " MACSTR 2352271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt " with minor reason code %u (stype=%u (%s))", 2362271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt MAC2STR(addr), minor_reason_code, stype, 2372271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt fc2str(mgmt->frame_control)); 23804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 23904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt->da, addr, ETH_ALEN); 24004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN); 24104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN); 24204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (stype == WLAN_FC_STYPE_DEAUTH) { 24304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mgmt->u.deauth.reason_code = 24404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); 24504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = (u8 *) (&mgmt->u.deauth.reason_code + 1); 24604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 24704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mgmt->u.disassoc.reason_code = 24804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); 24904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = (u8 *) (&mgmt->u.disassoc.reason_code + 1); 25004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 25104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 25204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = WLAN_EID_VENDOR_SPECIFIC; 25304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = 4 + 3 + 1; 254a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_PUT_BE32(pos, P2P_IE_VENDOR_TYPE); 255a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt pos += 4; 25604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 25704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = P2P_ATTR_MINOR_REASON_CODE; 25804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WPA_PUT_LE16(pos, 1); 25904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += 2; 26004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = minor_reason_code; 26104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 26204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = hapd->driver->send_frame(hapd->drv_priv, (u8 *) mgmt, 26304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos - (u8 *) mgmt, 1); 26404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(mgmt); 26504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 26604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret < 0 ? -1 : 0; 26704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 26804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 26904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 27004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 27104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd, 27204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *txtaddr) 27304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 27404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 addr[ETH_ALEN]; 27504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta; 27604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *pos; 277a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u16 reason = WLAN_REASON_PREV_AUTH_NOT_VALID; 27804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 27904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s", 28004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt txtaddr); 28104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 28204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hwaddr_aton(txtaddr, addr)) 28304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 28404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 285b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt pos = os_strstr(txtaddr, " reason="); 286b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (pos) 287b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt reason = atoi(pos + 8); 288b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 28904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = os_strstr(txtaddr, " test="); 29004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pos) { 29104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_mgmt mgmt; 29204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int encrypt; 29304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->driver->send_frame == NULL) 29404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 29504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += 6; 29604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt encrypt = atoi(pos); 29704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&mgmt, 0, sizeof(mgmt)); 29804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 29904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_FC_STYPE_DEAUTH); 30004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt.da, addr, ETH_ALEN); 30104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); 30204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); 303b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt mgmt.u.deauth.reason_code = host_to_le16(reason); 30404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt, 30504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt IEEE80211_HDRLEN + 30604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(mgmt.u.deauth), 30704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt encrypt) < 0) 30804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 30904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 31004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 31104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 31204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_P2P_MANAGER 31304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = os_strstr(txtaddr, " p2p="); 31404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pos) { 31504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DEAUTH, 31604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt atoi(pos + 5), addr); 31704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 31804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 31904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 320a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hostapd_drv_sta_deauth(hapd, addr, reason); 32104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = ap_get_sta(hapd, addr); 32204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta) 323a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ap_sta_deauthenticate(hapd, sta, reason); 32404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (addr[0] == 0xff) 32504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_stas(hapd); 32604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 32704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 32804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 32904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 33004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 33104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd, 33204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *txtaddr) 33304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 33404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 addr[ETH_ALEN]; 33504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta; 33604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *pos; 337a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u16 reason = WLAN_REASON_PREV_AUTH_NOT_VALID; 33804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 33904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", 34004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt txtaddr); 34104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 34204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hwaddr_aton(txtaddr, addr)) 34304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 345b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt pos = os_strstr(txtaddr, " reason="); 346b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (pos) 347b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt reason = atoi(pos + 8); 348b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 34904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = os_strstr(txtaddr, " test="); 35004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pos) { 35104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_mgmt mgmt; 35204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int encrypt; 35304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->driver->send_frame == NULL) 35404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 35504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += 6; 35604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt encrypt = atoi(pos); 35704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&mgmt, 0, sizeof(mgmt)); 35804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 35904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_FC_STYPE_DISASSOC); 36004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt.da, addr, ETH_ALEN); 36104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); 36204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); 363b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt mgmt.u.disassoc.reason_code = host_to_le16(reason); 36404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt, 36504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt IEEE80211_HDRLEN + 36604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(mgmt.u.deauth), 36704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt encrypt) < 0) 36804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 36904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 37004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 37104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 37204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_P2P_MANAGER 37304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = os_strstr(txtaddr, " p2p="); 37404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pos) { 37504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DISASSOC, 37604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt atoi(pos + 5), addr); 37704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 37804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 37904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 380a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hostapd_drv_sta_disassoc(hapd, addr, reason); 38104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = ap_get_sta(hapd, addr); 38204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta) 383a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ap_sta_disassociate(hapd, sta, reason); 38404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (addr[0] == 0xff) 38504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_stas(hapd); 38604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 38704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 38804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 389cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 390cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 391cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtint hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, 392cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t buflen) 393cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 394cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = hapd->iface; 395cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int len = 0, ret; 396cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 397cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 398cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 399cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "state=%s\n" 400cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "phy=%s\n" 401cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "freq=%d\n" 402cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "num_sta_non_erp=%d\n" 403cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "num_sta_no_short_slot_time=%d\n" 404cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "num_sta_no_short_preamble=%d\n" 405cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "olbc=%d\n" 406cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "num_sta_ht_no_gf=%d\n" 407cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "num_sta_no_ht=%d\n" 408cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "num_sta_ht_20_mhz=%d\n" 4097832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt "num_sta_ht40_intolerant=%d\n" 410cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "olbc_ht=%d\n" 411cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "ht_op_mode=0x%x\n", 412cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_state_text(iface->state), 413cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->phy, 414cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->freq, 415cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->num_sta_non_erp, 416cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->num_sta_no_short_slot_time, 417cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->num_sta_no_short_preamble, 418cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->olbc, 419cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->num_sta_ht_no_gf, 420cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->num_sta_no_ht, 421cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->num_sta_ht_20mhz, 4227832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt iface->num_sta_ht40_intolerant, 423cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->olbc_ht, 424cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->ht_op_mode); 425cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 426cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return len; 427cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt len += ret; 428cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 429df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (!iface->cac_started || !iface->dfs_cac_ms) { 430df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 431df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt "cac_time_seconds=%d\n" 432df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt "cac_time_left_seconds=N/A\n", 433df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt iface->dfs_cac_ms / 1000); 434df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } else { 435df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt /* CAC started and CAC time set - calculate remaining time */ 436df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct os_reltime now; 437df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt unsigned int left_time; 438df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 439df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt os_reltime_age(&iface->dfs_cac_start, &now); 440df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt left_time = iface->dfs_cac_ms / 1000 - now.sec; 441df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 442df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt "cac_time_seconds=%u\n" 443df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt "cac_time_left_seconds=%u\n", 444df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt iface->dfs_cac_ms / 1000, 445df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt left_time); 446df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 447df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 448df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return len; 449df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt len += ret; 450df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 451cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 452cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "channel=%u\n" 453cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "secondary_channel=%d\n" 454cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "ieee80211n=%d\n" 455cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "ieee80211ac=%d\n" 456cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "vht_oper_chwidth=%d\n" 457cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "vht_oper_centr_freq_seg0_idx=%d\n" 458cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "vht_oper_centr_freq_seg1_idx=%d\n", 459cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->channel, 460cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->secondary_channel, 461cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->ieee80211n, 462cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->ieee80211ac, 463cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->vht_oper_chwidth, 464cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->vht_oper_centr_freq_seg0_idx, 465cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->vht_oper_centr_freq_seg1_idx); 466cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 467cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return len; 468cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt len += ret; 469cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 470cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) { 471cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *bss = iface->bss[i]; 472cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 473cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "bss[%d]=%s\n" 474cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "bssid[%d]=" MACSTR "\n" 475cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "ssid[%d]=%s\n" 476cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "num_sta[%d]=%d\n", 477cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (int) i, bss->conf->iface, 478cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (int) i, MAC2STR(bss->own_addr), 479cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (int) i, 480cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_ssid_txt(bss->conf->ssid.ssid, 481cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss->conf->ssid.ssid_len), 482cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (int) i, bss->num_sta); 483cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 484cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return len; 485cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt len += ret; 486cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 487cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 488cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return len; 489cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 490e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 491e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 492e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint hostapd_parse_csa_settings(const char *pos, 493e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 494e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 495e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt char *end; 496e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 497e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memset(settings, 0, sizeof(*settings)); 498e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->cs_count = strtol(pos, &end, 10); 499e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (pos == end) { 500e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpa_printf(MSG_ERROR, "chanswitch: invalid cs_count provided"); 501e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 502e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 503e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 504e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->freq_params.freq = atoi(end); 505e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (settings->freq_params.freq == 0) { 506e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpa_printf(MSG_ERROR, "chanswitch: invalid freq provided"); 507e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 508e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 509e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 510e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#define SET_CSA_SETTING(str) \ 511e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt do { \ 512e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt const char *pos2 = os_strstr(pos, " " #str "="); \ 513e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (pos2) { \ 514e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt pos2 += sizeof(" " #str "=") - 1; \ 515e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->freq_params.str = atoi(pos2); \ 516e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } \ 517e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } while (0) 518e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 519e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt SET_CSA_SETTING(center_freq1); 520e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt SET_CSA_SETTING(center_freq2); 521e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt SET_CSA_SETTING(bandwidth); 522e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt SET_CSA_SETTING(sec_channel_offset); 523e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->freq_params.ht_enabled = !!os_strstr(pos, " ht"); 524e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->freq_params.vht_enabled = !!os_strstr(pos, " vht"); 525e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->block_tx = !!os_strstr(pos, " blocktx"); 526e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#undef SET_CSA_SETTING 527e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 528e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 529e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 530