• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "wifi_p2p_dns_sd_service_response.h"
16 #include <climits>
17 #include "wifi_p2p_dns_sd_service_info.h"
18 
19 namespace OHOS {
20 namespace Wifi {
WifiP2pDnsSdServiceResponse(P2pServiceStatus status,int tranId,const std::vector<unsigned char> & data)21 WifiP2pDnsSdServiceResponse::WifiP2pDnsSdServiceResponse(
22     P2pServiceStatus status, int tranId, const std::vector<unsigned char> &data)
23     : WifiP2pServiceResponse(P2pServicerProtocolType::SERVICE_TYPE_BONJOUR, status, tranId, data),
24       dnsQueryName(), instanceName(), dnsType(-1), version(-1), txtRecord(), sVmpack()
25 {
26     Init();
27 };
28 
WifiP2pDnsSdServiceResponse(const WifiP2pServiceResponse & resp)29 WifiP2pDnsSdServiceResponse::WifiP2pDnsSdServiceResponse(const WifiP2pServiceResponse &resp)
30     : WifiP2pServiceResponse(resp),
31       dnsQueryName(), instanceName(), dnsType(-1), version(-1), txtRecord(), sVmpack()
32 {
33     Init();
34 };
35 
Init()36 void WifiP2pDnsSdServiceResponse::Init()
37 {
38     sVmpack.insert(std::make_pair(0x0c, "_tcp.local."));
39     sVmpack.insert(std::make_pair(0x11, "local."));
40     sVmpack.insert(std::make_pair(0x1c, "_udp.local."));
41 }
42 
FetchTxtData(std::istringstream & istream)43 bool WifiP2pDnsSdServiceResponse::FetchTxtData(std::istringstream &istream)
44 {
45     unsigned char t = static_cast<unsigned char>(istream.get());
46     while (!istream.eof()) {
47         if (t == 0) {
48             break;
49         }
50         if (t > (istream.str().size() - static_cast<unsigned char>(istream.tellg()))) {
51             return false;
52         }
53         std::unique_ptr<char[]> ptr = std::make_unique<char[]>(t + 1);
54         istream.read(ptr.get(), t);
55         ptr[t] = '\0';
56         std::istringstream iss(ptr.get());
57         std::string keyVal[2];
58         getline(iss, keyVal[0], '=');
59         getline(iss, keyVal[1], '=');
60         txtRecord.insert(std::make_pair(keyVal[0], keyVal[1]));
61         t = istream.get();
62     }
63     return true;
64 }
65 
FetchDnsName(std::istringstream & istream,std::string & dnsName)66 bool WifiP2pDnsSdServiceResponse::FetchDnsName(std::istringstream &istream, std::string &dnsName)
67 {
68     if (!dnsQueryName.empty()) {
69         sVmpack.insert(std::make_pair(0x27, dnsQueryName));
70     }
71     dnsName = "";
72 
73     unsigned char t = static_cast<unsigned char>(istream.get());
74     while (!istream.eof()) {
75         if (t == 0x00) {
76             return true;
77         } else if (t == 0xc0) {
78             t = istream.get();
79             auto it = sVmpack.find(t);
80             if (it == sVmpack.end()) {
81                 return false;
82             }
83             dnsName.append(it->second);
84             return true;
85         } else {
86             if (t > (istream.str().size() - static_cast<unsigned char>(istream.tellg()))) {
87                 return false;
88             }
89             std::unique_ptr<char[]> ptr = std::make_unique<char[]>(t);
90             istream.read(ptr.get(), t);
91             dnsName.append(ptr.get(), 0, t);
92             dnsName.append(".");
93         }
94         t = istream.get();
95     }
96     return false;
97 }
98 
ParseData()99 bool WifiP2pDnsSdServiceResponse::ParseData()
100 {
101     std::vector<unsigned char> data = GetData();
102     if (data.empty()) {
103         return true; /* empty is ok */
104     }
105     std::string strData;
106     strData.insert(strData.begin(), data.begin(), data.end());
107     std::istringstream istream(strData);
108     std::string dnsName;
109     if (!FetchDnsName(istream, dnsName) || dnsName.empty()) {
110         return false;
111     }
112     dnsQueryName = dnsName;
113 
114     const int typeAndVersionSize = 3;
115     if ((static_cast<int>(istream.str().size()) - istream.tellg()) <= typeAndVersionSize) {
116         return false;
117     }
118     dnsType = static_cast<int>(static_cast<size_t>(istream.get()) << CHAR_BIT); /* 2 Byte of high bit */
119     dnsType = istream.get();
120     version = istream.get(); /* 1 Byte */
121 
122     if (dnsType == WifiP2pDnsSdServiceInfo::DNS_PTR_TYPE) {
123         std::string rData;
124         if (!FetchDnsName(istream, rData) || rData.empty()) {
125             return false;
126         }
127         if (rData.length() <= dnsQueryName.length()) {
128             return false;
129         }
130         instanceName.insert(instanceName.begin(), rData.begin(), rData.end() - dnsQueryName.length() - 1);
131     } else if (dnsType == WifiP2pDnsSdServiceInfo::DNS_TXT_TYPE) {
132         if (!FetchTxtData(istream)) {
133             return false;
134         }
135     } else {
136         return false;
137     }
138     if (!istream.eof() && istream.get() == ';') {
139         std::string svrName("");
140         unsigned char svrNameLength = static_cast<unsigned char>(istream.get());
141         std::unique_ptr<char[]> ptr = std::make_unique<char[]>(svrNameLength);
142         istream.read(ptr.get(), svrNameLength);
143         svrName.append(ptr.get(), 0, svrNameLength);
144         mSvrName = svrName;
145     }
146     return true;
147 }
148 
GetQueryName() const149 const std::string &WifiP2pDnsSdServiceResponse::GetQueryName() const
150 {
151     return dnsQueryName;
152 }
153 
GetInstanceName() const154 const std::string &WifiP2pDnsSdServiceResponse::GetInstanceName() const
155 {
156     return instanceName;
157 }
158 
GetDnsType() const159 int WifiP2pDnsSdServiceResponse::GetDnsType() const
160 {
161     return dnsType;
162 }
163 
GetVersion() const164 int WifiP2pDnsSdServiceResponse::GetVersion() const
165 {
166     return version;
167 }
168 
GetTxtRecord() const169 const std::map<std::string, std::string> &WifiP2pDnsSdServiceResponse::GetTxtRecord() const
170 {
171     return txtRecord;
172 }
173 }  // namespace Wifi
174 }  // namespace OHOS
175