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 
16 #include "lnn_connection_addr_utils.h"
17 
18 #include <securec.h>
19 #include <string.h>
20 
21 #include "anonymizer.h"
22 #include "lnn_log.h"
23 #include "softbus_def.h"
24 
25 #define LNN_MAX_PRINT_ADDR_LEN 100
26 #define SHORT_UDID_HASH_LEN    8
27 
28 static __thread char g_printAddr[LNN_MAX_PRINT_ADDR_LEN] = { 0 };
29 
LnnIsSameConnectionAddr(const ConnectionAddr * addr1,const ConnectionAddr * addr2,bool isShort)30 bool LnnIsSameConnectionAddr(const ConnectionAddr *addr1, const ConnectionAddr *addr2, bool isShort)
31 {
32     if (addr1 == NULL || addr2 == NULL) {
33         LNN_LOGD(LNN_STATE, "addr1 or addr2 is null");
34         return false;
35     }
36     if (addr1->type != addr2->type) {
37         LNN_LOGD(LNN_STATE, "addr1 type not equal addr2 type");
38         return false;
39     }
40     if (addr1->type == CONNECTION_ADDR_BR) {
41         return strncmp(addr1->info.br.brMac, addr2->info.br.brMac, BT_MAC_LEN) == 0;
42     }
43     if (addr1->type == CONNECTION_ADDR_BLE) {
44         if (isShort) {
45             return memcmp(addr1->info.ble.udidHash, addr2->info.ble.udidHash, SHORT_UDID_HASH_LEN) == 0 ||
46                 strncmp(addr1->info.ble.bleMac, addr2->info.ble.bleMac, BT_MAC_LEN) == 0;
47         } else {
48             return memcmp(addr1->info.ble.udidHash, addr2->info.ble.udidHash, UDID_HASH_LEN) == 0 ||
49                 strncmp(addr1->info.ble.bleMac, addr2->info.ble.bleMac, BT_MAC_LEN) == 0;
50         }
51     }
52     if (addr1->type == CONNECTION_ADDR_WLAN || addr1->type == CONNECTION_ADDR_ETH) {
53         return (strncmp(addr1->info.ip.ip, addr2->info.ip.ip, IP_STR_MAX_LEN) == 0) &&
54         (addr1->info.ip.port == addr2->info.ip.port);
55     }
56     if (addr1->type == CONNECTION_ADDR_SESSION) {
57         return ((addr1->info.session.sessionId == addr2->info.session.sessionId) &&
58             (addr1->info.session.channelId == addr2->info.session.channelId) &&
59             (addr1->info.session.type == addr2->info.session.type));
60     }
61     return false;
62 }
63 
LnnConvertAddrToOption(const ConnectionAddr * addr,ConnectOption * option)64 bool LnnConvertAddrToOption(const ConnectionAddr *addr, ConnectOption *option)
65 {
66     if (addr == NULL || option == NULL) {
67         LNN_LOGW(LNN_STATE, "addr or option is null");
68         return false;
69     }
70     if (addr->type == CONNECTION_ADDR_BR) {
71         option->type = CONNECT_BR;
72         if (strncpy_s(option->brOption.brMac, BT_MAC_LEN, addr->info.br.brMac,
73             strlen(addr->info.br.brMac)) != EOK) {
74             LNN_LOGE(LNN_STATE, "copy br mac to addr fail");
75             return false;
76         }
77         return true;
78     }
79     if (addr->type == CONNECTION_ADDR_BLE) {
80         option->type = CONNECT_BLE;
81         if (strncpy_s(option->bleOption.bleMac, BT_MAC_LEN, addr->info.ble.bleMac,
82             strlen(addr->info.ble.bleMac)) != EOK) {
83             LNN_LOGE(LNN_STATE, "copy ble mac to addr fail");
84             return false;
85         }
86         if (memcpy_s((int8_t *)option->bleOption.deviceIdHash, UDID_HASH_LEN, addr->info.ble.udidHash,
87             UDID_HASH_LEN) != EOK) {
88             LNN_LOGE(LNN_STATE, "copy ble deviceIdHash to addr fail");
89             return false;
90         }
91         return true;
92     }
93     if (addr->type == CONNECTION_ADDR_ETH || addr->type == CONNECTION_ADDR_WLAN) {
94         option->type = CONNECT_TCP;
95         if (strncpy_s(option->socketOption.addr, sizeof(option->socketOption.addr), addr->info.ip.ip,
96             strlen(addr->info.ip.ip)) != EOK) {
97             LNN_LOGE(LNN_STATE, "copy ip to addr fail");
98             return false;
99         }
100         option->socketOption.port = addr->info.ip.port;
101         option->socketOption.protocol = LNN_PROTOCOL_IP;
102         option->socketOption.moduleId = AUTH;
103         return true;
104     }
105     LNN_LOGE(LNN_STATE, "not supported type=%{public}d", addr->type);
106     return false;
107 }
108 
LnnConvertOptionToAddr(ConnectionAddr * addr,const ConnectOption * option,ConnectionAddrType hintType)109 bool LnnConvertOptionToAddr(ConnectionAddr *addr, const ConnectOption *option,
110     ConnectionAddrType hintType)
111 {
112     if (addr == NULL || option == NULL) {
113         LNN_LOGW(LNN_STATE, "addr or option is null");
114         return false;
115     }
116     if (option->type == CONNECT_BR) {
117         addr->type = CONNECTION_ADDR_BR;
118         if (strncpy_s(addr->info.br.brMac, BT_MAC_LEN, option->brOption.brMac,
119             strlen(option->brOption.brMac)) != EOK) {
120             LNN_LOGE(LNN_STATE, "copy br mac to addr fail");
121             return false;
122         }
123         return true;
124     }
125     if (option->type == CONNECT_BLE) {
126         addr->type = CONNECTION_ADDR_BLE;
127         if (strncpy_s(addr->info.ble.bleMac, BT_MAC_LEN, option->bleOption.bleMac,
128             strlen(option->bleOption.bleMac)) != EOK) {
129             LNN_LOGE(LNN_STATE, "copy ble mac to addr fail");
130             return false;
131         }
132         if (memcpy_s(addr->info.ble.udidHash, UDID_HASH_LEN, (int8_t *)option->bleOption.deviceIdHash,
133             UDID_HASH_LEN) != EOK) {
134             LNN_LOGE(LNN_STATE, "copy ble deviceIdHash to udidHash fail");
135             return false;
136         }
137         return true;
138     }
139     if (option->type == CONNECT_TCP) {
140         if (option->socketOption.protocol != LNN_PROTOCOL_IP) {
141             LNN_LOGE(LNN_STATE, "only ip is supportted");
142             return false;
143         }
144         addr->type = hintType;
145         if (strncpy_s(addr->info.ip.ip, IP_LEN, option->socketOption.addr,
146             strlen(option->socketOption.addr)) != EOK) {
147             LNN_LOGE(LNN_STATE, "copy ip to addr fail");
148             return false;
149         }
150         addr->info.ip.port = (uint16_t)option->socketOption.port;
151         return true;
152     }
153     LNN_LOGE(LNN_STATE, "not supported type=%{public}d", option->type);
154     return false;
155 }
156 
LnnConvAddrTypeToDiscType(ConnectionAddrType type)157 DiscoveryType LnnConvAddrTypeToDiscType(ConnectionAddrType type)
158 {
159     if (type == CONNECTION_ADDR_WLAN || type == CONNECTION_ADDR_ETH) {
160         return DISCOVERY_TYPE_WIFI;
161     } else if (type == CONNECTION_ADDR_BR) {
162         return DISCOVERY_TYPE_BR;
163     } else if (type == CONNECTION_ADDR_BLE) {
164         return DISCOVERY_TYPE_BLE;
165     } else if (type == CONNECTION_ADDR_SESSION) {
166         return DISCOVERY_TYPE_BLE;
167     } else {
168         return DISCOVERY_TYPE_COUNT;
169     }
170 }
171 
LnnDiscTypeToConnAddrType(DiscoveryType type)172 ConnectionAddrType LnnDiscTypeToConnAddrType(DiscoveryType type)
173 {
174     switch (type) {
175         case DISCOVERY_TYPE_WIFI:
176             return CONNECTION_ADDR_WLAN;
177         case DISCOVERY_TYPE_BLE:
178             return CONNECTION_ADDR_BLE;
179         case DISCOVERY_TYPE_BR:
180             return CONNECTION_ADDR_BR;
181         default:
182             break;
183     }
184     return CONNECTION_ADDR_MAX;
185 }
186 
LnnConvertAddrToAuthConnInfo(const ConnectionAddr * addr,AuthConnInfo * connInfo)187 bool LnnConvertAddrToAuthConnInfo(const ConnectionAddr *addr, AuthConnInfo *connInfo)
188 {
189     if (addr == NULL || connInfo == NULL) {
190         LNN_LOGW(LNN_STATE, "addr or connInfo is null");
191         return false;
192     }
193     if (addr->type == CONNECTION_ADDR_BR) {
194         connInfo->type = AUTH_LINK_TYPE_BR;
195         if (strcpy_s(connInfo->info.brInfo.brMac, BT_MAC_LEN, addr->info.br.brMac) != EOK) {
196             LNN_LOGE(LNN_STATE, "copy br mac to connInfo fail");
197             return false;
198         }
199         return true;
200     }
201     if (addr->type == CONNECTION_ADDR_BLE) {
202         connInfo->type = AUTH_LINK_TYPE_BLE;
203         if (strcpy_s(connInfo->info.bleInfo.bleMac, BT_MAC_LEN, addr->info.ble.bleMac) != EOK ||
204             memcpy_s(connInfo->info.bleInfo.deviceIdHash, UDID_HASH_LEN, addr->info.ble.udidHash,
205                 UDID_HASH_LEN) != EOK) {
206             LNN_LOGE(LNN_STATE, "copy ble mac to connInfo fail");
207             return false;
208         }
209         connInfo->info.bleInfo.protocol = addr->info.ble.protocol;
210         connInfo->info.bleInfo.psm = addr->info.ble.psm;
211         return true;
212     }
213     if (addr->type == CONNECTION_ADDR_ETH || addr->type == CONNECTION_ADDR_WLAN) {
214         connInfo->type = AUTH_LINK_TYPE_WIFI;
215         if (strcpy_s(connInfo->info.ipInfo.ip, IP_LEN, addr->info.ip.ip) != EOK ||
216             memcpy_s(connInfo->info.ipInfo.deviceIdHash, UDID_HASH_LEN, addr->info.ip.udidHash, UDID_HASH_LEN) != EOK) {
217             LNN_LOGE(LNN_STATE, "copy ip to connInfo fail");
218             return false;
219         }
220         connInfo->info.ipInfo.port = addr->info.ip.port;
221         return true;
222     }
223     LNN_LOGE(LNN_STATE, "not supported type=%{public}d", addr->type);
224     return false;
225 }
226 
LnnConvertAuthConnInfoToAddr(ConnectionAddr * addr,const AuthConnInfo * connInfo,ConnectionAddrType hintType)227 bool LnnConvertAuthConnInfoToAddr(ConnectionAddr *addr, const AuthConnInfo *connInfo,
228     ConnectionAddrType hintType)
229 {
230     if (addr == NULL || connInfo == NULL) {
231         LNN_LOGW(LNN_STATE, "addr or connInfo is null");
232         return false;
233     }
234     if (connInfo->type == AUTH_LINK_TYPE_BR) {
235         addr->type = CONNECTION_ADDR_BR;
236         if (strcpy_s(addr->info.br.brMac, BT_MAC_LEN, connInfo->info.brInfo.brMac) != EOK) {
237             LNN_LOGE(LNN_STATE, "copy br mac to addr fail");
238             return false;
239         }
240         return true;
241     }
242     if (connInfo->type == AUTH_LINK_TYPE_BLE) {
243         addr->type = CONNECTION_ADDR_BLE;
244         if (strcpy_s(addr->info.ble.bleMac, BT_MAC_LEN, connInfo->info.bleInfo.bleMac) != EOK) {
245             LNN_LOGE(LNN_STATE, "copy ble mac to addr fail");
246             return false;
247         }
248         addr->info.ble.protocol = connInfo->info.bleInfo.protocol;
249         addr->info.ble.psm = connInfo->info.bleInfo.psm;
250         return true;
251     }
252     if (connInfo->type == AUTH_LINK_TYPE_WIFI) {
253         addr->type = hintType;
254         if (strcpy_s(addr->info.ip.ip, IP_LEN, connInfo->info.ipInfo.ip) != EOK) {
255             LNN_LOGE(LNN_STATE, "copy ip to addr fail");
256             return false;
257         }
258         addr->info.ip.port = (uint16_t)connInfo->info.ipInfo.port;
259         return true;
260     }
261     LNN_LOGE(LNN_STATE, "not supported type=%{public}d", connInfo->type);
262     return false;
263 }
264 
LnnIsConnectionAddrInvalid(const ConnectionAddr * addr)265 bool LnnIsConnectionAddrInvalid(const ConnectionAddr *addr)
266 {
267     if (addr == NULL) {
268         LNN_LOGE(LNN_STATE, "connection addr get invalid param");
269         return true;
270     }
271     switch (addr->type) {
272         case CONNECTION_ADDR_WLAN:
273         /* fall-through */
274         case CONNECTION_ADDR_ETH:
275             if (strnlen(addr->info.ip.ip, IP_STR_MAX_LEN) == 0 ||
276                 strnlen(addr->info.ip.ip, IP_STR_MAX_LEN) == IP_STR_MAX_LEN) {
277                 LNN_LOGE(LNN_STATE, "get invalid ip info");
278                 return true;
279             }
280             break;
281         case CONNECTION_ADDR_BR:
282             if (strnlen(addr->info.br.brMac, BT_MAC_LEN) == 0 ||
283                 strnlen(addr->info.br.brMac, BT_MAC_LEN) == BT_MAC_LEN) {
284                 LNN_LOGE(LNN_STATE, "get invalid brMac info");
285                 return true;
286             }
287             break;
288         case CONNECTION_ADDR_BLE:
289             if (strnlen(addr->info.ble.bleMac, BT_MAC_LEN) == 0 ||
290                 strnlen(addr->info.ble.bleMac, BT_MAC_LEN) == BT_MAC_LEN) {
291                 LNN_LOGE(LNN_STATE, "get invalid bleMac info");
292                 return true;
293             }
294             break;
295         case CONNECTION_ADDR_SESSION:
296             break;
297         default:
298             LNN_LOGW(LNN_STATE, "invalid connection addr type");
299             return true;
300     }
301     return false;
302 }
303 
LnnPrintConnectionAddr(const ConnectionAddr * addr)304 const char *LnnPrintConnectionAddr(const ConnectionAddr *addr)
305 {
306     int32_t ret = 0;
307     char *anonyIp = NULL;
308     char *anonyMac = NULL;
309 
310     if (LnnIsConnectionAddrInvalid(addr)) {
311         LNN_LOGW(LNN_STATE, "print connection addr get invalid param");
312         return "Addr=";
313     }
314     switch (addr->type) {
315         case CONNECTION_ADDR_WLAN:
316         /* fall-through */
317         case CONNECTION_ADDR_ETH:
318             Anonymize(addr->info.ip.ip, &anonyIp);
319             ret = sprintf_s(g_printAddr, sizeof(g_printAddr),
320                 "Ip=%s", anonyIp);
321             AnonymizeFree(anonyIp);
322             break;
323         case CONNECTION_ADDR_BR:
324             Anonymize(addr->info.br.brMac, &anonyMac);
325             ret = sprintf_s(g_printAddr, sizeof(g_printAddr),
326                 "BrMac=%s", anonyMac);
327             AnonymizeFree(anonyMac);
328             break;
329         case CONNECTION_ADDR_BLE:
330             Anonymize(addr->info.ble.bleMac, &anonyMac);
331             ret = sprintf_s(g_printAddr, sizeof(g_printAddr),
332                 "BleMac=%s", anonyMac);
333             AnonymizeFree(anonyMac);
334             break;
335         default:
336             LNN_LOGW(LNN_STATE, "print invalid connection addr type");
337             return "Addr=";
338     }
339     if (ret < 0) {
340         LNN_LOGE(LNN_STATE, "sprintf_s connection addr failed");
341         return "Addr=";
342     }
343     return g_printAddr;
344 }