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