DPP: Allow Relay connections to Controllers to be added and removed
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>
This commit is contained in:
parent
808834b18b
commit
bfe3cfc382
5 changed files with 101 additions and 0 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue