Occasionally, external applications require information about AP configurations and capabilities. The optimal source for this is the beacon frame content. To support this need, a new raw command is being introduced: DUMP_BEACON. Using wpa_cli or hostapd_cli to execute this command results in a hex dump of the beacon content. hostapd_cli -i wlxxx raw DUMP_BEACON 80000000ffffffffffff... dd180050f2020101010003a4000027a4000042435e0062322f007f080000000000000040 Signed-off-by: Marek Puzyniak <marek.puzyniak@xxxxxxxxxxxxx> --- hostapd/ctrl_iface.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/ap/hostapd.c | 4 +-- src/ap/hostapd.h | 2 ++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 1fcefb355..371e3f2c5 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -1354,6 +1354,75 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) } +static int hostapd_ctrl_iface_dump_beacon(struct hostapd_data *hapd, + char *buf, size_t buflen) +{ + struct ieee80211_mgmt *mgmt; + struct beacon_data beacon; + size_t ies_len, req_buf; + char *pos, *end; + u8 *ies_start; + int ret; + + pos = buf; + end = buf + buflen; + + ret = hostapd_build_beacon_data(hapd, &beacon); + if (ret) + return -1; + + /* calculate required buffer size to store beacon hex dump */ + /* beacon ies, first part */ + mgmt = (struct ieee80211_mgmt*)beacon.head; + ies_start = &mgmt->u.beacon.variable[0]; + ies_len = beacon.head_len - (ies_start - beacon.head); + + req_buf = 2 * (beacon.head_len + ies_len + beacon.tail_len + beacon.beacon_ies_len) + 1; + + if (req_buf > buflen) { + hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_WARNING, + "Get beacon failed, required bufer %zu > %zu buffer", + req_buf, buflen); + ret = -1; + goto error_return; + } + + /* beacon head, management frame */ + ret = wpa_snprintf_hex(pos, end - pos, beacon.head, beacon.head_len); + pos += ret; + + /* beacon ies, first part */ + ret = wpa_snprintf_hex(pos, end - pos, ies_start, ies_len); + pos += ret; + + /* beacon tail, ie continuation */ + ret = wpa_snprintf_hex(pos, end - pos, beacon.tail, beacon.tail_len); + pos += ret; + + /* beacon extra ie */ + ret = wpa_snprintf_hex(pos, end - pos, beacon.beacon_ies, beacon.beacon_ies_len); + pos += ret; + + ret = os_snprintf(pos, end - pos, "\n"); + if (os_snprintf_error(end - pos, ret)) { + hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_WARNING, + "Get beacon failed, used:%lu of %zu", + end - pos, buflen); + ret = -1; + goto error_return; + } + pos += ret; + + ret = pos - buf; +error_return: + free_beacon_data(&beacon); + + return ret; +} + + static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd, char *buf, size_t buflen) { @@ -4370,6 +4439,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, } else if (os_strncmp(buf, "REQ_BEACON ", 11) == 0) { reply_len = hostapd_ctrl_iface_req_beacon(hapd, buf + 11, reply, reply_size); + } else if (os_strcmp(buf, "DUMP_BEACON") == 0) { + reply_len = hostapd_ctrl_iface_dump_beacon(hapd, reply, + reply_size); } else if (os_strncmp(buf, "REQ_LINK_MEASUREMENT ", 21) == 0) { reply_len = hostapd_ctrl_iface_req_link_measurement( hapd, buf + 21, reply, reply_size); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 5ba2cab2c..01a228c43 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -4200,8 +4200,8 @@ void free_beacon_data(struct beacon_data *beacon) } -static int hostapd_build_beacon_data(struct hostapd_data *hapd, - struct beacon_data *beacon) +int hostapd_build_beacon_data(struct hostapd_data *hapd, + struct beacon_data *beacon) { struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra; struct wpa_driver_ap_params params; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 7e72863af..6cc25e474 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -859,6 +859,8 @@ int hostapd_mld_add_link(struct hostapd_data *hapd); int hostapd_mld_remove_link(struct hostapd_data *hapd); struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd); +int hostapd_build_beacon_data(struct hostapd_data *hapd, + struct beacon_data *beacon); void free_beacon_data(struct beacon_data *beacon); int hostapd_fill_cca_settings(struct hostapd_data *hapd, struct cca_settings *settings); -- 2.43.2 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap