• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "wrapper_decoder.h"
17 
18 #include <climits>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <map>
23 #include <memory>
24 #include <vector>
25 
26 #include <arpa/inet.h>
27 #include <net/if.h>
28 #include <netinet/in.h>
29 #include <sys/socket.h>
30 #include <sys/types.h>
31 
32 #include <linux/genetlink.h>
33 #include <linux/if_addr.h>
34 #include <linux/if_link.h>
35 #include <linux/netfilter/nfnetlink.h>
36 #include <linux/netfilter/nfnetlink_log.h>
37 
38 #include "netlink_define.h"
39 #include "netmanager_base_common_utils.h"
40 #include "netnative_log_wrapper.h"
41 
42 namespace OHOS {
43 namespace nmd {
44 using namespace OHOS::NetManagerStandard::CommonUtils;
45 using namespace NetlinkDefine;
46 namespace {
47 constexpr int16_t LOCAL_QLOG_NL_EVENT = 112;
48 constexpr int16_t LOCAL_NFLOG_PACKET = NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET;
49 
50 constexpr int16_t ULOG_MAC_LEN = 80;
51 constexpr int16_t ULOG_PREFIX_LEN = 32;
52 
53 // The message key for Ascii decode.
54 constexpr const char *SYMBOL_AT = "@";
55 constexpr const char *SYMBOL_EQUAL = "=";
56 constexpr const char *KEY_ACTION = "ACTION=";
57 constexpr const char *KEY_SEQNUM = "SEQNUM=";
58 constexpr const char *KEY_SUBSYSTEM = "SUBSYSTEM=";
59 constexpr const char *VALUE_ADD = "add";
60 constexpr const char *VALUE_REMOVE = "remove";
61 constexpr const char *VALUE_CHANGE = "change";
62 constexpr const char *SYMBOL_ADDRESS_SPLIT = "_";
63 constexpr const char *ADDRESS_SPLIT = "-";
64 constexpr const char *ROUTE_DEFAULT_ADDR = "0.0.0.0";
65 constexpr const char *ROUTE_DEFAULT_SPLIT = "::";
66 constexpr const char *ROUTE_ADDRESS_SPLIT = "/";
67 constexpr const char *RTA_GATEWAY_STR = "RTA_GATEWAY";
68 constexpr const char *RTA_DST_STR = "RTA_DST";
69 constexpr const char *RTA_OIF_STR = "RTA_OIF";
70 
71 struct ULogMessage {
72     uint64_t mark;
73     int64_t timeStampSec;
74     int64_t timeStampUsec;
75     uint32_t hook;
76     char indevName[IFNAMSIZ];
77     char outdevName[IFNAMSIZ];
78     size_t dataLen;
79     char prefix[ULOG_PREFIX_LEN];
80     uint8_t macLen;
81     uint8_t mac[ULOG_MAC_LEN];
82     uint8_t payload[0];
83 };
84 
85 const std::map<int32_t, std::string> MSG_NAME_MAP = {
86     {RTM_NEWLINK, "RTM_NEWLINK"},
87     {RTM_DELLINK, "RTM_DELLINK"},
88     {RTM_NEWADDR, "RTM_NEWADDR"},
89     {RTM_DELADDR, "RTM_DELADDR"},
90     {RTM_NEWROUTE, "RTM_NEWROUTE"},
91     {RTM_DELROUTE, "RTM_DELROUTE"},
92     {RTM_NEWNDUSEROPT, "RTM_NEWNDUSEROPT"},
93     {LOCAL_QLOG_NL_EVENT, "LOCAL_QLOG_NL_EVENT"},
94     {LOCAL_NFLOG_PACKET, "LOCAL_NFLOG_PACKET"},
95 };
96 
97 struct ServerInfo {
98     std::string ipAddr;
99     std::string ifName;
ServerInfoOHOS::nmd::__anon662ef6ce0111::ServerInfo100     ServerInfo(const std::string &ipAddr, const std::string &ifName) : ipAddr(ipAddr), ifName(ifName) {}
101 };
102 
103 struct ServerList {
104     std::vector<ServerInfo> infos;
SerializeOHOS::nmd::__anon662ef6ce0111::ServerList105     std::string Serialize()
106     {
107         std::string str;
108         for (const auto &info : infos) {
109             str += info.ipAddr + SYMBOL_ADDRESS_SPLIT;
110             if (!info.ifName.empty()) {
111                 str += info.ifName + ADDRESS_SPLIT;
112             }
113         }
114         return str;
115     }
116 
AddOHOS::nmd::__anon662ef6ce0111::ServerList117     void Add(const std::string &ipAddr, const std::string &ifName)
118     {
119         infos.emplace_back(ipAddr, ifName);
120     }
121 };
122 
CastNameToStr(int32_t form)123 const std::string CastNameToStr(int32_t form)
124 {
125     const auto &itr = MSG_NAME_MAP.find(form);
126     if (itr == MSG_NAME_MAP.end()) {
127         return {};
128     }
129     return itr->second;
130 }
131 
CheckRtNetlinkLength(const nlmsghdr * hdrMsg,size_t size)132 bool CheckRtNetlinkLength(const nlmsghdr *hdrMsg, size_t size)
133 {
134     int32_t type = hdrMsg->nlmsg_type;
135     bool ret = hdrMsg->nlmsg_len >= static_cast<uint32_t>(NLMSG_LENGTH(int(size)));
136     if (!ret) {
137         if (MSG_NAME_MAP.find(type) != MSG_NAME_MAP.end()) {
138             const std::string &netlinkType = MSG_NAME_MAP.at(type);
139             NETNATIVE_LOGE("Got a short %{public}s message\n", netlinkType.c_str());
140         }
141     }
142     return ret;
143 }
144 
IsDataEmpty(bool isValid,const std::string & attrName,const std::string & msgName)145 inline bool IsDataEmpty(bool isValid, const std::string &attrName, const std::string &msgName)
146 {
147     if (isValid) {
148         NETNATIVE_LOGE("Error Msg Repeated: attrName : %{public}s msgName: %{public}s", attrName.c_str(),
149                        msgName.c_str());
150     }
151     return !isValid;
152 }
153 
IsPayloadValidated(rtattr * dest,uint32_t size)154 inline bool IsPayloadValidated(rtattr *dest, uint32_t size)
155 {
156     int destLen = RTA_PAYLOAD(dest);
157     int32_t rtaSize = static_cast<int32_t>(size);
158     bool ret = destLen >= rtaSize;
159     if (!ret) {
160         NETNATIVE_LOGE("Short IFA_CACHEINFO dest = %{public}d, size = %{public}d", destLen, rtaSize);
161     }
162     return ret;
163 }
164 
165 const std::map<std::string, NetsysEventMessage::Type> ASCII_PARAM_LIST = {
166     {"IFINDEX", NetsysEventMessage::Type::IFINDEX},
167     {"INTERFACE", NetsysEventMessage::Type::INTERFACE}};
168 
169 const std::map<std::string, NetsysEventMessage::SubSys> SUB_SYS_LIST = {
170     {"net", NetsysEventMessage::SubSys::NET},
171 };
172 } // namespace
173 
WrapperDecoder(std::shared_ptr<NetsysEventMessage> message)174 WrapperDecoder::WrapperDecoder(std::shared_ptr<NetsysEventMessage> message) : message_(message) {}
175 
DecodeAscii(const char * buffer,int32_t buffSize)176 bool WrapperDecoder::DecodeAscii(const char *buffer, int32_t buffSize)
177 {
178     std::string buf = buffer;
179     const char *start = buffer;
180     const char *end = start + buffSize;
181     std::vector<std::string> recvmsg;
182     if (buffSize == 0) {
183         return false;
184     }
185     const auto msg = Split(buf, SYMBOL_AT);
186     if (msg.size() <= 1) {
187         NETNATIVE_LOGE("msg.size() = %{public}d, buf = %{public}s.", static_cast<int32_t>(msg.size()), buf.c_str());
188         return false;
189     }
190     const std::string path = msg[1];
191     if (path.empty()) {
192         return false;
193     }
194     const auto action = msg[0];
195     if (action.empty()) {
196         return false;
197     }
198 
199     // Skip the first line.
200     start += strlen(start) + 1;
201     while (start < end) {
202         if (start != nullptr) {
203             recvmsg.emplace_back(start);
204         }
205         // Skip to next line.
206         start += strlen(start) + 1;
207     }
208 
209     // Split the message and push them into params.
210     PushAsciiMessage(recvmsg);
211     return true;
212 }
213 
PushAsciiMessage(const std::vector<std::string> & recvmsg)214 bool WrapperDecoder::PushAsciiMessage(const std::vector<std::string> &recvmsg)
215 {
216     for (auto &i : recvmsg) {
217         if (i.compare(0, strlen(KEY_ACTION), KEY_ACTION) == 0) {
218             if (i.compare(strlen(KEY_ACTION), strlen(VALUE_ADD), VALUE_ADD) == 0) {
219                 message_->SetAction(NetsysEventMessage::Action::ADD);
220             } else if (i.compare(strlen(KEY_ACTION), strlen(VALUE_REMOVE), VALUE_REMOVE) == 0) {
221                 message_->SetAction(NetsysEventMessage::Action::REMOVE);
222             } else if (i.compare(strlen(KEY_ACTION), strlen(VALUE_CHANGE), VALUE_CHANGE) == 0) {
223                 message_->SetAction(NetsysEventMessage::Action::CHANGE);
224             }
225         } else if (i.compare(0, strlen(KEY_SEQNUM), KEY_SEQNUM) == 0) {
226             const auto seq = Split(i, SYMBOL_EQUAL);
227             if (seq.size() == SPLIT_SIZE) {
228                 message_->SetSeq(StrToInt(seq[1]));
229             }
230         } else if (i.compare(0, strlen(KEY_SUBSYSTEM), KEY_SUBSYSTEM) == 0) {
231             const auto subsys = Split(i, SYMBOL_EQUAL);
232             if ((subsys.size() == SPLIT_SIZE) && (SUB_SYS_LIST.find(subsys[1]) != SUB_SYS_LIST.end())) {
233                 message_->SetSubSys(SUB_SYS_LIST.at(subsys[1]));
234             }
235         } else {
236             SaveOtherMsg(i);
237         }
238     }
239     return true;
240 }
241 
DecodeBinary(const char * buffer,int32_t buffSize)242 bool WrapperDecoder::DecodeBinary(const char *buffer, int32_t buffSize)
243 {
244     const nlmsghdr *hdrMsg = nullptr;
245     bool result = false;
246     for (hdrMsg = reinterpret_cast<const nlmsghdr *>(buffer);
247          NLMSG_OK(hdrMsg, (unsigned)buffSize) && (hdrMsg->nlmsg_type != NLMSG_DONE);
248          hdrMsg = NLMSG_NEXT(hdrMsg, buffSize)) {
249         if (CastNameToStr(hdrMsg->nlmsg_type).empty()) {
250             NETNATIVE_LOGW("Netlink message type is unexpected as : %{public}d\n", hdrMsg->nlmsg_type);
251             continue;
252         }
253         switch (hdrMsg->nlmsg_type) {
254             case RTM_NEWLINK:
255                 result = InterpreteInfoMsg(hdrMsg);
256                 break;
257             case LOCAL_QLOG_NL_EVENT:
258                 result = InterpreteUlogMsg(hdrMsg);
259                 break;
260             case RTM_NEWADDR:
261             case RTM_DELADDR:
262                 result = InterpreteAddressMsg(hdrMsg);
263                 break;
264             case RTM_NEWROUTE:
265             case RTM_DELROUTE:
266                 result = InterpreteRtMsg(hdrMsg);
267                 break;
268             default:
269                 result = false;
270                 NETNATIVE_LOG_D("message type error as :%{public}d\n", hdrMsg->nlmsg_type);
271                 break;
272         }
273         if (result) {
274             return true;
275         }
276     }
277     return false;
278 }
279 
InterpreteInfoMsg(const nlmsghdr * hdrMsg)280 bool WrapperDecoder::InterpreteInfoMsg(const nlmsghdr *hdrMsg)
281 {
282     if (hdrMsg == nullptr) {
283         return false;
284     }
285     auto info = reinterpret_cast<ifinfomsg *>(NLMSG_DATA(hdrMsg));
286     if (info == nullptr || !CheckRtNetlinkLength(hdrMsg, sizeof(*info)) || (info->ifi_flags & IFF_LOOPBACK) != 0) {
287         return false;
288     }
289 
290     int32_t len = IFLA_PAYLOAD(hdrMsg);
291     rtattr *rtaInfo = nullptr;
292     for (rtaInfo = IFLA_RTA(info); RTA_OK(rtaInfo, len); rtaInfo = RTA_NEXT(rtaInfo, len)) {
293         if (rtaInfo == nullptr) {
294             NETNATIVE_LOGE("Unavailable ifinfomsg\n");
295             return false;
296         }
297         if (rtaInfo->rta_type == IFLA_IFNAME) {
298             message_->PushMessage(NetsysEventMessage::Type::INTERFACE,
299                                   std::string(reinterpret_cast<const char *>(RTA_DATA(rtaInfo))));
300             message_->PushMessage(NetsysEventMessage::Type::IFINDEX, std::to_string(info->ifi_index));
301             auto action = (info->ifi_flags & IFF_LOWER_UP) ? NetsysEventMessage::Action::LINKUP
302                                                            : NetsysEventMessage::Action::LINKDOWN;
303             message_->SetAction(action);
304             message_->SetSubSys(NetsysEventMessage::SubSys::NET);
305             return true;
306         }
307     }
308     return false;
309 }
310 
InterpreteUlogMsg(const nlmsghdr * hdrMsg)311 bool WrapperDecoder::InterpreteUlogMsg(const nlmsghdr *hdrMsg)
312 {
313     std::string devname;
314     ULogMessage *pm = reinterpret_cast<ULogMessage *>(NLMSG_DATA(hdrMsg));
315     if (!CheckRtNetlinkLength(hdrMsg, sizeof(*pm))) {
316         return false;
317     }
318     devname = pm->indevName[0] ? pm->indevName : pm->outdevName;
319     message_->PushMessage(NetsysEventMessage::Type::ALERT_NAME, std::string(pm->prefix));
320     message_->PushMessage(NetsysEventMessage::Type::INTERFACE, devname);
321     message_->SetSubSys(NetsysEventMessage::SubSys::QLOG);
322     message_->SetAction(NetsysEventMessage::Action::CHANGE);
323     return true;
324 }
325 
InterpreteAddressMsg(const nlmsghdr * hdrMsg)326 bool WrapperDecoder::InterpreteAddressMsg(const nlmsghdr *hdrMsg)
327 {
328     ifaddrmsg *addrMsg = reinterpret_cast<ifaddrmsg *>(NLMSG_DATA(hdrMsg));
329     ifa_cacheinfo *cacheInfo = nullptr;
330     char addresses[INET6_ADDRSTRLEN] = "";
331     char interfaceName[IFNAMSIZ] = "";
332     uint32_t flags;
333 
334     if (!CheckRtNetlinkLength(hdrMsg, sizeof(*addrMsg))) {
335         return false;
336     }
337     int32_t nlType = hdrMsg->nlmsg_type;
338     if (nlType != RTM_NEWADDR && nlType != RTM_DELADDR) {
339         NETNATIVE_LOGE("InterpreteAddressMsg on incorrect message nlType 0x%{public}x\n", nlType);
340         return false;
341     }
342     const std::string rtMsgType = CastNameToStr(nlType);
343     flags = addrMsg->ifa_flags;
344     int32_t len = IFA_PAYLOAD(hdrMsg);
345     for (rtattr *rtAttr = IFA_RTA(addrMsg); RTA_OK(rtAttr, len); rtAttr = RTA_NEXT(rtAttr, len)) {
346         if (rtAttr == nullptr) {
347             NETNATIVE_LOGE("Invalid ifaddrmsg\n");
348             return false;
349         }
350         switch (rtAttr->rta_type) {
351             case IFA_ADDRESS:
352                 if (!InterpreteIFaceAddr(addrMsg, addresses, sizeof(addresses), rtMsgType, interfaceName, rtAttr)) {
353                     // This is not an error, but we don't want to continue.
354                     NETNATIVE_LOG_D("InterpreteIFaceAddr failed");
355                 }
356                 break;
357             case IFA_CACHEINFO:
358                 if (IsDataEmpty(cacheInfo, "IFA_CACHEINFO", rtMsgType) &&
359                     !IsPayloadValidated(rtAttr, sizeof(*cacheInfo))) {
360                     break;
361                 }
362                 cacheInfo = reinterpret_cast<ifa_cacheinfo *>(RTA_DATA(rtAttr));
363                 break;
364             case IFA_FLAGS:
365                 flags = *(reinterpret_cast<uint32_t *>(RTA_DATA(rtAttr)));
366                 break;
367             default:
368                 break;
369         }
370     }
371     if (addresses[0] == '\0') {
372         NETNATIVE_LOGE("IFA_ADDRESS not exist in %{public}s\n", rtMsgType.c_str());
373         return false;
374     }
375     message_->SetAction((nlType == RTM_NEWADDR) ? NetsysEventMessage::Action::ADDRESSUPDATE
376                                                 : NetsysEventMessage::Action::ADDRESSREMOVED);
377     return SaveAddressMsg(addresses, addrMsg, std::to_string(flags), cacheInfo, interfaceName);
378 }
379 
InterpreteIFaceAddr(ifaddrmsg * ifAddr,char * addrStr,socklen_t sockLen,const std::string & msgType,char * ifName,rtattr * rta)380 bool WrapperDecoder::InterpreteIFaceAddr(ifaddrmsg *ifAddr, char *addrStr, socklen_t sockLen,
381                                          const std::string &msgType, char *ifName, rtattr *rta)
382 {
383     if (*addrStr != 0) {
384         NETNATIVE_LOGE("IFA_ADDRESS already exist in %{public}s", msgType.c_str());
385         return false;
386     }
387 
388     switch (ifAddr->ifa_family) {
389         case AF_INET: {
390             in_addr *ipv4Addr = reinterpret_cast<in_addr *>(RTA_DATA(rta));
391             if (!IsPayloadValidated(rta, sizeof(*ipv4Addr))) {
392                 return false;
393             }
394             inet_ntop(AF_INET, ipv4Addr, addrStr, sockLen);
395             break;
396         }
397         case AF_INET6: {
398             in6_addr *ipv6Addr = reinterpret_cast<in6_addr *>(RTA_DATA(rta));
399             if (!IsPayloadValidated(rta, sizeof(*ipv6Addr))) {
400                 return false;
401             }
402             inet_ntop(AF_INET6, ipv6Addr, addrStr, sockLen);
403             break;
404         }
405         default:
406             NETNATIVE_LOGE("Address family is unknown %{public}d\n", ifAddr->ifa_family);
407             return false;
408     }
409 
410     if (!if_indextoname(ifAddr->ifa_index, ifName)) {
411         NETNATIVE_LOGW("The interface index %{public}d in %{public}s is unknown", ifAddr->ifa_index, msgType.c_str());
412     }
413     return true;
414 }
415 
SaveAddressMsg(const std::string addrStr,const ifaddrmsg * addrMsg,const std::string flags,const ifa_cacheinfo * cacheInfo,const std::string interfaceName)416 bool WrapperDecoder::SaveAddressMsg(const std::string addrStr, const ifaddrmsg *addrMsg, const std::string flags,
417                                     const ifa_cacheinfo *cacheInfo, const std::string interfaceName)
418 {
419     if (addrStr.empty()) {
420         NETNATIVE_LOGE("No IFA_ADDRESS");
421         return false;
422     }
423     message_->SetSubSys(NetsysEventMessage::SubSys::NET);
424     message_->PushMessage(NetsysEventMessage::Type::INTERFACE, interfaceName);
425     message_->PushMessage(NetsysEventMessage::Type::ADDRESS,
426                           addrStr + ROUTE_ADDRESS_SPLIT + std::to_string(addrMsg->ifa_prefixlen));
427     message_->PushMessage(NetsysEventMessage::Type::FLAGS, flags);
428     message_->PushMessage(NetsysEventMessage::Type::SCOPE, std::to_string(addrMsg->ifa_scope));
429     message_->PushMessage(NetsysEventMessage::Type::IFINDEX, std::to_string(addrMsg->ifa_index));
430     if (cacheInfo != nullptr) {
431         message_->PushMessage(NetsysEventMessage::Type::PREFERRED, std::to_string(cacheInfo->ifa_prefered));
432         message_->PushMessage(NetsysEventMessage::Type::VALID, std::to_string(cacheInfo->ifa_valid));
433         message_->PushMessage(NetsysEventMessage::Type::CSTAMP, std::to_string(cacheInfo->cstamp));
434         message_->PushMessage(NetsysEventMessage::Type::TSTAMP, std::to_string(cacheInfo->tstamp));
435     }
436 
437     return true;
438 }
439 
InterpreteRtMsg(const nlmsghdr * hdrMsg)440 bool WrapperDecoder::InterpreteRtMsg(const nlmsghdr *hdrMsg)
441 {
442     uint8_t type = hdrMsg->nlmsg_type;
443     rtmsg *rtMsg = CheckRtParam(hdrMsg, type);
444     if (rtMsg == nullptr) {
445         return false;
446     }
447     char device[IFNAMSIZ] = {0};
448     char dst[INET6_ADDRSTRLEN] = {0};
449     char gateWay[INET6_ADDRSTRLEN] = {0};
450     int32_t rtmFamily = rtMsg->rtm_family;
451     int32_t rtmDstLen = rtMsg->rtm_dst_len;
452     std::string msgName = CastNameToStr(type);
453     size_t size = RTM_PAYLOAD(hdrMsg);
454     rtattr *rtAttr = nullptr;
455     for (rtAttr = RTM_RTA(rtMsg); RTA_OK(rtAttr, (int)size); rtAttr = RTA_NEXT(rtAttr, size)) {
456         switch (rtAttr->rta_type) {
457             case RTA_GATEWAY:
458                 if (IsDataEmpty(*gateWay, RTA_GATEWAY_STR, msgName) &&
459                     !inet_ntop(rtmFamily, RTA_DATA(rtAttr), gateWay, sizeof(gateWay))) {
460                     return false;
461                 }
462                 break;
463             case RTA_DST:
464                 if (IsDataEmpty(*dst, RTA_DST_STR, msgName) &&
465                     !inet_ntop(rtmFamily, RTA_DATA(rtAttr), dst, sizeof(dst))) {
466                     return false;
467                 }
468                 break;
469             case RTA_OIF:
470                 if (IsDataEmpty(*device, RTA_OIF_STR, msgName) &&
471                     if_indextoname(*(reinterpret_cast<int32_t *>(RTA_DATA(rtAttr))), device) == nullptr) {
472                     return false;
473                 }
474                 break;
475             default:
476                 break;
477         }
478     }
479     if (!SaveRtMsg(dst, gateWay, device, rtmDstLen, rtmFamily)) {
480         return false;
481     }
482     auto action =
483         (type == RTM_NEWROUTE) ? NetsysEventMessage::Action::ROUTEUPDATED : NetsysEventMessage::Action::ROUTEREMOVED;
484     message_->SetAction(action);
485     return true;
486 }
487 
CheckRtParam(const nlmsghdr * hdrMsg,uint8_t type)488 rtmsg *WrapperDecoder::CheckRtParam(const nlmsghdr *hdrMsg, uint8_t type)
489 {
490     if (type != RTM_NEWROUTE && type != RTM_DELROUTE) {
491         NETNATIVE_LOGE("read message error type %{public}d\n", type);
492         return nullptr;
493     }
494 
495     rtmsg *rtm = reinterpret_cast<rtmsg *>(NLMSG_DATA(hdrMsg));
496     if (!CheckRtNetlinkLength(hdrMsg, sizeof(*rtm))) {
497         return nullptr;
498     }
499 
500     if ((rtm->rtm_protocol != RTPROT_KERNEL && rtm->rtm_protocol != RTPROT_RA) ||
501         (rtm->rtm_scope != RT_SCOPE_UNIVERSE) || (rtm->rtm_type != RTN_UNICAST) || (rtm->rtm_src_len != 0) ||
502         (rtm->rtm_flags & RTM_F_CLONED)) {
503         return nullptr;
504     }
505     return rtm;
506 }
507 
SaveRtMsg(std::string dst,const std::string gateWay,const std::string device,int32_t length,int32_t family)508 bool WrapperDecoder::SaveRtMsg(std::string dst, const std::string gateWay, const std::string device, int32_t length,
509                                int32_t family)
510 {
511     if (length == 0) {
512         if (family == AF_INET) {
513             dst.append(ROUTE_DEFAULT_ADDR);
514         }
515         if (family == AF_INET6) {
516             dst.append(ROUTE_DEFAULT_SPLIT);
517         }
518     }
519     if (dst.empty() || (gateWay.empty() && device.empty())) {
520         NETNATIVE_LOGE("read message error dstSize: %{public}zu, gateWaySize: %{public}zu, deviceSize: %{public}zu",
521                        dst.size(), gateWay.size(), device.size());
522         return false;
523     }
524 
525     message_->SetSubSys(NetsysEventMessage::SubSys::NET);
526     message_->PushMessage(NetsysEventMessage::Type::ROUTE, dst + ROUTE_ADDRESS_SPLIT + std::to_string(length));
527     message_->PushMessage(NetsysEventMessage::Type::GATEWAY, gateWay);
528     message_->PushMessage(NetsysEventMessage::Type::INTERFACE, device);
529     return true;
530 }
531 
SaveOtherMsg(const std::string & info)532 void WrapperDecoder::SaveOtherMsg(const std::string &info)
533 {
534     auto msgList = Split(info, SYMBOL_EQUAL);
535     if (msgList.size() == SPLIT_SIZE) {
536         const auto key = msgList[0];
537         auto value = msgList[1];
538         if (ASCII_PARAM_LIST.find(key) != ASCII_PARAM_LIST.end()) {
539             message_->PushMessage(ASCII_PARAM_LIST.at(key), value);
540         }
541     }
542 }
543 } // namespace nmd
544 } // namespace OHOS
545