From patchwork Fri Jul 19 04:39:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shivani Baranwal X-Patchwork-Id: 1962286 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=H9pk0Bmb; 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=ZBOKex+W; 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 4WQH7g0b2Tz20FP for ; Fri, 19 Jul 2024 14:41:33 +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=i1oltNkabm7phd5jECx46tO4eaatzCnQtzVZ73O62l8=; b=H9pk0BmbMdBMlY 0iQdf8te620Aoq/XBWAfi0s+z6cTP6S3LWBkxyJi1BUq5PQzY1/JJj2N2DEE7ZtEECxV+1CjU+SMM t7M2YGAIsNfw4Oo/2fxudjBPiOZqliTpzbf12FG9RYACWLLOvcOSdCuVQbihEAh+Y5TzW1NZ2UXw3 AQy3J0Qb1nTXyHYm8DWqo+6fJY2yxF46i+ILZqq5CX+fP75mIiO7J0GmGdOfoaVXDDHa5zbMW+Xe0 0lWMAg1x5GD3rdPFGAU0JyCLL0cdM/RL/FGy4lHPJ1BmUG0WQklhg4qp4WLELdhE1/GoQIpGnq4Ih mB9dJpfiJLL/AITHu21g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sUfQd-00000001XOD-0ZH4; Fri, 19 Jul 2024 04:41:11 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sUfQR-00000001XIw-0Q0M for hostap@lists.infradead.org; Fri, 19 Jul 2024 04:41:01 +0000 Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46J0x0Nr016795 for ; Fri, 19 Jul 2024 04:40:58 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=2a2TJiVDlrpQ065yse/h/FkQ wdXdM73hg+4HG3XHTn8=; b=ZBOKex+W9MEY/DqGLpSFw+uFDsBkQnETlHGaglKE SWSy0TfF4v259UFVnvz/dTyhP2rd+6SHuun1ZC+thXZKaQcR9clJIneyzzZE9SKZ 52i8UxNs+gAu29FDtxAQ5aOfEMUzKVPlo61A3UmNZi3i/jICG8RvYTqZqVd+STPO SetR63xARixclhnUC6g3C2vh6g7V+hkOSZdGhIvqFAdwzlwmJ8O0Swvgj96zokpM uPu6X4fb8nye1QsyEheL/3L0pvAeTkLOWjr+nofj5GZFCyHT4N7vLTOxpPw/qM+7 XmqYfWcBDXyOgoS5mjhYuvCngXxo4d5gRY+N91dcq/frKg== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40fe33gc0v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 19 Jul 2024 04:40:57 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46J4eu1Z021151 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 19 Jul 2024 04:40:57 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; Thu, 18 Jul 2024 21:40:55 -0700 From: Shivani Baranwal To: CC: Subject: [PATCH v2 05/14] P2P: Cleanup of provision discovery req and resp processing Date: Fri, 19 Jul 2024 10:09:57 +0530 Message-ID: <1721364006-21658-6-git-send-email-quic_shivbara@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721364006-21658-1-git-send-email-quic_shivbara@quicinc.com> References: <1721364006-21658-1-git-send-email-quic_shivbara@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) 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: oF2VcBJQ3OUsOScYrs1d5qnSjdHvEOKd X-Proofpoint-GUID: oF2VcBJQ3OUsOScYrs1d5qnSjdHvEOKd 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-07-19_01,2024-07-18_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 bulkscore=0 priorityscore=1501 impostorscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2407110000 definitions=main-2407190035 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240718_214059_372724_8A398094 X-CRM114-Status: GOOD ( 25.29 ) 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: Parse the p2p ies in handle provision discovery req and response functions and process the frames based on the ies received in the pd frames. Signed-off-by: Shivani Baranwal --- src/p2p/p2p.c | 4 +- src/p2p/p2p_i.h | 8 +- src/p2p/p2p_pd.c | 355 ++++++++++++++++++++++++++++ 3 files chang [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -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 Parse the p2p ies in handle provision discovery req and response functions and process the frames based on the ies received in the pd frames. Signed-off-by: Shivani Baranwal --- src/p2p/p2p.c | 4 +- src/p2p/p2p_i.h | 8 +- src/p2p/p2p_pd.c | 355 ++++++++++++++++++++++++++++--------------------------- 3 files changed, 187 insertions(+), 180 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index aa6e8ed..0a5c35f 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1925,10 +1925,10 @@ static void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); break; case P2P_PROV_DISC_REQ: - p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); + p2p_handle_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); break; case P2P_PROV_DISC_RESP: - p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); + p2p_handle_prov_disc_resp(p2p, sa, data + 1, len - 1); break; case P2P_DEV_DISC_REQ: p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 787e599..2b10877 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -884,10 +884,10 @@ void p2p_check_pref_chan(struct p2p_data *p2p, int go, struct p2p_device *dev, struct p2p_message *msg); /* p2p_pd.c */ -void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq); -void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len); +void p2p_handle_prov_disc_req(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len, int rx_freq); +void p2p_handle_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len); int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, int join, int force_freq); void p2p_reset_pending_pd(struct p2p_data *p2p); diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index 7f9ee08..23bba08 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -600,10 +600,10 @@ void p2p_process_pcea(struct p2p_data *p2p, struct p2p_message *msg, } -void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq) +static void p2p_process_prov_disc_req(struct p2p_data *p2p, + struct p2p_message *msg, const u8 *sa, + const u8 *data, size_t len, int rx_freq) { - struct p2p_message msg; struct p2p_device *dev; int freq; enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; @@ -624,13 +624,10 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, u8 remote_conncap; u16 method; - if (p2p_parse(data, len, &msg)) - return; - p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR " with config methods 0x%x (freq=%d)", - MAC2STR(sa), msg.wps_config_methods, rx_freq); - group_mac = msg.intended_addr; + MAC2STR(sa), msg->wps_config_methods, rx_freq); + group_mac = msg->intended_addr; dev = p2p_get_device(p2p, sa); if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { @@ -651,29 +648,29 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, MACSTR, MAC2STR(sa)); goto out; } - } else if (msg.wfd_subelems) { + } else if (msg->wfd_subelems) { wpabuf_free(dev->info.wfd_subelems); - dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); + dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); } - p2p_update_peer_6ghz_capab(dev, &msg); + p2p_update_peer_6ghz_capab(dev, msg); - if (!msg.adv_id) { + if (!msg->adv_id) { allowed_config_methods |= WPS_CONFIG_PUSHBUTTON; - if (!(msg.wps_config_methods & allowed_config_methods)) { + if (!(msg->wps_config_methods & allowed_config_methods)) { p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request"); goto out; } /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */ - if (msg.group_id) { + if (msg->group_id) { size_t i; for (i = 0; i < p2p->num_groups; i++) { if (p2p_group_is_group_id_match( p2p->groups[i], - msg.group_id, msg.group_id_len)) + msg->group_id, msg->group_id_len)) break; } if (i == p2p->num_groups) { @@ -689,29 +686,29 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, * Set adv_id here, so in case of an error, a P2PS PD Response * will be sent. */ - adv_id = WPA_GET_LE32(msg.adv_id); - if (p2ps_validate_pd_req(p2p, &msg, sa) < 0) { + adv_id = WPA_GET_LE32(msg->adv_id); + if (p2ps_validate_pd_req(p2p, msg, sa) < 0) { reject = P2P_SC_FAIL_INVALID_PARAMS; goto out; } - req_fcap = (struct p2ps_feature_capab *) msg.feature_cap; + req_fcap = (struct p2ps_feature_capab *) msg->feature_cap; - os_memcpy(session_mac, msg.session_mac, ETH_ALEN); - os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN); + os_memcpy(session_mac, msg->session_mac, ETH_ALEN); + os_memcpy(adv_mac, msg->adv_mac, ETH_ALEN); - session_id = WPA_GET_LE32(msg.session_id); + session_id = WPA_GET_LE32(msg->session_id); - if (msg.conn_cap) - conncap = *msg.conn_cap; + if (msg->conn_cap) + conncap = *msg->conn_cap; /* * We need to verify a P2PS config methog in an initial PD * request or in a follow-on PD request with the status * SUCCESS_DEFERRED. */ - if ((!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) && - !(msg.wps_config_methods & allowed_config_methods)) { + if ((!msg->status || *msg->status == P2P_SC_SUCCESS_DEFERRED) && + !(msg->wps_config_methods & allowed_config_methods)) { p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request"); goto out; @@ -727,18 +724,18 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, P2P_DEV_PD_PEER_KEYPAD | P2P_DEV_PD_PEER_P2PS); - if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) { + if (msg->wps_config_methods & WPS_CONFIG_DISPLAY) { p2p_dbg(p2p, "Peer " MACSTR " requested us to show a PIN on display", MAC2STR(sa)); dev->flags |= P2P_DEV_PD_PEER_KEYPAD; passwd_id = DEV_PW_USER_SPECIFIED; - } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { + } else if (msg->wps_config_methods & WPS_CONFIG_KEYPAD) { p2p_dbg(p2p, "Peer " MACSTR " requested us to write its PIN using keypad", MAC2STR(sa)); dev->flags |= P2P_DEV_PD_PEER_DISPLAY; passwd_id = DEV_PW_REGISTRAR_SPECIFIED; - } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) { + } else if (msg->wps_config_methods & WPS_CONFIG_P2PS) { p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN", MAC2STR(sa)); dev->flags |= P2P_DEV_PD_PEER_P2PS; @@ -749,8 +746,8 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, if (p2p->cfg->remove_stale_groups) { p2p->cfg->remove_stale_groups( p2p->cfg->cb_ctx, dev->info.p2p_device_addr, - msg.persistent_dev, - msg.persistent_ssid, msg.persistent_ssid_len); + msg->persistent_dev, + msg->persistent_ssid, msg->persistent_ssid_len); } reject = P2P_SC_SUCCESS; @@ -759,15 +756,15 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, * End of a legacy P2P PD Request processing, from this point continue * with P2PS one. */ - if (!msg.adv_id) + if (!msg->adv_id) goto out; remote_conncap = conncap; - if (!msg.status) { + if (!msg->status) { unsigned int forced_freq, pref_freq; - if (!ether_addr_equal(p2p->cfg->dev_addr, msg.adv_mac)) { + if (!ether_addr_equal(p2p->cfg->dev_addr, msg->adv_mac)) { p2p_dbg(p2p, "P2PS PD adv mac does not match the local one"); reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; @@ -804,12 +801,12 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, "Incompatible P2PS feature capability CPT bitmask"); reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; } else if (p2ps_adv->config_methods && - !(msg.wps_config_methods & + !(msg->wps_config_methods & p2ps_adv->config_methods)) { p2p_dbg(p2p, "Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)", p2ps_adv->config_methods, - msg.wps_config_methods); + msg->wps_config_methods); reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; } else if (!p2ps_adv->state) { p2p_dbg(p2p, "P2PS state unavailable"); @@ -819,24 +816,24 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; } - if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { + if (msg->wps_config_methods & WPS_CONFIG_KEYPAD) { p2p_dbg(p2p, "Keypad - always defer"); auto_accept = 0; } if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) || - msg.persistent_dev) && conncap != P2PS_SETUP_NEW && - msg.channel_list && msg.channel_list_len && + msg->persistent_dev) && conncap != P2PS_SETUP_NEW && + msg->channel_list && msg->channel_list_len && p2p_peer_channels_check(p2p, &p2p->channels, dev, - msg.channel_list, - msg.channel_list_len) < 0) { + msg->channel_list, + msg->channel_list_len) < 0) { p2p_dbg(p2p, "No common channels - force deferred flow"); auto_accept = 0; } if (((remote_conncap & P2PS_SETUP_GROUP_OWNER) || - msg.persistent_dev) && msg.operating_channel) { + msg->persistent_dev) && msg->operating_channel) { struct p2p_channels intersect; /* @@ -847,15 +844,15 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, */ if (dev->channels.reg_classes == 0 || !p2p_channels_includes(&dev->channels, - msg.operating_channel[3], - msg.operating_channel[4])) { + msg->operating_channel[3], + msg->operating_channel[4])) { struct p2p_channels *ch = &dev->channels; os_memset(ch, 0, sizeof(*ch)); ch->reg_class[0].reg_class = - msg.operating_channel[3]; + msg->operating_channel[3]; ch->reg_class[0].channel[0] = - msg.operating_channel[4]; + msg->operating_channel[4]; ch->reg_class[0].channels = 1; ch->reg_classes = 1; } @@ -874,7 +871,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, struct p2ps_provision *tmp; if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id, - msg.wps_config_methods, + msg->wps_config_methods, session_mac, adv_mac) < 0) { reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; goto out; @@ -896,7 +893,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, } } - if (!msg.status && !auto_accept && + if (!msg->status && !auto_accept && (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) { struct p2ps_provision *tmp; @@ -906,7 +903,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, } if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id, - msg.wps_config_methods, + msg->wps_config_methods, session_mac, adv_mac) < 0) { reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; goto out; @@ -917,26 +914,26 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, } /* Not a P2PS Follow-on PD */ - if (!msg.status) + if (!msg->status) goto out; - if (*msg.status && *msg.status != P2P_SC_SUCCESS_DEFERRED) { - reject = *msg.status; + if (*msg->status && *msg->status != P2P_SC_SUCCESS_DEFERRED) { + reject = *msg->status; goto out; } - if (*msg.status != P2P_SC_SUCCESS_DEFERRED || !p2p->p2ps_prov) + if (*msg->status != P2P_SC_SUCCESS_DEFERRED || !p2p->p2ps_prov) goto out; if (p2p->p2ps_prov->adv_id != adv_id || - !ether_addr_equal(p2p->p2ps_prov->adv_mac, msg.adv_mac)) { + !ether_addr_equal(p2p->p2ps_prov->adv_mac, msg->adv_mac)) { p2p_dbg(p2p, "P2PS Follow-on PD with mismatch Advertisement ID/MAC"); goto out; } if (p2p->p2ps_prov->session_id != session_id || - !ether_addr_equal(p2p->p2ps_prov->session_mac, msg.session_mac)) { + !ether_addr_equal(p2p->p2ps_prov->session_mac, msg->session_mac)) { p2p_dbg(p2p, "P2PS Follow-on PD with mismatch Session ID/MAC"); goto out; } @@ -967,7 +964,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, else if (method & WPS_CONFIG_KEYPAD) method = WPS_CONFIG_DISPLAY; - if (!conncap || !(msg.wps_config_methods & method)) { + if (!conncap || !(msg->wps_config_methods & method)) { /* * Reject this "Deferred Accept* * if incompatible conncap or method @@ -978,11 +975,11 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, "Incompatible P2PS feature capability CPT bitmask"); reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; } else if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) || - msg.persistent_dev) && conncap != P2PS_SETUP_NEW && - msg.channel_list && msg.channel_list_len && + msg->persistent_dev) && conncap != P2PS_SETUP_NEW && + msg->channel_list && msg->channel_list_len && p2p_peer_channels_check(p2p, &p2p->channels, dev, - msg.channel_list, - msg.channel_list_len) < 0) { + msg->channel_list, + msg->channel_list_len) < 0) { p2p_dbg(p2p, "No common channels in Follow-On Provision Discovery Request"); reject = P2P_SC_FAIL_NO_COMMON_CHANNELS; @@ -994,10 +991,10 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, if (reject == P2P_SC_SUCCESS || reject == P2P_SC_SUCCESS_DEFERRED) { u8 tmp; - if (msg.operating_channel) + if (msg->operating_channel) dev->oper_freq = - p2p_channel_to_freq(msg.operating_channel[3], - msg.operating_channel[4]); + p2p_channel_to_freq(msg->operating_channel[3], + msg->operating_channel[4]); if ((conncap & P2PS_SETUP_GROUP_OWNER) && p2p_go_select_channel(p2p, dev, &tmp) < 0) @@ -1010,7 +1007,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, out: if (reject == P2P_SC_SUCCESS || reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) - config_methods = msg.wps_config_methods; + config_methods = msg->wps_config_methods; else config_methods = 0; @@ -1018,18 +1015,17 @@ out: * Send PD Response for an initial PD Request or for follow-on * PD Request with P2P_SC_SUCCESS_DEFERRED status. */ - if (!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) { - resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token, + if (!msg->status || *msg->status == P2P_SC_SUCCESS_DEFERRED) { + resp = p2p_build_prov_disc_resp(p2p, dev, msg->dialog_token, reject, config_methods, adv_id, - msg.group_id, msg.group_id_len, - msg.persistent_ssid, - msg.persistent_ssid_len, + msg->group_id, msg->group_id_len, + msg->persistent_ssid, + msg->persistent_ssid_len, (const u8 *) &resp_fcap, sizeof(resp_fcap)); - if (!resp) { - p2p_parse_free(&msg); + if (!resp) return; - } + p2p_dbg(p2p, "Sending Provision Discovery Response"); if (rx_freq > 0) freq = rx_freq; @@ -1039,7 +1035,6 @@ out: if (freq < 0) { p2p_dbg(p2p, "Unknown regulatory class/channel"); wpabuf_free(resp); - p2p_parse_free(&msg); return; } p2p->pending_action_state = P2P_PENDING_PD_RESPONSE; @@ -1054,10 +1049,8 @@ out: wpabuf_free(resp); } - if (!dev) { - p2p_parse_free(&msg); + if (!dev) return; - } freq = 0; if (reject == P2P_SC_SUCCESS && conncap == P2PS_SETUP_GROUP_OWNER) { @@ -1069,17 +1062,17 @@ out: if (!p2p->cfg->p2ps_prov_complete) { /* Don't emit anything */ - } else if (msg.status && *msg.status != P2P_SC_SUCCESS && - *msg.status != P2P_SC_SUCCESS_DEFERRED) { - reject = *msg.status; + } else if (msg->status && *msg->status != P2P_SC_SUCCESS && + *msg->status != P2P_SC_SUCCESS_DEFERRED) { + reject = *msg->status; p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject, sa, adv_mac, session_mac, NULL, adv_id, session_id, - 0, 0, msg.persistent_ssid, - msg.persistent_ssid_len, + 0, 0, msg->persistent_ssid, + msg->persistent_ssid_len, 0, 0, NULL, NULL, 0, freq, NULL, 0); - } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED && + } else if (msg->status && *msg->status == P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) { p2p->p2ps_prov->status = reject; p2p->p2ps_prov->conncap = conncap; @@ -1089,77 +1082,77 @@ out: sa, adv_mac, session_mac, NULL, adv_id, session_id, conncap, 0, - msg.persistent_ssid, - msg.persistent_ssid_len, 0, + msg->persistent_ssid, + msg->persistent_ssid_len, 0, 0, NULL, NULL, 0, freq, NULL, 0); else p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, - *msg.status, + *msg->status, sa, adv_mac, session_mac, group_mac, adv_id, session_id, conncap, passwd_id, - msg.persistent_ssid, - msg.persistent_ssid_len, 0, + msg->persistent_ssid, + msg->persistent_ssid_len, 0, 0, NULL, (const u8 *) &resp_fcap, sizeof(resp_fcap), freq, NULL, 0); - } else if (msg.status && p2p->p2ps_prov) { + } else if (msg->status && p2p->p2ps_prov) { p2p->p2ps_prov->status = P2P_SC_SUCCESS; - p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa, + p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg->status, sa, adv_mac, session_mac, group_mac, adv_id, session_id, conncap, passwd_id, - msg.persistent_ssid, - msg.persistent_ssid_len, + msg->persistent_ssid, + msg->persistent_ssid_len, 0, 0, NULL, (const u8 *) &resp_fcap, sizeof(resp_fcap), freq, NULL, 0); - } else if (msg.status) { + } else if (msg->status) { } else if (auto_accept && reject == P2P_SC_SUCCESS) { p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa, adv_mac, session_mac, group_mac, adv_id, session_id, conncap, passwd_id, - msg.persistent_ssid, - msg.persistent_ssid_len, + msg->persistent_ssid, + msg->persistent_ssid_len, 0, 0, NULL, (const u8 *) &resp_fcap, sizeof(resp_fcap), freq, - msg.group_id ? - msg.group_id + ETH_ALEN : NULL, - msg.group_id ? - msg.group_id_len - ETH_ALEN : 0); + msg->group_id ? + msg->group_id + ETH_ALEN : NULL, + msg->group_id ? + msg->group_id_len - ETH_ALEN : 0); } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE && - (!msg.session_info || !msg.session_info_len)) { - p2p->p2ps_prov->method = msg.wps_config_methods; + (!msg->session_info || !msg->session_info_len)) { + p2p->p2ps_prov->method = msg->wps_config_methods; p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa, adv_mac, session_mac, group_mac, adv_id, session_id, conncap, passwd_id, - msg.persistent_ssid, - msg.persistent_ssid_len, + msg->persistent_ssid, + msg->persistent_ssid_len, 0, 1, NULL, (const u8 *) &resp_fcap, sizeof(resp_fcap), freq, NULL, 0); } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { - size_t buf_len = msg.session_info_len; + size_t buf_len = msg->session_info_len; char *buf = os_malloc(2 * buf_len + 1); if (buf) { - p2p->p2ps_prov->method = msg.wps_config_methods; + p2p->p2ps_prov->method = msg->wps_config_methods; - utf8_escape((char *) msg.session_info, buf_len, + utf8_escape((char *) msg->session_info, buf_len, buf, 2 * buf_len + 1); p2p->cfg->p2ps_prov_complete( p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa, adv_mac, session_mac, group_mac, adv_id, session_id, conncap, passwd_id, - msg.persistent_ssid, msg.persistent_ssid_len, + msg->persistent_ssid, msg->persistent_ssid_len, 0, 1, buf, (const u8 *) &resp_fcap, sizeof(resp_fcap), freq, NULL, 0); @@ -1187,29 +1180,29 @@ out: * seeker: KEYPAD, response status: SUCCESS */ if (p2p->cfg->prov_disc_req && - ((reject == P2P_SC_SUCCESS && !msg.adv_id) || - (!msg.status && + ((reject == P2P_SC_SUCCESS && !msg->adv_id) || + (!msg->status && (reject == P2P_SC_SUCCESS || reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) && passwd_id == DEV_PW_USER_SPECIFIED) || - (!msg.status && + (!msg->status && reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE && passwd_id == DEV_PW_REGISTRAR_SPECIFIED) || (reject == P2P_SC_SUCCESS && - msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED && + msg->status && *msg->status == P2P_SC_SUCCESS_DEFERRED && passwd_id == DEV_PW_REGISTRAR_SPECIFIED))) { const u8 *dev_addr = sa; - if (msg.p2p_device_addr) - dev_addr = msg.p2p_device_addr; + if (msg->p2p_device_addr) + dev_addr = msg->p2p_device_addr; p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa, - msg.wps_config_methods, - dev_addr, msg.pri_dev_type, - msg.device_name, msg.config_methods, - msg.capability ? msg.capability[0] : 0, - msg.capability ? msg.capability[1] : + msg->wps_config_methods, + dev_addr, msg->pri_dev_type, + msg->device_name, msg->config_methods, + msg->capability ? msg->capability[0] : 0, + msg->capability ? msg->capability[1] : 0, - msg.group_id, msg.group_id_len); + msg->group_id, msg->group_id_len); } if (reject != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) @@ -1234,10 +1227,22 @@ out: break; } - if (msg.intended_addr) - os_memcpy(dev->interface_addr, msg.intended_addr, + if (msg->intended_addr) + os_memcpy(dev->interface_addr, msg->intended_addr, ETH_ALEN); } +} + + +void p2p_handle_prov_disc_req(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len, int rx_freq) +{ + struct p2p_message msg; + + if (p2p_parse(data, len, &msg)) + return; + + p2p_process_prov_disc_req(p2p, &msg, sa, data + 1, len - 1, rx_freq); p2p_parse_free(&msg); } @@ -1340,10 +1345,10 @@ static int p2p_validate_p2ps_pd_resp(struct p2p_data *p2p, } -void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len) +static void p2p_process_prov_disc_resp(struct p2p_data *p2p, + struct p2p_message *msg, const u8 *sa, + const u8 *data, size_t len) { - struct p2p_message msg; struct p2p_device *dev; u16 report_config_methods = 0, req_config_methods; u8 status = P2P_SC_SUCCESS; @@ -1354,30 +1359,26 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, int passwd_id = DEV_PW_DEFAULT; int p2ps_seeker; - if (p2p_parse(data, len, &msg)) - return; - - if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) { - p2p_parse_free(&msg); + if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, msg)) { return; } /* Parse the P2PS members present */ - if (msg.status) - status = *msg.status; + if (msg->status) + status = *msg->status; - group_mac = msg.intended_addr; + group_mac = msg->intended_addr; - if (msg.adv_mac) - os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN); + if (msg->adv_mac) + os_memcpy(adv_mac, msg->adv_mac, ETH_ALEN); else os_memset(adv_mac, 0, ETH_ALEN); - if (msg.adv_id) - adv_id = WPA_GET_LE32(msg.adv_id); + if (msg->adv_id) + adv_id = WPA_GET_LE32(msg->adv_id); - if (msg.conn_cap) { - conncap = *msg.conn_cap; + if (msg->conn_cap) { + conncap = *msg->conn_cap; /* Switch bits to local relative */ switch (conncap) { @@ -1392,25 +1393,23 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR " with config methods 0x%x", - MAC2STR(sa), msg.wps_config_methods); + MAC2STR(sa), msg->wps_config_methods); dev = p2p_get_device(p2p, sa); if (dev == NULL || !dev->req_config_methods) { p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR " with no pending request", MAC2STR(sa)); - p2p_parse_free(&msg); return; - } else if (msg.wfd_subelems) { + } else if (msg->wfd_subelems) { wpabuf_free(dev->info.wfd_subelems); - dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); + dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); } - p2p_update_peer_6ghz_capab(dev, &msg); + p2p_update_peer_6ghz_capab(dev, msg); - if (dev->dialog_token != msg.dialog_token) { + if (dev->dialog_token != msg->dialog_token) { p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)", - msg.dialog_token, dev->dialog_token); - p2p_parse_free(&msg); + msg->dialog_token, dev->dialog_token); return; } @@ -1435,14 +1434,13 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, ether_addr_equal(p2p->pending_pd_devaddr, sa)) p2p_reset_pending_pd(p2p); - if (msg.wps_config_methods != req_config_methods) { + if (msg->wps_config_methods != req_config_methods) { p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x", - msg.wps_config_methods, req_config_methods); + msg->wps_config_methods, req_config_methods); if (p2p->cfg->prov_disc_fail) p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, P2P_PROV_DISC_REJECTED, adv_id, adv_mac, NULL); - p2p_parse_free(&msg); p2ps_prov_free(p2p); goto out; } @@ -1456,13 +1454,13 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, " accepted to show a PIN on display", MAC2STR(sa)); dev->flags |= P2P_DEV_PD_PEER_DISPLAY; passwd_id = DEV_PW_REGISTRAR_SPECIFIED; - } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { + } else if (msg->wps_config_methods & WPS_CONFIG_KEYPAD) { p2p_dbg(p2p, "Peer " MACSTR " accepted to write our PIN using keypad", MAC2STR(sa)); dev->flags |= P2P_DEV_PD_PEER_KEYPAD; passwd_id = DEV_PW_USER_SPECIFIED; - } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) { + } else if (msg->wps_config_methods & WPS_CONFIG_P2PS) { p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN", MAC2STR(sa)); dev->flags |= P2P_DEV_PD_PEER_P2PS; @@ -1481,23 +1479,23 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, * fails the flow would continue, although it would probably * fail. Same is true for the operating channel. */ - if (msg.channel_list && msg.channel_list_len && + if (msg->channel_list && msg->channel_list_len && p2p_peer_channels_check(p2p, &p2p->channels, dev, - msg.channel_list, - msg.channel_list_len) < 0) + msg->channel_list, + msg->channel_list_len) < 0) p2p_dbg(p2p, "P2PS PD Response - no common channels"); - if (msg.operating_channel) { + if (msg->operating_channel) { if (p2p_channels_includes(&p2p->channels, - msg.operating_channel[3], - msg.operating_channel[4]) && + msg->operating_channel[3], + msg->operating_channel[4]) && p2p_channels_includes(&dev->channels, - msg.operating_channel[3], - msg.operating_channel[4])) { + msg->operating_channel[3], + msg->operating_channel[4])) { dev->oper_freq = p2p_channel_to_freq( - msg.operating_channel[3], - msg.operating_channel[4]); + msg->operating_channel[3], + msg->operating_channel[4]); } else { p2p_dbg(p2p, "P2PS PD Response - invalid operating channel"); @@ -1529,11 +1527,11 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, p2p->cfg->cb_ctx, status, sa, adv_mac, p2p->p2ps_prov->session_mac, group_mac, adv_id, p2p->p2ps_prov->session_id, - conncap, passwd_id, msg.persistent_ssid, - msg.persistent_ssid_len, 1, 0, NULL, - msg.feature_cap, msg.feature_cap_len, freq, - msg.group_id ? msg.group_id + ETH_ALEN : NULL, - msg.group_id ? msg.group_id_len - ETH_ALEN : 0); + conncap, passwd_id, msg->persistent_ssid, + msg->persistent_ssid_len, 1, 0, NULL, + msg->feature_cap, msg->feature_cap_len, freq, + msg->group_id ? msg->group_id + ETH_ALEN : NULL, + msg->group_id ? msg->group_id_len - ETH_ALEN : 0); } p2ps_prov_free(p2p); } else if (status != P2P_SC_SUCCESS && @@ -1555,16 +1553,15 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, NULL, NULL, 0); } - if (msg.session_info && msg.session_info_len) { - size_t info_len = msg.session_info_len; + if (msg->session_info && msg->session_info_len) { + size_t info_len = msg->session_info_len; char *deferred_sess_resp = os_malloc(2 * info_len + 1); if (!deferred_sess_resp) { - p2p_parse_free(&msg); p2ps_prov_free(p2p); goto out; } - utf8_escape((char *) msg.session_info, info_len, + utf8_escape((char *) msg->session_info, info_len, deferred_sess_resp, 2 * info_len + 1); if (p2p->cfg->prov_disc_fail) @@ -1586,17 +1583,14 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, P2P_PROV_DISC_REJECTED, adv_id, adv_mac, NULL); - p2p_parse_free(&msg); p2ps_prov_free(p2p); goto out; } /* Store the provisioning info */ - dev->wps_prov_info = msg.wps_config_methods; - if (msg.intended_addr) - os_memcpy(dev->interface_addr, msg.intended_addr, ETH_ALEN); - - p2p_parse_free(&msg); + dev->wps_prov_info = msg->wps_config_methods; + if (msg->intended_addr) + os_memcpy(dev->interface_addr, msg->intended_addr, ETH_ALEN); out: dev->req_config_methods = 0; @@ -1640,6 +1634,19 @@ out: } +void p2p_handle_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len) +{ + struct p2p_message msg; + + if (p2p_parse(data, len, &msg)) + return; + + p2p_process_prov_disc_resp(p2p, &msg, sa, data + 1, len - 1); + p2p_parse_free(&msg); +} + + int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, int join, int force_freq) {