@@ -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);
@@ -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;
@@ -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);
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@holisticon.pl> --- hostapd/ctrl_iface.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/ap/hostapd.c | 4 +-- src/ap/hostapd.h | 2 ++ 3 files changed, 76 insertions(+), 2 deletions(-)