1 /*
2  * Copyright (C) 2022 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 "fillp_mgt_msg_log.h"
17 #include "net.h"
18 #include "nstackx_util.h"
19 
20 #ifdef FILLP_MGT_MSG_LOG
21 
22 #define FILLP_EXT_PARA_FORMAT_BUF_LEN 512
23 #define FILLP_IP_ADDR_FORMAT_BUF_LEN 64
24 
25 #define FILLP_COOKIE_TAG_AND_LEN_SIZE (sizeof(FILLP_UINT16) + sizeof(FILLP_UINT16))
26 
27 #define FILLP_DIRECTION_STR(_d) (((_d) == FILLP_DIRECTION_RX) ? "recv" : "send")
28 
29 #define FILLP_MGT_MSG_PRINT(_sockIndex, _hdr, _direction, fmt, ...) do { \
30         FILLP_LOGMGTMSG("sock %d %s management message, version: %u, msg type: %s(0x%X)," \
31             " msg flag: reserved(0x%02X), msg length: %u, seq num: %u, pkt seq: %u. " fmt, \
32             _sockIndex, FILLP_DIRECTION_STR(_direction), FILLP_PKT_GET_PROTCOL_VERSION((_hdr)->flag), \
33             g_fillpTypeStr[FILLP_PKT_GET_TYPE((_hdr)->flag)], FILLP_PKT_GET_TYPE((_hdr)->flag), \
34             FILLP_PKT_GET_FLAG((_hdr)->flag), (_hdr)->dataLen, (_hdr)->seqNum, (_hdr)->pktNum, ##__VA_ARGS__); \
35     } while (0)
36 
37 static FILLP_CONST FILLP_CHAR *g_fillpTypeStr[] = {
38     "RESERVED",
39     "DATA",
40     "CONN_REQ",
41     "NACK",
42     "RESERVED",
43     "PACK",
44     "FIN",
45     "RESERVED",
46     "RESERVED",
47     "RESERVED",
48     "CONN_REQ_ACK",
49     "CONN_CONFIRM",
50     "CONN_CONFIRM_ACK",
51     "HISTORY_ACK",
52     "CTRL_MSG",
53 };
54 
FillpHeaderNtoH(struct FillpPktHead * out,FILLP_CONST struct FillpPktHead * in,FILLP_INT direction)55 static void FillpHeaderNtoH(struct FillpPktHead *out, FILLP_CONST struct FillpPktHead *in, FILLP_INT direction)
56 {
57     if (direction == FILLP_DIRECTION_RX) { /* already convert to host byte order in FillpDoInput */
58         (void)memcpy_s(out, sizeof(struct FillpPktHead), in, sizeof(struct FillpPktHead));
59     } else {
60         out->flag = FILLP_NTOHS(in->flag);
61         out->dataLen = FILLP_NTOHS(in->dataLen);
62         out->pktNum = FILLP_NTOHL(in->pktNum);
63         out->seqNum = FILLP_NTOHL(in->seqNum);
64     }
65 }
66 
FillpPktSimpleLog(FILLP_INT sockIndex,FILLP_CONST struct FillpPktHead * hdrInput,FILLP_INT direction)67 void FillpPktSimpleLog(FILLP_INT sockIndex, FILLP_CONST struct FillpPktHead *hdrInput, FILLP_INT direction)
68 {
69     struct FillpPktHead hdr = {0};
70     FillpHeaderNtoH(&hdr, hdrInput, direction);
71     FILLP_UINT16 type = FILLP_PKT_GET_TYPE(hdr.flag);
72     if (type == FILLP_PKT_TYPE_CONN_REQ || type == FILLP_PKT_TYPE_CONN_REQ_ACK ||
73         type == FILLP_PKT_TYPE_CONN_CONFIRM || type == FILLP_PKT_TYPE_CONN_CONFIRM_ACK ||
74         type == FILLP_PKT_TYPE_FIN) {
75         FILLP_MGT_MSG_PRINT(sockIndex, &hdr, direction, "");
76     }
77 }
78 
FillpConnReqLog(FILLP_INT sockIndex,FILLP_CONST struct FillpPktConnReq * req,FILLP_INT direction)79 void FillpConnReqLog(FILLP_INT sockIndex, FILLP_CONST struct FillpPktConnReq *req, FILLP_INT direction)
80 {
81     struct FillpPktHead hdr = {0};
82     FillpHeaderNtoH(&hdr, (FILLP_CONST struct FillpPktHead *)req->head, direction);
83     FILLP_MGT_MSG_PRINT(sockIndex, &hdr, direction,
84         "cookie preserve time: %u, send cache: %u, recv cache: %u, timestamp: %llu",
85         FILLP_NTOHL(req->cookiePreserveTime), FILLP_NTOHL(req->sendCache), FILLP_NTOHL(req->recvCache),
86         FILLP_NTOHLL(req->timestamp));
87 }
88 
FillpExtParaRttFormat(FILLP_CONST struct FtNetconn * conn,FILLP_CHAR * buf,size_t len)89 static FILLP_INT FillpExtParaRttFormat(FILLP_CONST struct FtNetconn *conn, FILLP_CHAR *buf, size_t len)
90 {
91     return snprintf_s(buf, len, len - 1, "    init rtt: %llu", conn->calcRttDuringConnect);
92 }
93 
FillpExtParaPktSizeFormat(FILLP_CONST struct FtNetconn * conn,FILLP_CHAR * buf,size_t len)94 static FILLP_INT FillpExtParaPktSizeFormat(FILLP_CONST struct FtNetconn *conn, FILLP_CHAR *buf, size_t len)
95 {
96     return snprintf_s(buf, len, len - 1, "    peer pkt size: %u", conn->peerPktSize);
97 }
98 
FillpBitmapFormat(FILLP_CHAR * buf,size_t len,FILLP_UINT32 bitmap,FILLP_CONST FILLP_CHAR * bitmapStr[],size_t bitmapStrSize)99 static FILLP_INT FillpBitmapFormat(FILLP_CHAR *buf, size_t len, FILLP_UINT32 bitmap,
100     FILLP_CONST FILLP_CHAR *bitmapStr[], size_t bitmapStrSize)
101 {
102     size_t formatLen = 0;
103     size_t i;
104     for (i = 0; i < bitmapStrSize; i++) {
105         if (!UTILS_FLAGS_CHECK(bitmap, 1u << i)) {
106             continue;
107         }
108 
109         FILLP_INT ret = snprintf_s(buf + formatLen, len - formatLen, (len - formatLen) - 1, " %s", bitmapStr[i]);
110         if (ret < 0) {
111             FILLP_LOGERR("snprintf_s failed");
112             return ret;
113         }
114         formatLen += (FILLP_UINT32)ret;
115     }
116 
117     return (FILLP_INT)formatLen;
118 }
119 
FillpExtParaCharacterFormat(FILLP_CONST struct FtNetconn * conn,FILLP_CHAR * buf,size_t len)120 static FILLP_INT FillpExtParaCharacterFormat(FILLP_CONST struct FtNetconn *conn, FILLP_CHAR *buf, size_t len)
121 {
122     FILLP_INT ret = snprintf_s(buf, len, len - 1, "    characters: 0x%08X", conn->peerCharacters);
123     if (ret < 0) {
124         FILLP_LOGERR("snprintf_s failed");
125         return ret;
126     }
127     size_t formatLen = (FILLP_UINT32)ret;
128 
129     FILLP_CONST FILLP_CHAR *characterStr[] = { "HRBB", "PKT_IVAR" };
130     ret = FillpBitmapFormat(buf + formatLen, len - formatLen, conn->peerCharacters,
131         characterStr, UTILS_ARRAY_LEN(characterStr));
132     if (ret < 0) {
133         FILLP_LOGERR("FillpBitmapFormat failed");
134         return ret;
135     }
136     formatLen += (FILLP_UINT32)ret;
137 
138     return (FILLP_INT)formatLen;
139 }
140 
FillpExtParaFcAlgFormat(FILLP_CONST struct FtNetconn * conn,FILLP_CHAR * buf,size_t len)141 static FILLP_INT FillpExtParaFcAlgFormat(FILLP_CONST struct FtNetconn *conn, FILLP_CHAR *buf, size_t len)
142 {
143     FILLP_INT ret = snprintf_s(buf, len, len - 1, "    FC ALG: 0x%02X", conn->peerFcAlgs);
144     if (ret < 0) {
145         FILLP_LOGERR("snprintf_s failed");
146         return ret;
147     }
148     size_t formatLen = (FILLP_UINT32)ret;
149 
150     FILLP_CONST FILLP_CHAR *fcAlgStr[] = { "ALG_1", "ALG_2", "ALG_3", "ALG_MSG" };
151     ret = FillpBitmapFormat(buf + formatLen, len - formatLen, conn->peerFcAlgs,
152         fcAlgStr, UTILS_ARRAY_LEN(fcAlgStr));
153     if (ret < 0) {
154         FILLP_LOGERR("FillpBitmapFormat failed");
155         return ret;
156     }
157     formatLen += (FILLP_UINT32)ret;
158 
159     return (FILLP_INT)formatLen;
160 }
161 
162 static FILLP_INT (*g_extParaFormatter[FILLP_PKT_EXT_BUTT])(
163     FILLP_CONST struct FtNetconn *conn, FILLP_CHAR *buf, size_t len) = {
164     FILLP_NULL_PTR,
165     FillpExtParaRttFormat,
166     FillpExtParaPktSizeFormat,
167     FillpExtParaCharacterFormat,
168     FillpExtParaFcAlgFormat,
169 };
170 
FillpExtParaFormat(FILLP_CONST FILLP_UCHAR * extPara,FILLP_INT extParaLen,FILLP_CHAR * buf,size_t len)171 static FILLP_INT FillpExtParaFormat(FILLP_CONST FILLP_UCHAR *extPara, FILLP_INT extParaLen, FILLP_CHAR *buf, size_t len)
172 {
173     struct FtNetconn conn;
174     (void)memset_s(&conn, sizeof(struct FtNetconn), 0, sizeof(struct FtNetconn));
175     if (FillpDecodeExtPara(extPara, extParaLen, &conn) != ERR_OK) {
176         FILLP_LOGERR("FillpDecodeExtPara failed");
177         return -1;
178     }
179 
180     size_t formatLen = 0;
181     FILLP_INT i;
182     for (i = 0; i < FILLP_PKT_EXT_BUTT; i++) {
183         if (!conn.extParameterExisted[i] || g_extParaFormatter[i] == FILLP_NULL_PTR) {
184             continue;
185         }
186 
187         FILLP_INT ret = g_extParaFormatter[i](&conn, buf + formatLen, len - formatLen);
188         if (ret < 0 || (FILLP_UINT32)ret > len - formatLen) {
189             FILLP_LOGERR("g_extParaFormatter failed");
190             return -1;
191         }
192 
193         formatLen += ret;
194     }
195 
196     return (FILLP_INT)formatLen;
197 }
198 
FillpConnReqAckRxLog(FILLP_INT sockIndex,FILLP_CONST struct FillpPktHead * hdr,FILLP_CONST struct FillpConnReqAckClient * ack,FILLP_CONST FILLP_UCHAR * extPara,FILLP_INT extParaLen)199 void FillpConnReqAckRxLog(FILLP_INT sockIndex, FILLP_CONST struct FillpPktHead *hdr,
200     FILLP_CONST struct FillpConnReqAckClient *ack, FILLP_CONST FILLP_UCHAR *extPara, FILLP_INT extParaLen)
201 {
202     FILLP_CHAR tmpBuf[FILLP_EXT_PARA_FORMAT_BUF_LEN] = {0};
203     if (FillpExtParaFormat(extPara, extParaLen, tmpBuf, sizeof(tmpBuf)) < 0) {
204         return;
205     }
206 
207     FILLP_MGT_MSG_PRINT(sockIndex, hdr, FILLP_DIRECTION_RX,
208         "tag cookie: %hu, cookie len: %hu, cookie content: ****, timestamp: %llu, external parameter: %s",
209         ack->tagCookie, ack->cookieLength, ack->timestamp, tmpBuf);
210 }
211 
FillpConnReqAckTxLog(FILLP_INT sockIndex,FILLP_CONST struct FillpPktConnReqAck * ack,FILLP_CONST FILLP_UCHAR * extPara,FILLP_INT extParaLen)212 void FillpConnReqAckTxLog(FILLP_INT sockIndex, FILLP_CONST struct FillpPktConnReqAck *ack,
213     FILLP_CONST FILLP_UCHAR *extPara, FILLP_INT extParaLen)
214 {
215     FILLP_CHAR tmpBuf[FILLP_EXT_PARA_FORMAT_BUF_LEN] = {0};
216     if (FillpExtParaFormat(extPara, extParaLen, tmpBuf, sizeof(tmpBuf)) < 0) {
217         return;
218     }
219 
220     struct FillpPktHead hdr = {0};
221     FillpHeaderNtoH(&hdr, (FILLP_CONST struct FillpPktHead *)ack, FILLP_DIRECTION_TX);
222     FILLP_MGT_MSG_PRINT(sockIndex, &hdr, FILLP_DIRECTION_TX,
223         "tag cookie: %hu, cookie len: %hu, cookie content: ****, timestamp: %llu, external parameter: %s",
224         FILLP_NTOHS(ack->tagCookie), FILLP_NTOHS(ack->cookieLength), FILLP_NTOHLL(ack->timestamp), tmpBuf);
225 }
226 
FillpConnConfirmRxLog(FILLP_INT sockIndex,FILLP_CONST struct FillpPktConnConfirm * confirm,FILLP_CONST FILLP_UCHAR * extPara,FILLP_INT extParaLen)227 void FillpConnConfirmRxLog(FILLP_INT sockIndex, FILLP_CONST struct FillpPktConnConfirm *confirm,
228     FILLP_CONST FILLP_UCHAR *extPara, FILLP_INT extParaLen)
229 {
230     FILLP_CHAR tmpBuf[FILLP_EXT_PARA_FORMAT_BUF_LEN] = {0};
231     if (FillpExtParaFormat(extPara, extParaLen, tmpBuf, sizeof(tmpBuf)) < 0) {
232         return;
233     }
234 
235     FILLP_CHAR ipStr[FILLP_IP_ADDR_FORMAT_BUF_LEN] = {0};
236     FILLP_INT ret = IpAddrAnonymousFormat(ipStr, sizeof(ipStr),
237         (struct sockaddr *)&confirm->remoteAddr, sizeof(confirm->remoteAddr));
238     if (ret < 0) {
239         FILLP_LOGERR("ip addr format failed");
240         return;
241     }
242 
243     FILLP_MGT_MSG_PRINT(sockIndex, (FILLP_CONST struct FillpPktHead *)confirm->head, FILLP_DIRECTION_RX,
244         "tag cookie: %hu, cookie len: %hu, cookie content: ****, "
245         "remote address: [family: %s, port: %hu, IP: %s], external parameter: %s",
246         FILLP_NTOHS(confirm->tagCookie), FILLP_NTOHS(confirm->cookieLength),
247         (confirm->remoteAddr.sin6_family == AF_INET) ? "ipv4" : "ipv6",
248         FILLP_NTOHS(confirm->remoteAddr.sin6_port), ipStr, tmpBuf);
249 }
250 
FillpConnConfirmTxLog(FILLP_INT sockIndex,FILLP_CONST FILLP_UCHAR * data,FILLP_INT dataLen,FILLP_INT extParaOffset)251 void FillpConnConfirmTxLog(FILLP_INT sockIndex, FILLP_CONST FILLP_UCHAR *data, FILLP_INT dataLen,
252     FILLP_INT extParaOffset)
253 {
254     if (dataLen < extParaOffset || dataLen < (FILLP_INT)(FILLP_HLEN + FILLP_COOKIE_TAG_AND_LEN_SIZE)) {
255         return;
256     }
257 
258     FILLP_UINT16 tagCookie = *(FILLP_UINT16 *)(data + FILLP_HLEN);
259     tagCookie = FILLP_NTOHS(tagCookie);
260     FILLP_UINT16 cookieLen = *(FILLP_UINT16 *)(data + FILLP_HLEN + sizeof(FILLP_UINT16));
261     cookieLen = FILLP_NTOHS(cookieLen);
262     if (dataLen < (FILLP_INT)(FILLP_HLEN + FILLP_COOKIE_TAG_AND_LEN_SIZE + cookieLen + sizeof(struct sockaddr_in6))) {
263         return;
264     }
265 
266     struct sockaddr_in6 remoteAddr;
267     (void)memcpy_s(&remoteAddr, sizeof(struct sockaddr_in6),
268         data + FILLP_HLEN + FILLP_COOKIE_TAG_AND_LEN_SIZE + cookieLen, sizeof(struct sockaddr_in6));
269     FILLP_CHAR ipStr[FILLP_IP_ADDR_FORMAT_BUF_LEN] = {0};
270     FILLP_INT ret = IpAddrAnonymousFormat(ipStr, sizeof(ipStr), (struct sockaddr *)&remoteAddr, sizeof(remoteAddr));
271     if (ret < 0) {
272         FILLP_LOGERR("ip addr format failed");
273         return;
274     }
275 
276     FILLP_CHAR tmpBuf[FILLP_EXT_PARA_FORMAT_BUF_LEN] = {0};
277     if (FillpExtParaFormat(data + extParaOffset, dataLen - extParaOffset, tmpBuf, sizeof(tmpBuf)) < 0) {
278         return;
279     }
280 
281     struct FillpPktHead hdr = {0};
282     FillpHeaderNtoH(&hdr, (FILLP_CONST struct FillpPktHead *)data, FILLP_DIRECTION_TX);
283 
284     FILLP_MGT_MSG_PRINT(sockIndex, &hdr, FILLP_DIRECTION_TX,
285         "tag cookie: %hu, cookie len: %hu, cookie content: ****, "
286         "remote address: [family: %s, port: %hu, IP: %s], external parameter: %s",
287         tagCookie, cookieLen,
288         (remoteAddr.sin6_family == AF_INET) ? "ipv4" : "ipv6",
289         FILLP_NTOHS(remoteAddr.sin6_port), ipStr, tmpBuf);
290 }
291 
FillpConnConfirmAckLog(FILLP_INT sockIndex,FILLP_CONST struct FillpPktConnConfirmAck * confirmAck,FILLP_INT direction)292 void FillpConnConfirmAckLog(FILLP_INT sockIndex,
293     FILLP_CONST struct FillpPktConnConfirmAck *confirmAck, FILLP_INT direction)
294 {
295     struct FillpPktHead hdr = {0};
296     FillpHeaderNtoH(&hdr, (FILLP_CONST struct FillpPktHead *)confirmAck->head, direction);
297 
298     FILLP_CHAR ipStr[FILLP_IP_ADDR_FORMAT_BUF_LEN] = {0};
299     FILLP_INT ret = IpAddrAnonymousFormat(ipStr, sizeof(ipStr),
300         (struct sockaddr *)&confirmAck->remoteAddr, sizeof(confirmAck->remoteAddr));
301     if (ret < 0) {
302         FILLP_LOGERR("ip addr format failed");
303         return;
304     }
305 
306     FILLP_MGT_MSG_PRINT(sockIndex, &hdr, direction,
307         "send cache: %u, recv cache: %u, packet size: %u, remote address: [family: %s, port: %hu, IP: %s]",
308         FILLP_NTOHL(confirmAck->sendCache), FILLP_NTOHL(confirmAck->recvCache), FILLP_NTOHL(confirmAck->pktSize),
309         (confirmAck->remoteAddr.sin6_family == AF_INET) ? "ipv4" : "ipv6",
310         FILLP_NTOHS(confirmAck->remoteAddr.sin6_port), ipStr);
311 }
312 
FillpConnFinLog(FILLP_INT sockIndex,FILLP_CONST struct FillpPktFin * fin,FILLP_INT direction)313 void FillpConnFinLog(FILLP_INT sockIndex, FILLP_CONST struct FillpPktFin *fin, FILLP_INT direction)
314 {
315     FILLP_CHAR tmpBuf[FILLP_EXT_PARA_FORMAT_BUF_LEN] = {0};
316     FILLP_CONST FILLP_CHAR *flagStr[] = { "WR", "RD", "ACK", "VERSION_MISMATCH" };
317     FILLP_UINT32 flags = FILLP_NTOHS(fin->flag);
318     if (FillpBitmapFormat(tmpBuf, sizeof(tmpBuf), flags, flagStr, UTILS_ARRAY_LEN(flagStr)) < 0) {
319         FILLP_LOGERR("FillpBitmapFormat failed");
320         return;
321     }
322 
323     struct FillpPktHead hdr = {0};
324     FillpHeaderNtoH(&hdr, (FILLP_CONST struct FillpPktHead *)fin->head, direction);
325 
326     FILLP_MGT_MSG_PRINT(sockIndex, &hdr, direction, "flags: %s", tmpBuf);
327 }
328 #endif
329