Пример #1
0
/**
 * p2p_parse_ies - Parse P2P message IEs (both WPS and P2P IE)
 * @data: IEs from the message
 * @len: Length of data buffer in octets
 * @msg: Buffer for returning parsed attributes
 * Returns: 0 on success, -1 on failure
 *
 * Note: Caller is responsible for clearing the msg data structure before
 * calling this function.
 *
 * Note: Caller must free temporary memory allocations by calling
 * p2p_parse_free() when the parsed data is not needed anymore.
 */
int p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg)
{
    struct ieee802_11_elems elems;

    ieee802_11_parse_elems(data, len, &elems, 0);
    if (elems.ds_params && elems.ds_params_len >= 1)
        msg->ds_params = elems.ds_params;
    if (elems.ssid)
        msg->ssid = elems.ssid - 2;

    msg->wps_attributes = ieee802_11_vendor_ie_concat(data, len,
                          WPS_DEV_OUI_WFA);
    if (msg->wps_attributes &&
            p2p_parse_wps_ie(msg->wps_attributes, msg)) {
        p2p_parse_free(msg);
        return -1;
    }

    msg->p2p_attributes = ieee802_11_vendor_ie_concat(data, len,
                          P2P_IE_VENDOR_TYPE);
    if (msg->p2p_attributes &&
            p2p_parse_p2p_ie(msg->p2p_attributes, msg)) {
        wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data");
        if (msg->p2p_attributes)
            wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data",
                            msg->p2p_attributes);
        p2p_parse_free(msg);
        return -1;
    }

    return 0;
}
int p2p_parse_ies_separate(const u8 *wsc, size_t wsc_len, const u8 *p2p,
			   size_t p2p_len, struct p2p_message *msg)
{
	os_memset(msg, 0, sizeof(*msg));

	msg->wps_attributes = wpabuf_alloc_copy(wsc, wsc_len);
	if (msg->wps_attributes &&
	    p2p_parse_wps_ie(msg->wps_attributes, msg)) {
		p2p_parse_free(msg);
		return -1;
	}

	msg->p2p_attributes = wpabuf_alloc_copy(p2p, p2p_len);
	if (msg->p2p_attributes &&
	    p2p_parse_p2p_ie(msg->p2p_attributes, msg)) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data");
		if (msg->p2p_attributes)
			wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data",
					msg->p2p_attributes);
		p2p_parse_free(msg);
		return -1;
	}

	return 0;
}
Пример #3
0
u8 p2p_get_group_capab(const struct wpabuf *p2p_ie)
{
    struct p2p_message msg;

    os_memset(&msg, 0, sizeof(msg));
    if (p2p_parse_p2p_ie(p2p_ie, &msg))
        return 0;

    if (!msg.capability)
        return 0;

    return msg.capability[1];
}
Пример #4
0
int p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie)
{
    struct p2p_message msg;

    os_memset(&msg, 0, sizeof(msg));
    if (p2p_parse_p2p_ie(p2p_ie, &msg))
        return 0;

    if (!msg.manageability)
        return 0;

    return !(msg.manageability[0] & P2P_MAN_CROSS_CONNECTION_PERMITTED);
}
Пример #5
0
const u8 * p2p_get_go_dev_addr(const struct wpabuf *p2p_ie)
{
    struct p2p_message msg;

    os_memset(&msg, 0, sizeof(msg));
    if (p2p_parse_p2p_ie(p2p_ie, &msg))
        return NULL;

    if (msg.p2p_device_addr)
        return msg.p2p_device_addr;
    if (msg.device_id)
        return msg.device_id;

    return NULL;
}
Пример #6
0
/**
 * p2p_build_client_info - Build P2P Client Info Descriptor
 * @addr: MAC address of the peer device
 * @p2p_ie: P2P IE from (Re)Association Request
 * @dev_capab: Buffer for returning Device Capability
 * @dev_addr: Buffer for returning P2P Device Address
 * Returns: P2P Client Info Descriptor or %NULL on failure
 *
 * This function builds P2P Client Info Descriptor based on the information
 * available from (Re)Association Request frame. Group owner can use this to
 * build the P2P Group Info attribute for Probe Response frames.
 */
static struct wpabuf * p2p_build_client_info(const u8 *addr,
					     struct wpabuf *p2p_ie,
					     u8 *dev_capab, u8 *dev_addr)
{
	const u8 *spos;
	struct p2p_message msg;
	u8 *len_pos;
	struct wpabuf *buf;

	if (p2p_ie == NULL)
		return NULL;

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_p2p_ie(p2p_ie, &msg) ||
	    msg.capability == NULL || msg.p2p_device_info == NULL)
		return NULL;

	buf = wpabuf_alloc(ETH_ALEN + 1 + 1 + msg.p2p_device_info_len);
	if (buf == NULL)
		return NULL;

	*dev_capab = msg.capability[0];
	os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN);

	spos = msg.p2p_device_info; /* P2P Device address */

	/* P2P Client Info Descriptor */
	/* Length to be set */
	len_pos = wpabuf_put(buf, 1);
	/* P2P Device address */
	wpabuf_put_data(buf, spos, ETH_ALEN);
	/* P2P Interface address */
	wpabuf_put_data(buf, addr, ETH_ALEN);
	/* Device Capability Bitmap */
	wpabuf_put_u8(buf, msg.capability[0]);
	/*
	 * Config Methods, Primary Device Type, Number of Secondary Device
	 * Types, Secondary Device Type List, Device Name copied from
	 * Device Info
	 */
	wpabuf_put_data(buf, spos + ETH_ALEN,
			msg.p2p_device_info_len - ETH_ALEN);

	*len_pos = wpabuf_len(buf) - 1;


	return buf;
}
Пример #7
0
/**
 * p2p_parse_ies - Parse P2P message IEs (both WPS and P2P IE)
 * @data: IEs from the message
 * @len: Length of data buffer in octets
 * @msg: Buffer for returning parsed attributes
 * Returns: 0 on success, -1 on failure
 *
 * Note: Caller is responsible for clearing the msg data structure before
 * calling this function.
 *
 * Note: Caller must free temporary memory allocations by calling
 * p2p_parse_free() when the parsed data is not needed anymore.
 */
int p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg)
{
	struct ieee802_11_elems elems;

	ieee802_11_parse_elems(data, len, &elems, 0);
	if (elems.ds_params)
		msg->ds_params = elems.ds_params;
	if (elems.ssid)
		msg->ssid = elems.ssid - 2;

	msg->wps_attributes = ieee802_11_vendor_ie_concat(data, len,
							  WPS_DEV_OUI_WFA);
	if (msg->wps_attributes &&
	    p2p_parse_wps_ie(msg->wps_attributes, msg)) {
		p2p_parse_free(msg);
		return -1;
	}

	msg->p2p_attributes = ieee802_11_vendor_ie_concat(data, len,
							  P2P_IE_VENDOR_TYPE);
	if (msg->p2p_attributes &&
	    p2p_parse_p2p_ie(msg->p2p_attributes, msg)) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data");
		if (msg->p2p_attributes)
			wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data",
					msg->p2p_attributes);
		p2p_parse_free(msg);
		return -1;
	}

#ifdef CONFIG_WIFI_DISPLAY
	if (elems.wfd) {
		msg->wfd_subelems = ieee802_11_vendor_ie_concat(
			data, len, WFD_IE_VENDOR_TYPE);
	}
#endif /* CONFIG_WIFI_DISPLAY */

	msg->pref_freq_list = elems.pref_freq_list;
	msg->pref_freq_list_len = elems.pref_freq_list_len;

	return 0;
}
Пример #8
0
int p2p_group_match_dev_id(struct p2p_group *group, struct wpabuf *p2p)
{
	struct p2p_group_member *m;
	struct p2p_message msg;

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_p2p_ie(p2p, &msg))
		return 1; /* Failed to parse - assume no filter on Device ID */

	if (!msg.device_id)
		return 1; /* No filter on Device ID */

	if (os_memcmp(msg.device_id, group->p2p->cfg->dev_addr, ETH_ALEN) == 0)
		return 1; /* Match with our P2P Device Address */

	for (m = group->members; m; m = m->next) {
		if (os_memcmp(msg.device_id, m->dev_addr, ETH_ALEN) == 0)
			return 1; /* Match with group client P2P Device Address */
	}

	/* No match with Device ID */
	return 0;
}
Пример #9
0
/**
 * p2p_attr_text - Build text format description of P2P IE attributes
 * @data: P2P IE contents
 * @buf: Buffer for returning text
 * @end: Pointer to the end of the buf area
 * Returns: Number of octets written to the buffer or -1 on faikure
 *
 * This function can be used to parse P2P IE contents into text format
 * field=value lines.
 */
int p2p_attr_text(struct wpabuf *data, char *buf, char *end)
{
    struct p2p_message msg;
    char *pos = buf;
    int ret;

    os_memset(&msg, 0, sizeof(msg));
    if (p2p_parse_p2p_ie(data, &msg))
        return -1;

    if (msg.capability) {
        ret = os_snprintf(pos, end - pos,
                          "p2p_dev_capab=0x%x\n"
                          "p2p_group_capab=0x%x\n",
                          msg.capability[0], msg.capability[1]);
        if (ret < 0 || ret >= end - pos)
            return pos - buf;
        pos += ret;
    }

    if (msg.pri_dev_type) {
        char devtype[WPS_DEV_TYPE_BUFSIZE];
        ret = os_snprintf(pos, end - pos,
                          "p2p_primary_device_type=%s\n",
                          wps_dev_type_bin2str(msg.pri_dev_type,
                                               devtype,
                                               sizeof(devtype)));
        if (ret < 0 || ret >= end - pos)
            return pos - buf;
        pos += ret;
    }

    ret = os_snprintf(pos, end - pos, "p2p_device_name=%s\n",
                      msg.device_name);
    if (ret < 0 || ret >= end - pos)
        return pos - buf;
    pos += ret;

    if (msg.p2p_device_addr) {
        ret = os_snprintf(pos, end - pos, "p2p_device_addr=" MACSTR
                          "\n",
                          MAC2STR(msg.p2p_device_addr));
        if (ret < 0 || ret >= end - pos)
            return pos - buf;
        pos += ret;
    }

    ret = os_snprintf(pos, end - pos, "p2p_config_methods=0x%x\n",
                      msg.config_methods);
    if (ret < 0 || ret >= end - pos)
        return pos - buf;
    pos += ret;

    ret = p2p_group_info_text(msg.group_info, msg.group_info_len,
                              pos, end);
    if (ret < 0)
        return pos - buf;
    pos += ret;

    return pos - buf;
}