From patchwork Mon Aug 5 09:33:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shivani Baranwal X-Patchwork-Id: 1969027 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=g5GMmYY9; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=quicinc.com header.i=@quicinc.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=bRGnYv4Z; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WctQ46QlWz20Mv for ; Mon, 5 Aug 2024 20:45:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=DgxWPVzlpsz+IMGFenuRy8ZK4mclCxMG5wdbLWAe2xg=; b=g5GMmYY9Sr34dm 4OakkHBsFxtzArR/eYRw2kRRiZgX5C3Fhb5TMe27KHBdnfMj7TGhdxg7tXKwBDJ+bJWdcgz1rfypo BzqIU5SN7IQdbN4LnYgIMohz6HcFswJAgYO49AYcrcSODFyYrupZtWF0pV8cEMFejX2oVDzfJSQXc JEDOVnZT+WN2+kDXAb+ovrblojSiYfJL5XPFahUBtOyqmHQex4m3DZLIpquqTQ0D71GNGG4iscv1V c0tAqUezgNTbxqsWbR+oebCJUc77bnrpUgbu38Q6sCtacTI259B8XnT9AEaRoz6KBD5BkGGaaaI1o s0G57PpASCJQGnV734Yw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1savDX-0000000FZAt-1BEX; Mon, 05 Aug 2024 10:45:31 +0000 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sau6s-0000000FIpE-3moD for hostap@lists.infradead.org; Mon, 05 Aug 2024 09:34:40 +0000 Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4752Vj1t019240 for ; Mon, 5 Aug 2024 09:34:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=0rlfFrvu8ikQAoSxlSwLcbPn BgwnrWhf+uLXoQ3kNbE=; b=bRGnYv4ZoQleVmU6rEe/JwAq3QQar5cKtTOsnUxX gzXL9F9vlene3vPuprddVGrMIW/4YpIHYwUDtvnyJktGE0ToBqcztnKR1wz2aCIO nv4rrT90xvdqZv4LddCuz1o4OT65o0Abfm/xVvtfcf5iDPU9NIb7I/Y3QVuEMprr VDGsOhpiKU25PqqFjgOQAK/4jFM3T48s/eMjrc93GTWQcrJfXg5520VCr2idMUtq 77aaDRmJMwrutgp/MAMOPiHkg4xjeQcLNxm4kEIpGUy3fL1KugaTtoMiNr826JkK NtrvlXnBRuUW5lRytflo7H/9x/9qIai04vUr9z8iNcykXQ== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40scs2uef6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 05 Aug 2024 09:34:34 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA02.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 4759YXrE008699 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 5 Aug 2024 09:34:33 GMT Received: from hu-shivbara-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 5 Aug 2024 02:34:31 -0700 From: Shivani Baranwal To: CC: Subject: [PATCH v3 15/25] P2P: Encapsulate P2P2 vendor IE with size more than 255 bytes Date: Mon, 5 Aug 2024 15:03:13 +0530 Message-ID: <1722850403-8852-16-git-send-email-quic_shivbara@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1722850403-8852-1-git-send-email-quic_shivbara@quicinc.com> References: <1722850403-8852-1-git-send-email-quic_shivbara@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: i4gGF4pPTMgVtKlmSBfOcl6BmMGI-HFX X-Proofpoint-GUID: i4gGF4pPTMgVtKlmSBfOcl6BmMGI-HFX X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-08-04_14,2024-08-02_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 bulkscore=0 suspectscore=0 adultscore=0 spamscore=0 priorityscore=1501 impostorscore=0 lowpriorityscore=0 mlxlogscore=999 phishscore=0 malwarescore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2407110000 definitions=main-2408050067 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240805_023435_176242_84346C68 X-CRM114-Status: GOOD ( 20.25 ) X-Spam-Score: -2.1 (--) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Add support to encapsulate vendor IE exceeding 255 bytes in go negotiation frames and action wrapper IE of pasn auth frames for p2p2. Signed-off-by: Shivani Baranwal --- src/p2p/p2p_build.c | 35 +++++++++++++ src/p2p/p2p_go_neg.c | 137 +++++++++++++++++++++++++++++ src/p2p/p2p_i.h | [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [205.220.168.131 listed in sa-accredit.habeas.com] 0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [205.220.168.131 listed in sa-trusted.bondedsender.org] 0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [205.220.168.131 listed in bl.score.senderscore.com] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add support to encapsulate vendor IE exceeding 255 bytes in go negotiation frames and action wrapper IE of pasn auth frames for p2p2. Signed-off-by: Shivani Baranwal --- src/p2p/p2p_build.c | 35 +++++++++++++ src/p2p/p2p_go_neg.c | 137 +++++++++++++++++++++++++++++---------------------- src/p2p/p2p_i.h | 2 + 3 files changed, 115 insertions(+), 59 deletions(-) diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c index 182af37..f505ad9 100644 --- a/src/p2p/p2p_build.c +++ b/src/p2p/p2p_build.c @@ -1022,3 +1022,38 @@ int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id, return 0; } + + +struct wpabuf *p2p_encaps_p2p_vendor_ie(struct p2p_data *p2p, + struct wpabuf *subelems, u32 ie_type) +{ + struct wpabuf *ie; + const u8 *pos, *end; + size_t len; + + if (!subelems) + return NULL; + + len = wpabuf_len(subelems) + 1000; + + ie = wpabuf_alloc(len); + if (!ie) + return NULL; + + pos = wpabuf_head(subelems); + end = pos + wpabuf_len(subelems); + + while (end > pos) { + size_t frag_len = end - pos; + + if (frag_len > 251) + frag_len = 251; + wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC); + wpabuf_put_u8(ie, 4 + frag_len); + wpabuf_put_be32(ie, ie_type); + wpabuf_put_data(ie, pos, frag_len); + pos += frag_len; + } + + return ie; +} diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 58ea89c..5798018 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -138,12 +138,11 @@ static const char * p2p_wps_method_str(enum p2p_wps_method wps_method) static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p, struct p2p_device *peer) { - struct wpabuf *buf; - u8 *len; u8 group_capab; size_t extra = 0; u16 pw_id; bool is_6ghz_capab; + struct wpabuf *buf, *buf2, *p2p_ie; #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_go_neg) @@ -153,13 +152,16 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p, if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]) extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]); - buf = wpabuf_alloc(1000 + extra); - if (buf == NULL) + buf2 = wpabuf_alloc(1000 + extra); + if (!buf2) return NULL; - p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_REQ, peer->dialog_token); + p2p_buf_add_public_action_hdr(buf2, P2P_GO_NEG_REQ, peer->dialog_token); + + p2p_ie = wpabuf_alloc(500); + if (!p2p_ie) + return NULL; - len = p2p_buf_add_ie_hdr(buf); group_capab = 0; if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP; @@ -170,17 +172,17 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p, group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; if (p2p->cfg->p2p_intra_bss) group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; - p2p_buf_add_capability(buf, p2p->dev_capab & + p2p_buf_add_capability(p2p_ie, p2p->dev_capab & ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, group_capab); - p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | peer->tie_breaker); - p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout); - p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class, + p2p_buf_add_go_intent(p2p_ie, (p2p->go_intent << 1) | peer->tie_breaker); + p2p_buf_add_config_timeout(p2p_ie, p2p->go_timeout, p2p->client_timeout); + p2p_buf_add_listen_channel(p2p_ie, p2p->cfg->country, p2p->cfg->reg_class, p2p->cfg->channel); if (p2p->ext_listen_interval) - p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, + p2p_buf_add_ext_listen_timing(p2p_ie, p2p->ext_listen_period, p2p->ext_listen_interval); - p2p_buf_add_intended_addr(buf, p2p->intended_addr); + p2p_buf_add_intended_addr(p2p_ie, p2p->intended_addr); is_6ghz_capab = is_p2p_6ghz_capable(p2p) && p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr); if (p2p->num_pref_freq) { @@ -191,37 +193,41 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p, p2p->num_pref_freq, &pref_chanlist, go); p2p_channels_dump(p2p, "channel list after filtering", &pref_chanlist); - p2p_buf_add_channel_list(buf, p2p->cfg->country, + p2p_buf_add_channel_list(p2p_ie, p2p->cfg->country, &pref_chanlist, is_6ghz_capab); } else { - p2p_buf_add_channel_list(buf, p2p->cfg->country, + p2p_buf_add_channel_list(p2p_ie, p2p->cfg->country, &p2p->channels, is_6ghz_capab); } - p2p_buf_add_device_info(buf, p2p, peer); - p2p_buf_add_operating_channel(buf, p2p->cfg->country, + p2p_buf_add_device_info(p2p_ie, p2p, peer); + p2p_buf_add_operating_channel(p2p_ie, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); - p2p_buf_update_ie_hdr(buf, len); - p2p_buf_add_pref_channel_list(buf, p2p->pref_freq_list, + buf = p2p_encaps_p2p_vendor_ie(p2p, p2p_ie, P2P_IE_VENDOR_TYPE); + wpabuf_free(p2p_ie); + + p2p_buf_add_pref_channel_list(buf2, p2p->pref_freq_list, p2p->num_pref_freq); /* WPS IE with Device Password ID attribute */ pw_id = p2p_wps_method_pw_id(peer->wps_method); if (peer->oob_pw_id) pw_id = peer->oob_pw_id; - if (p2p_build_wps_ie(p2p, buf, pw_id, 0) < 0) { + if (peer && !peer->p2p2 && p2p_build_wps_ie(p2p, buf2, pw_id, 0) < 0) { p2p_dbg(p2p, "Failed to build WPS IE for GO Negotiation Request"); + wpabuf_free(buf2); wpabuf_free(buf); return NULL; } #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_go_neg) - wpabuf_put_buf(buf, p2p->wfd_ie_go_neg); + wpabuf_put_buf(buf2, p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]) - wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]); + wpabuf_put_buf(buf2, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]); + buf = wpabuf_concat(buf2, buf); return buf; } @@ -292,13 +298,12 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, u8 dialog_token, u8 status, u8 tie_breaker) { - struct wpabuf *buf; - u8 *len; u8 group_capab; size_t extra = 0; u16 pw_id; bool is_6ghz_capab; struct p2p_channels pref_chanlist; + struct wpabuf *buf, *buf2, *p2p_ie; p2p_dbg(p2p, "Building GO Negotiation Response"); @@ -310,14 +315,17 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]) extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]); - buf = wpabuf_alloc(1000 + extra); - if (buf == NULL) + buf2 = wpabuf_alloc(1000 + extra); + if (!buf2) return NULL; - p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_RESP, dialog_token); + p2p_buf_add_public_action_hdr(buf2, P2P_GO_NEG_RESP, dialog_token); - len = p2p_buf_add_ie_hdr(buf); - p2p_buf_add_status(buf, status); + p2p_ie = wpabuf_alloc(500); + if (!p2p_ie) + return NULL; + + p2p_buf_add_status(p2p_ie, status); group_capab = 0; if (peer && peer->go_state == LOCAL_GO) { if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { @@ -331,24 +339,25 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, if (p2p->cfg->p2p_intra_bss) group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; } - p2p_buf_add_capability(buf, p2p->dev_capab & + p2p_buf_add_capability(p2p_ie, p2p->dev_capab & ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, group_capab); - p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker); - p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout); + p2p_buf_add_go_intent(p2p_ie, (p2p->go_intent << 1) | tie_breaker); + p2p_buf_add_config_timeout(p2p_ie, p2p->go_timeout, p2p->client_timeout); if (p2p->override_pref_op_class) { p2p_dbg(p2p, "Override operating channel preference"); - p2p_buf_add_operating_channel(buf, p2p->cfg->country, + p2p_buf_add_operating_channel(p2p_ie, p2p->cfg->country, p2p->override_pref_op_class, p2p->override_pref_channel); } else if (peer && peer->go_state == REMOTE_GO && !p2p->num_pref_freq) { p2p_dbg(p2p, "Omit Operating Channel attribute"); } else { - p2p_buf_add_operating_channel(buf, p2p->cfg->country, + p2p_buf_add_operating_channel(p2p_ie, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); } - p2p_buf_add_intended_addr(buf, p2p->intended_addr); + p2p_buf_add_intended_addr(p2p_ie, p2p->intended_addr); + if (p2p->num_pref_freq) { bool go = (peer && peer->go_state == LOCAL_GO) || p2p->go_intent == 15; @@ -362,12 +371,12 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, p2p->allow_6ghz); } if (status || peer == NULL) { - p2p_buf_add_channel_list(buf, p2p->cfg->country, + p2p_buf_add_channel_list(p2p_ie, p2p->cfg->country, &pref_chanlist, false); } else if (peer->go_state == REMOTE_GO) { is_6ghz_capab = is_p2p_6ghz_capable(p2p) && p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr); - p2p_buf_add_channel_list(buf, p2p->cfg->country, + p2p_buf_add_channel_list(p2p_ie, p2p->cfg->country, &pref_chanlist, is_6ghz_capab); } else { struct p2p_channels res; @@ -376,33 +385,37 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr); p2p_channels_intersect(&pref_chanlist, &peer->channels, &res); - p2p_buf_add_channel_list(buf, p2p->cfg->country, &res, - is_6ghz_capab); + p2p_buf_add_channel_list(p2p_ie, p2p->cfg->country, &res, + is_6ghz_capab); } - p2p_buf_add_device_info(buf, p2p, peer); + p2p_buf_add_device_info(p2p_ie, p2p, peer); if (peer && peer->go_state == LOCAL_GO) { - p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid, + p2p_buf_add_group_id(p2p_ie, p2p->cfg->dev_addr, p2p->ssid, p2p->ssid_len); } - p2p_buf_update_ie_hdr(buf, len); + + buf = p2p_encaps_p2p_vendor_ie(p2p, p2p_ie, P2P_IE_VENDOR_TYPE); + wpabuf_free(p2p_ie); /* WPS IE with Device Password ID attribute */ pw_id = p2p_wps_method_pw_id(peer ? peer->wps_method : WPS_NOT_READY); if (peer && peer->oob_pw_id) pw_id = peer->oob_pw_id; - if (p2p_build_wps_ie(p2p, buf, pw_id, 0) < 0) { + if (peer && !peer->p2p2 && p2p_build_wps_ie(p2p, buf2, pw_id, 0) < 0) { p2p_dbg(p2p, "Failed to build WPS IE for GO Negotiation Response"); + wpabuf_free(buf2); wpabuf_free(buf); return NULL; } #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_go_neg) - wpabuf_put_buf(buf, p2p->wfd_ie_go_neg); + wpabuf_put_buf(buf2, p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]) - wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]); + wpabuf_put_buf(buf2, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]); + buf = wpabuf_concat(buf2, buf); return buf; } @@ -1163,12 +1176,11 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p, u8 dialog_token, u8 status, const u8 *resp_chan, int go) { - struct wpabuf *buf; - u8 *len; struct p2p_channels res; u8 group_capab; size_t extra = 0; bool is_6ghz_capab; + struct wpabuf *buf, *buf2, *p2p_ie; p2p_dbg(p2p, "Building GO Negotiation Confirm"); @@ -1180,14 +1192,17 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p, if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]) extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]); - buf = wpabuf_alloc(1000 + extra); - if (buf == NULL) + buf2 = wpabuf_alloc(1000 + extra); + if (!buf2) return NULL; - p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_CONF, dialog_token); + p2p_buf_add_public_action_hdr(buf2, P2P_GO_NEG_CONF, dialog_token); + + p2p_ie = wpabuf_alloc(500); + if (!p2p_ie) + return NULL; - len = p2p_buf_add_ie_hdr(buf); - p2p_buf_add_status(buf, status); + p2p_buf_add_status(p2p_ie, status); group_capab = 0; if (peer->go_state == LOCAL_GO) { if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { @@ -1201,33 +1216,37 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p, if (p2p->cfg->p2p_intra_bss) group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; } - p2p_buf_add_capability(buf, p2p->dev_capab & + p2p_buf_add_capability(p2p_ie, p2p->dev_capab & ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, group_capab); if (go || resp_chan == NULL) - p2p_buf_add_operating_channel(buf, p2p->cfg->country, + p2p_buf_add_operating_channel(p2p_ie, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); else - p2p_buf_add_operating_channel(buf, (const char *) resp_chan, + p2p_buf_add_operating_channel(p2p_ie, (const char *) resp_chan, resp_chan[3], resp_chan[4]); p2p_channels_intersect(&p2p->channels, &peer->channels, &res); is_6ghz_capab = is_p2p_6ghz_capable(p2p) && p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr); - p2p_buf_add_channel_list(buf, p2p->cfg->country, &res, is_6ghz_capab); + p2p_buf_add_channel_list(p2p_ie, p2p->cfg->country, &res, is_6ghz_capab); if (go) { - p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid, + p2p_buf_add_group_id(p2p_ie, p2p->cfg->dev_addr, p2p->ssid, p2p->ssid_len); } - p2p_buf_update_ie_hdr(buf, len); + + buf = p2p_encaps_p2p_vendor_ie(p2p, p2p_ie, P2P_IE_VENDOR_TYPE); + wpabuf_free(p2p_ie); #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_go_neg) - wpabuf_put_buf(buf, p2p->wfd_ie_go_neg); + wpabuf_put_buf(buf2, p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]) - wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]); + wpabuf_put_buf(buf2, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]); + + buf = wpabuf_concat(buf2, buf); return buf; } diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index c3dfcea..d7a5dc1 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -901,6 +901,8 @@ int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id, void p2p_buf_add_pref_channel_list(struct wpabuf *buf, const struct weighted_pcl *pref_freq_list, unsigned int size); +struct wpabuf *p2p_encaps_p2p_vendor_ie(struct p2p_data *p2p, + struct wpabuf *subelems, u32 ie_type); /* p2p_sd.c */ struct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p,