1 /*
2  * Copyright (c) 2021-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 "netlink_msg.h"
17 
18 #include "netnative_log_wrapper.h"
19 #include "securec.h"
20 
21 namespace OHOS {
22 namespace nmd {
NetlinkMsg(uint16_t flags,size_t maxBufLen,int32_t pid)23 NetlinkMsg::NetlinkMsg(uint16_t flags, size_t maxBufLen, int32_t pid)
24 {
25     maxBufLen_ = maxBufLen;
26     msghdrBuf_ = std::make_unique<char[]>(NLMSG_SPACE(maxBufLen));
27     netlinkMessage_ = reinterpret_cast<struct nlmsghdr *>(msghdrBuf_.get());
28     errno_t result = memset_s(netlinkMessage_, NLMSG_SPACE(maxBufLen), 0, NLMSG_SPACE(maxBufLen));
29     if (result != 0) {
30         NETNATIVE_LOGE("[NetlinkMessage]: memset result %{public}d", result);
31         return;
32     }
33     netlinkMessage_->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
34     netlinkMessage_->nlmsg_pid = static_cast<uint32_t>(pid);
35     netlinkMessage_->nlmsg_seq = 1;
36 }
37 
38 NetlinkMsg::~NetlinkMsg() = default;
39 
AddRoute(uint16_t action,struct rtmsg msg)40 void NetlinkMsg::AddRoute(uint16_t action, struct rtmsg msg)
41 {
42     netlinkMessage_->nlmsg_type = action;
43     int32_t result = memcpy_s(NLMSG_DATA(netlinkMessage_), sizeof(struct rtmsg), &msg, sizeof(struct rtmsg));
44     if (result != 0) {
45         NETNATIVE_LOGE("[AddRoute]: string copy failed result %{public}d", result);
46     }
47     netlinkMessage_->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
48 }
49 
AddRule(uint16_t action,struct fib_rule_hdr msg)50 void NetlinkMsg::AddRule(uint16_t action, struct fib_rule_hdr msg)
51 {
52     netlinkMessage_->nlmsg_type = action;
53     int32_t result =
54         memcpy_s(NLMSG_DATA(netlinkMessage_), sizeof(struct fib_rule_hdr), &msg, sizeof(struct fib_rule_hdr));
55     if (result != 0) {
56         NETNATIVE_LOGE("[AddRule]: string copy failed result %{public}d", result);
57     }
58     netlinkMessage_->nlmsg_len = static_cast<uint32_t>(NLMSG_LENGTH(sizeof(struct fib_rule_hdr)));
59 }
60 
AddAddress(uint16_t action,struct ifaddrmsg msg)61 void NetlinkMsg::AddAddress(uint16_t action, struct ifaddrmsg msg)
62 {
63     netlinkMessage_->nlmsg_type = action;
64     int32_t result = memcpy_s(NLMSG_DATA(netlinkMessage_), sizeof(struct ifaddrmsg), &msg, sizeof(struct ifaddrmsg));
65     if (result != 0) {
66         NETNATIVE_LOGE("[AddAddress]: string copy failed result %{public}d", result);
67         return;
68     }
69     netlinkMessage_->nlmsg_len = static_cast<uint32_t>(NLMSG_LENGTH(sizeof(struct ifaddrmsg)));
70 }
71 
AddAttr(uint16_t type,void * data,size_t alen)72 int32_t NetlinkMsg::AddAttr(uint16_t type, void *data, size_t alen)
73 {
74     if (alen == 0 || data == nullptr) {
75         NETNATIVE_LOGE("[NetlinkMessage]: length data can not be 0 or attr data can not be null");
76         return -1;
77     }
78 
79     int32_t len = RTA_LENGTH(alen);
80     if (NLMSG_ALIGN(netlinkMessage_->nlmsg_len) + RTA_ALIGN(len) > maxBufLen_) {
81         NETNATIVE_LOGE("[NetlinkMessage]: attr length than max len: %{public}d", (int32_t)maxBufLen_);
82         return -1;
83     }
84 
85     struct rtattr *rta = (struct rtattr *)(((char *)netlinkMessage_) + NLMSG_ALIGN(netlinkMessage_->nlmsg_len));
86     if (rta == nullptr) {
87         NETNATIVE_LOGE("Pointer rta is nullptr");
88         return -1;
89     }
90     rta->rta_type = type;
91     rta->rta_len = static_cast<uint16_t>(len);
92 
93     if (data != nullptr) {
94         int32_t result = memcpy_s(RTA_DATA(rta), alen, data, alen);
95         if (result != 0) {
96             NETNATIVE_LOGE("[get_addr_info]: string copy failed result %{public}d", result);
97             return -1;
98         }
99     }
100 
101     netlinkMessage_->nlmsg_len = NLMSG_ALIGN(netlinkMessage_->nlmsg_len) + RTA_ALIGN(len);
102     return 0;
103 }
104 
AddAttr16(uint16_t type,uint16_t data)105 int32_t NetlinkMsg::AddAttr16(uint16_t type, uint16_t data)
106 {
107     return AddAttr(type, &data, sizeof(uint16_t));
108 }
109 
AddAttr32(uint16_t type,uint32_t data)110 int32_t NetlinkMsg::AddAttr32(uint16_t type, uint32_t data)
111 {
112     return AddAttr(type, &data, sizeof(uint32_t));
113 }
114 
GetNetLinkMessage()115 nlmsghdr *NetlinkMsg::GetNetLinkMessage()
116 {
117     return netlinkMessage_;
118 }
119 } // namespace nmd
120 } // namespace OHOS
121