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;
|
reply_len = -1;
|
||||||
} else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {
|
} else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {
|
||||||
hostapd_dpp_chirp_stop(hapd);
|
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 */
|
#endif /* CONFIG_DPP2 */
|
||||||
#ifdef CONFIG_DPP3
|
#ifdef CONFIG_DPP3
|
||||||
} else if (os_strcmp(buf, "DPP_PUSH_BUTTON") == 0) {
|
} else if (os_strcmp(buf, "DPP_PUSH_BUTTON") == 0) {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "gas_query_ap.h"
|
#include "gas_query_ap.h"
|
||||||
#include "gas_serv.h"
|
#include "gas_serv.h"
|
||||||
#include "wpa_auth.h"
|
#include "wpa_auth.h"
|
||||||
|
#include "beacon.h"
|
||||||
#include "dpp_hostapd.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)
|
int hostapd_dpp_init(struct hostapd_data *hapd)
|
||||||
{
|
{
|
||||||
hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
|
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);
|
int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd);
|
||||||
void hostapd_dpp_push_button_stop(struct hostapd_data *hapd);
|
void hostapd_dpp_push_button_stop(struct hostapd_data *hapd);
|
||||||
bool hostapd_dpp_configurator_connectivity(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 */
|
#endif /* DPP_HOSTAPD_H */
|
||||||
|
|
|
@ -749,6 +749,8 @@ struct dpp_configurator * dpp_configurator_find_kid(struct dpp_global *dpp,
|
||||||
const u8 *kid);
|
const u8 *kid);
|
||||||
int dpp_relay_add_controller(struct dpp_global *dpp,
|
int dpp_relay_add_controller(struct dpp_global *dpp,
|
||||||
struct dpp_relay_config *config);
|
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,
|
int dpp_relay_listen(struct dpp_global *dpp, int port,
|
||||||
struct dpp_relay_config *config);
|
struct dpp_relay_config *config);
|
||||||
void dpp_relay_stop_listen(struct dpp_global *dpp);
|
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_config *config)
|
||||||
{
|
{
|
||||||
struct dpp_relay_controller *ctrl;
|
struct dpp_relay_controller *ctrl;
|
||||||
|
char txt[100];
|
||||||
|
|
||||||
if (!dpp)
|
if (!dpp)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -154,6 +155,8 @@ int dpp_relay_add_controller(struct dpp_global *dpp,
|
||||||
ctrl->cb_ctx = config->cb_ctx;
|
ctrl->cb_ctx = config->cb_ctx;
|
||||||
ctrl->tx = config->tx;
|
ctrl->tx = config->tx;
|
||||||
ctrl->gas_resp_tx = config->gas_resp_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);
|
dl_list_add(&dpp->controllers, &ctrl->list);
|
||||||
return 0;
|
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)
|
static void dpp_relay_controller_free(struct dpp_relay_controller *ctrl)
|
||||||
{
|
{
|
||||||
struct dpp_connection *conn, *tmp;
|
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,
|
dl_list_for_each_safe(conn, tmp, &ctrl->conn, struct dpp_connection,
|
||||||
list)
|
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)
|
static void dpp_relay_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx)
|
||||||
{
|
{
|
||||||
struct dpp_global *dpp = eloop_ctx;
|
struct dpp_global *dpp = eloop_ctx;
|
||||||
|
|
Loading…
Reference in a new issue