]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Allow Relay connections to Controllers to be added and removed
authorJouni Malinen <quic_jouni@quicinc.com>
Sat, 23 Jul 2022 14:41:00 +0000 (17:41 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 24 Jul 2022 21:23:31 +0000 (00:23 +0300)
The new control interface commands "DPP_RELAY_ADD_CONTROLLER <IP addr>
<PK hash>" and "DPP_RELAY_REMOVE_CONTROLLER <IP addr>" can now be used
to dynamically add and remove connections to Controllers for the cases
where the connection is initialized through a DPP Public Action frame
(i.e., Controller as the Responder).

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
hostapd/ctrl_iface.c
src/ap/dpp_hostapd.c
src/ap/dpp_hostapd.h
src/common/dpp.h
src/common/dpp_tcp.c

index a976e8fcad8e4d218c0501c9acf485209ec544aa..32ab3019f776e6b0e6e9c3516e07abc64c060b23 100644 (file)
@@ -3673,6 +3673,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                        reply_len = -1;
        } else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {
                hostapd_dpp_chirp_stop(hapd);
+       } else if (os_strncmp(buf, "DPP_RELAY_ADD_CONTROLLER ", 25) == 0) {
+               if (hostapd_dpp_add_controller(hapd, buf + 25) < 0)
+                       reply_len = -1;
+       } else if (os_strncmp(buf, "DPP_RELAY_REMOVE_CONTROLLER ", 28) == 0) {
+               hostapd_dpp_remove_controller(hapd, buf + 28);
 #endif /* CONFIG_DPP2 */
 #ifdef CONFIG_DPP3
        } else if (os_strcmp(buf, "DPP_PUSH_BUTTON") == 0) {
index c1732ca4040ed670707742aee5b01c9666b72aff..a92ae0d79abeaa902d204b9b7f0e40586ce63ec5 100644 (file)
@@ -21,6 +21,7 @@
 #include "gas_query_ap.h"
 #include "gas_serv.h"
 #include "wpa_auth.h"
+#include "beacon.h"
 #include "dpp_hostapd.h"
 
 
@@ -3375,6 +3376,65 @@ static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
 }
 
 
+#ifdef CONFIG_DPP2
+
+int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd)
+{
+       struct dpp_relay_config config;
+       struct hostapd_ip_addr addr;
+       u8 pkhash[SHA256_MAC_LEN];
+       char *pos, *tmp;
+       int ret = -1;
+       bool prev_state, new_state;
+       struct dpp_global *dpp = hapd->iface->interfaces->dpp;
+
+       tmp = os_strdup(cmd);
+       if (!tmp)
+               goto fail;
+       pos = os_strchr(tmp, ' ');
+       if (!pos)
+               goto fail;
+       pos++;
+       if (hostapd_parse_ip_addr(tmp, &addr) < 0 ||
+           hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0)
+               goto fail;
+
+       os_memset(&config, 0, sizeof(config));
+       config.msg_ctx = hapd->msg_ctx;
+       config.cb_ctx = hapd;
+       config.tx = hostapd_dpp_relay_tx;
+       config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
+       config.ipaddr = &addr;
+       config.pkhash = pkhash;
+       prev_state = dpp_relay_controller_available(dpp);
+       ret = dpp_relay_add_controller(dpp, &config);
+       new_state = dpp_relay_controller_available(dpp);
+       if (new_state != prev_state)
+               ieee802_11_update_beacons(hapd->iface);
+fail:
+       os_free(tmp);
+       return ret;
+}
+
+
+void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd)
+{
+       struct hostapd_ip_addr addr;
+       bool prev_state, new_state;
+       struct dpp_global *dpp = hapd->iface->interfaces->dpp;
+
+       if (hostapd_parse_ip_addr(cmd, &addr) < 0)
+               return;
+       prev_state = dpp_relay_controller_available(dpp);
+       dpp_relay_remove_controller(dpp, &addr);
+       new_state = dpp_relay_controller_available(dpp);
+       if (new_state != prev_state)
+               ieee802_11_update_beacons(hapd->iface);
+}
+
+#endif /* CONFIG_DPP2 */
+
+
 int hostapd_dpp_init(struct hostapd_data *hapd)
 {
        hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
index d462a1a6a39080eeefa070f78b80427631f8a992..55f1fce22d1ac8839fa50a44aa0883537a5bcb93 100644 (file)
@@ -48,5 +48,7 @@ void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi);
 int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd);
 void hostapd_dpp_push_button_stop(struct hostapd_data *hapd);
 bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd);
+int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd);
+void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd);
 
 #endif /* DPP_HOSTAPD_H */
index 3b5f08967b4c08e0210e978bbec96d1646258919..ea91ece488037efe39efddb1fff63d75630b7184 100644 (file)
@@ -749,6 +749,8 @@ struct dpp_configurator * dpp_configurator_find_kid(struct dpp_global *dpp,
                                                    const u8 *kid);
 int dpp_relay_add_controller(struct dpp_global *dpp,
                             struct dpp_relay_config *config);
+void dpp_relay_remove_controller(struct dpp_global *dpp,
+                                const struct hostapd_ip_addr *addr);
 int dpp_relay_listen(struct dpp_global *dpp, int port,
                     struct dpp_relay_config *config);
 void dpp_relay_stop_listen(struct dpp_global *dpp);
index 6c5f3bf8381d5b45840db4ee0ddb48bcfb0cc6ed..e16d9b09b1436428fd067d30869c34318060fa52 100644 (file)
@@ -139,6 +139,7 @@ int dpp_relay_add_controller(struct dpp_global *dpp,
                             struct dpp_relay_config *config)
 {
        struct dpp_relay_controller *ctrl;
+       char txt[100];
 
        if (!dpp)
                return -1;
@@ -154,6 +155,8 @@ int dpp_relay_add_controller(struct dpp_global *dpp,
        ctrl->cb_ctx = config->cb_ctx;
        ctrl->tx = config->tx;
        ctrl->gas_resp_tx = config->gas_resp_tx;
+       wpa_printf(MSG_DEBUG, "DPP: Add Relay connection to Controller %s",
+                  hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt)));
        dl_list_add(&dpp->controllers, &ctrl->list);
        return 0;
 }
@@ -2344,6 +2347,10 @@ void dpp_tcp_init_flush(struct dpp_global *dpp)
 static void dpp_relay_controller_free(struct dpp_relay_controller *ctrl)
 {
        struct dpp_connection *conn, *tmp;
+       char txt[100];
+
+       wpa_printf(MSG_DEBUG, "DPP: Remove Relay connection to Controller %s",
+                  hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt)));
 
        dl_list_for_each_safe(conn, tmp, &ctrl->conn, struct dpp_connection,
                              list)
@@ -2372,6 +2379,31 @@ void dpp_relay_flush_controllers(struct dpp_global *dpp)
 }
 
 
+void dpp_relay_remove_controller(struct dpp_global *dpp,
+                                const struct hostapd_ip_addr *addr)
+{
+       struct dpp_relay_controller *ctrl;
+
+       if (!dpp)
+               return;
+
+       dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller,
+                        list) {
+               if (hostapd_ip_equal(&ctrl->ipaddr, addr)) {
+                       dl_list_del(&ctrl->list);
+                       dpp_relay_controller_free(ctrl);
+                       return;
+               }
+       }
+
+       if (dpp->tmp_controller &&
+           hostapd_ip_equal(&dpp->tmp_controller->ipaddr, addr)) {
+               dpp_relay_controller_free(dpp->tmp_controller);
+               dpp->tmp_controller = NULL;
+       }
+}
+
+
 static void dpp_relay_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx)
 {
        struct dpp_global *dpp = eloop_ctx;