}
+static int iftype_str_to_index(const char *iftype_str)
+{
+ if (!iftype_str)
+ return WPA_IF_MAX;
+
+ if (os_strcmp(iftype_str, "STATION") == 0)
+ return WPA_IF_STATION;
+
+ if (os_strcmp(iftype_str, "AP_VLAN") == 0)
+ return WPA_IF_AP_VLAN;
+
+ if (os_strcmp(iftype_str, "AP") == 0)
+ return WPA_IF_AP_BSS;
+
+ if (os_strcmp(iftype_str, "P2P_GO") == 0)
+ return WPA_IF_P2P_GO;
+
+ if (os_strcmp(iftype_str, "P2P_CLIENT") == 0)
+ return WPA_IF_P2P_CLIENT;
+
+ if (os_strcmp(iftype_str, "P2P_DEVICE") == 0)
+ return WPA_IF_P2P_DEVICE;
+
+ if (os_strcmp(iftype_str, "MESH") == 0)
+ return WPA_IF_MESH;
+
+ if (os_strcmp(iftype_str, "IBSS") == 0)
+ return WPA_IF_IBSS;
+
+ if (os_strcmp(iftype_str, "NAN") == 0)
+ return WPA_IF_NAN;
+
+ return WPA_IF_MAX;
+}
+
+
static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
struct wpa_driver_capa *capa,
+ const char *iftype_str,
char *buf, size_t buflen)
{
int ret;
+ unsigned int key_mgmt;
char *pos, *end;
size_t len;
return len;
}
+ if (iftype_str) {
+ enum wpa_driver_if_type iftype;
+
+ iftype = iftype_str_to_index(iftype_str);
+ if (iftype == WPA_IF_MAX)
+ return -1;
+ key_mgmt = capa->key_mgmt_iftype[iftype];
+ } else {
+ key_mgmt = capa->key_mgmt;
+ }
+
ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
- if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
+ if (key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
+ WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
ret = os_snprintf(pos, end - pos, " WPA-EAP");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
- if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
+ if (key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
+ WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
ret = os_snprintf(pos, end - pos, " WPA-PSK");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
ret = os_snprintf(pos, end - pos, " WPA-NONE");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
}
#ifdef CONFIG_SUITEB
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B) {
ret = os_snprintf(pos, end - pos, " WPA-EAP-SUITE-B");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
}
#endif /* CONFIG_SUITEB */
#ifdef CONFIG_SUITEB192
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
ret = os_snprintf(pos, end - pos, " WPA-EAP-SUITE-B-192");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
}
#endif /* CONFIG_SUITEB192 */
#ifdef CONFIG_OWE
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
ret = os_snprintf(pos, end - pos, " OWE");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
}
#endif /* CONFIG_OWE */
#ifdef CONFIG_DPP
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
ret = os_snprintf(pos, end - pos, " DPP");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
}
#endif /* CONFIG_DPP */
#ifdef CONFIG_FILS
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
ret = os_snprintf(pos, end - pos, " FILS-SHA256");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
ret = os_snprintf(pos, end - pos, " FILS-SHA384");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
#ifdef CONFIG_IEEE80211R
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256) {
ret = os_snprintf(pos, end - pos, " FT-FILS-SHA256");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384) {
ret = os_snprintf(pos, end - pos, " FT-FILS-SHA384");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
#endif /* CONFIG_IEEE80211R */
#endif /* CONFIG_FILS */
#ifdef CONFIG_IEEE80211R
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) {
ret = os_snprintf(pos, end - pos, " FT-PSK");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_SAE
- if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
+ if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
ret = os_snprintf(pos, end - pos, " SAE");
if (os_snprintf_error(end - pos, ret))
return pos - buf;
{
struct wpa_driver_capa capa;
int res;
- char *strict;
- char field[30];
+ char *next_param, *curr_param, *iftype = NULL, *strict = NULL;
+ char field[50];
size_t len;
/* Determine whether or not strict checking was requested */
len = os_strlcpy(field, _field, sizeof(field));
if (len >= sizeof(field))
return -1;
- strict = os_strchr(field, ' ');
- if (strict != NULL) {
- *strict++ = '\0';
- if (os_strcmp(strict, "strict") != 0)
+
+ next_param = os_strchr(field, ' ');
+ while (next_param) {
+ *next_param++ = '\0';
+ curr_param = next_param;
+ next_param = os_strchr(next_param, ' ');
+
+ if (next_param)
+ *next_param = '\0';
+
+ if (os_strcmp(curr_param, "strict") == 0)
+ strict = curr_param;
+ else if (os_strncmp(curr_param, "iftype=", 7) == 0)
+ iftype = curr_param + 7;
+ else
return -1;
}
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
- field, strict ? strict : "");
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s'%s%s%s",
+ field, iftype ? " iftype=" : "", iftype ? iftype : "",
+ strict ? " strict" : "");
if (os_strcmp(field, "eap") == 0) {
return eap_get_names(buf, buflen);
if (os_strcmp(field, "key_mgmt") == 0)
return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
- buf, buflen);
+ iftype, buf, buflen);
if (os_strcmp(field, "proto") == 0)
return ctrl_iface_get_capability_proto(res, strict, &capa,
static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
- if (argc < 1 || argc > 2) {
- printf("Invalid GET_CAPABILITY command: need either one or "
- "two arguments\n");
+ if (argc < 1 || argc > 3) {
+ printf("Invalid GET_CAPABILITY command: need at least one argument and max three arguments\n");
return -1;
}
- if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
- printf("Invalid GET_CAPABILITY command: second argument, "
- "if any, must be 'strict'\n");
+ if (argc > 1 && os_strcmp(argv[0], "key_mgmt") != 0 &&
+ os_strncmp(argv[1], "iftype=", 7) == 0) {
+ printf("Invalid GET_CAPABILITY command: 'iftype=' param is allowed only for 'key_mgmt'\n");
+ return -1;
+ }
+
+ if (argc == 2 && os_strcmp(argv[1], "strict") != 0 &&
+ os_strncmp(argv[1], "iftype=", 7) != 0) {
+ printf("Invalid GET_CAPABILITY command: the second argument, if any, must be 'strict' OR 'iftype=<iftype_name>'\n");
+ return -1;
+ }
+
+ if (argc == 3 && os_strcmp(argv[2], "strict") != 0) {
+ printf("Invalid GET_CAPABILITY command: the third argument, if any, must be 'strict'\n");
return -1;
}
"acs",
#endif /* CONFIG_ACS */
};
+ const char *iftypes[] = {
+ "iftype=STATION", "iftype=AP", "iftype=P2P_CLIENT",
+ "iftype=P2P_GO", "iftype=AP_VLAN", "iftype=IBSS", "iftype=NAN",
+ "iftype=P2P_DEVICE", "iftype=MESH",
+ };
int i, num_fields = ARRAY_SIZE(fields);
+ int num_iftypes = ARRAY_SIZE(iftypes);
char **res = NULL;
if (arg == 1) {
}
}
if (arg == 2) {
+ /* the second argument can be "iftype=<iftype_name>" OR
+ * "strict" */
+ res = os_calloc(num_iftypes + 2, sizeof(char *));
+ if (!res)
+ return NULL;
+ res[0] = os_strdup("strict");
+ if (!res[0])
+ return res;
+ for (i = 0; i < num_iftypes; i++) {
+ res[i + 1] = os_strdup(iftypes[i]);
+ if (!res[i + 1])
+ return res;
+ }
+ }
+ if (arg == 3) {
res = os_calloc(1 + 1, sizeof(char *));
if (res == NULL)
return NULL;