1 /*
2  * Copyright (C) 2024 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 <net/if.h>
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <sys/ioctl.h>
20 #include <sys/socket.h>
21 #include <unistd.h>
22 #include <hdf_log.h>
23 #include "securec.h"
24 #include "wpa_hdi_util.h"
25 
26 #define MAC_UINT_SIZE 6
27 #define MAC_STRING_SIZE 17
28 
ConvertMacToStr(const unsigned char * mac,int macSize,char * macStr,int strLen)29 int ConvertMacToStr(const unsigned char *mac, int macSize, char *macStr, int strLen)
30 {
31     if (mac == NULL || macStr == NULL || macSize != MAC_UINT_SIZE || strLen <= MAC_STRING_SIZE) {
32         return -1;
33     }
34     const int posZero = 0;
35     const int posOne = 1;
36     const int posTwo = 2;
37     const int posThree = 3;
38     const int posFour = 4;
39     const int posFive = 5;
40     if (snprintf_s(macStr, strLen, strLen - 1, "%02x:%02x:%02x:%02x:%02x:%02x", mac[posZero], mac[posOne], mac[posTwo],
41         mac[posThree], mac[posFour], mac[posFive]) < 0) {
42         return -1;
43     }
44     return 0;
45 }
46 
IsValidHexCharAndConvert(char c)47 char IsValidHexCharAndConvert(char c)
48 {
49     if (c >= '0' && c <= '9') {
50         return c - '0';
51     }
52     if (c >= 'a' && c <= 'f') {
53         return c - 'a' + ('9' - '0' + 1);
54     }
55     if (c >= 'A' && c <= 'F') {
56         return c - 'A' + ('9' - '0' + 1);
57     }
58     return -1;
59 }
60 
ConvertMacToArray(const char * macStr,unsigned char * mac,int macSize)61 int ConvertMacToArray(const char *macStr, unsigned char *mac, int macSize)
62 {
63     if (macStr == NULL || mac == NULL || macSize != MAC_UINT_SIZE || strlen(macStr) != MAC_STRING_SIZE) {
64         return -1;
65     }
66     const int shiftNum = 4;
67     const int macSpaceNum = 3;
68     unsigned char tmp = 0;
69     for (int i = 0, j = 0; i < MAC_STRING_SIZE; ++i) {
70         if (j == 0 || j == 1) {
71             int8_t v = IsValidHexCharAndConvert(macStr[i]);
72             if (v < 0) {
73                 return -1;
74             }
75             tmp <<= shiftNum;
76             tmp |= v;
77             ++j;
78         } else {
79             if (macStr[i] != ':') {
80                 return -1;
81             }
82             mac[i / macSpaceNum] = tmp;
83             j = 0;
84             tmp = 0;
85         }
86     }
87     mac[MAC_STRING_SIZE / macSpaceNum] = tmp;
88     return 0;
89 }
90 
CheckMacIsValid(const char * macStr)91 int CheckMacIsValid(const char *macStr)
92 {
93     if (macStr == NULL || strlen(macStr) != MAC_STRING_SIZE) {
94         return -1;
95     }
96     for (int i = 0, j = 0; i < MAC_STRING_SIZE; ++i) {
97         if (j == 0 || j == 1) {
98             int v = IsValidHexCharAndConvert(macStr[i]);
99             if (v < 0) {
100                 return -1;
101             }
102             ++j;
103         } else {
104             if (macStr[i] != ':') {
105                 return -1;
106             }
107             j = 0;
108         }
109     }
110     return 0;
111 }
112 
GetIfaceState(const char * ifaceName)113 int GetIfaceState(const char *ifaceName)
114 {
115     int state = 0;
116     int sock = socket(AF_INET, SOCK_DGRAM, 0);
117     if (sock < 0) {
118         HDF_LOGE("GetIfaceState: create socket fail");
119         return state;
120     }
121 
122     struct ifreq ifr;
123     (void)memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr));
124     if (strcpy_s(ifr.ifr_name, IFNAMSIZ, ifaceName) != EOK) {
125         HDF_LOGE("GetIfaceState: strcpy_s fail");
126         close(sock);
127         return state;
128     }
129     if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
130         HDF_LOGE("GetIfaceState: can not get interface state: %{public}s", ifaceName);
131         close(sock);
132         return state;
133     }
134     state = ((ifr.ifr_flags & IFF_UP) > 0 ? 1 : 0);
135     HDF_LOGD("GetIfaceState: current interface state: %{public}d", state);
136     close(sock);
137     return state;
138 }
139 
CharReplace(char * data,int start,int end,const char hiddenChar)140 static int CharReplace(char* data, int start, int end, const char hiddenChar)
141 {
142     if (!data) {
143         HDF_LOGE("CharReplace: data invalid.");
144         return 1;
145     }
146     for (int i = start; i < end; i++) {
147         data[i] = hiddenChar;
148     }
149 
150     return 0;
151 }
152 
DataAnonymize(const char * input,int inputLen,char * output,int outputSize)153 int DataAnonymize(const char *input, int inputLen, char* output, int outputSize)
154 {
155     if (!input || !output || inputLen > outputSize) {
156         HDF_LOGE("DataAnonymize: arg invalid.");
157         return 1;
158     }
159 
160     if (memcpy_s(output, outputSize, input, inputLen) != EOK) {
161         HDF_LOGE("DataAnonymize: memcpy_s fail");
162         return 1;
163     }
164 
165     const char hiddenChar = '*';
166     const int minHiddenSize = 3;
167     const int headKeepSize = 3;
168     const int tailKeepSize = 3;
169 
170     if (inputLen < minHiddenSize) {
171         return CharReplace(output, 0, inputLen, hiddenChar);
172     }
173 
174     if (inputLen < (minHiddenSize + headKeepSize + tailKeepSize)) {
175         int beginIndex = 1;
176         int hiddenSize = inputLen - minHiddenSize + 1;
177         hiddenSize = hiddenSize > minHiddenSize ? minHiddenSize : hiddenSize;
178         return CharReplace(output, beginIndex,  beginIndex + hiddenSize, hiddenChar);
179     }
180     return CharReplace(output, headKeepSize, inputLen - tailKeepSize, hiddenChar);
181 }
182