Example #1
0
static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
                            struct wpa_ft_ies *parse)
{
    const u8 *end, *pos;
    struct wpa_ie_data data;
    int ret;

    os_memset(parse, 0, sizeof(*parse));
    if (ies == NULL)
        return 0;

    pos = ies;
    end = ies + ies_len;
    while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
        switch (pos[0]) {
        case WLAN_EID_RSN:
            parse->rsn = pos + 2;
            parse->rsn_len = pos[1];
            ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
                                       parse->rsn_len + 2,
                                       &data);
            if (ret < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse "
                           "RSN IE: %d", ret);
                return -1;
            }
            if (data.num_pmkid == 1 && data.pmkid)
                parse->rsn_pmkid = data.pmkid;
            break;
        case WLAN_EID_MOBILITY_DOMAIN:
            parse->mdie = pos + 2;
            parse->mdie_len = pos[1];
            break;
        case WLAN_EID_FAST_BSS_TRANSITION:
            if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
                return -1;
            break;
        case WLAN_EID_TIMEOUT_INTERVAL:
            parse->tie = pos + 2;
            parse->tie_len = pos[1];
            break;
        }

        pos += 2 + pos[1];
    }

    return 0;
}
Example #2
0
static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
			    struct wpa_ft_ies *parse)
{
	const u8 *end, *pos;
	struct wpa_ie_data data;
	int ret;
	const struct rsn_ftie *ftie;
	int prot_ie_count = 0;

	os_memset(parse, 0, sizeof(*parse));
	if (ies == NULL)
		return 0;

	pos = ies;
	end = ies + ies_len;
	while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
		switch (pos[0]) {
		case WLAN_EID_RSN:
			parse->rsn = pos + 2;
			parse->rsn_len = pos[1];
			ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
						   parse->rsn_len + 2,
						   &data);
			if (ret < 0) {
				wpa_printf(MSG_DEBUG, "FT: Failed to parse "
					   "RSN IE: %d", ret);
				return -1;
			}
			if (data.num_pmkid == 1 && data.pmkid)
				parse->rsn_pmkid = data.pmkid;
			break;
		case WLAN_EID_MOBILITY_DOMAIN:
			parse->mdie = pos + 2;
			parse->mdie_len = pos[1];
			break;
		case WLAN_EID_FAST_BSS_TRANSITION:
			if (pos[1] < sizeof(*ftie))
				return -1;
			ftie = (const struct rsn_ftie *) (pos + 2);
			prot_ie_count = ftie->mic_control[1];
			if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
				return -1;
			break;
		case WLAN_EID_RIC_DATA:
			if (parse->ric == NULL)
				parse->ric = pos;
		}

		pos += 2 + pos[1];
	}

	if (prot_ie_count == 0)
		return 0; /* no MIC */

	/*
	 * Check that the protected IE count matches with IEs included in the
	 * frame.
	 */
	if (parse->rsn)
		prot_ie_count--;
	if (parse->mdie)
		prot_ie_count--;
	if (parse->ftie)
		prot_ie_count--;
	if (prot_ie_count < 0) {
		wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
			   "the protected IE count");
		return -1;
	}

	if (prot_ie_count == 0 && parse->ric) {
		wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
			   "included in protected IE count");
		return -1;
	}

	/* Determine the end of the RIC IE(s) */
	pos = parse->ric;
	while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
	       prot_ie_count) {
		prot_ie_count--;
		pos += 2 + pos[1];
	}
	parse->ric_len = pos - parse->ric;
	if (prot_ie_count) {
		wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
			   "frame", (int) prot_ie_count);
		return -1;
	}

	return 0;
}