1b1b8bc3fSopenharmony_ci/*
2b1b8bc3fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License.
5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at
6b1b8bc3fSopenharmony_ci *
7b1b8bc3fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8b1b8bc3fSopenharmony_ci *
9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and
13b1b8bc3fSopenharmony_ci * limitations under the License.
14b1b8bc3fSopenharmony_ci */
15b1b8bc3fSopenharmony_ci
16b1b8bc3fSopenharmony_ci#include "netlink_msg.h"
17b1b8bc3fSopenharmony_ci
18b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h"
19b1b8bc3fSopenharmony_ci#include "securec.h"
20b1b8bc3fSopenharmony_ci
21b1b8bc3fSopenharmony_cinamespace OHOS {
22b1b8bc3fSopenharmony_cinamespace nmd {
23b1b8bc3fSopenharmony_ciNetlinkMsg::NetlinkMsg(uint16_t flags, size_t maxBufLen, int32_t pid)
24b1b8bc3fSopenharmony_ci{
25b1b8bc3fSopenharmony_ci    maxBufLen_ = maxBufLen;
26b1b8bc3fSopenharmony_ci    msghdrBuf_ = std::make_unique<char[]>(NLMSG_SPACE(maxBufLen));
27b1b8bc3fSopenharmony_ci    netlinkMessage_ = reinterpret_cast<struct nlmsghdr *>(msghdrBuf_.get());
28b1b8bc3fSopenharmony_ci    errno_t result = memset_s(netlinkMessage_, NLMSG_SPACE(maxBufLen), 0, NLMSG_SPACE(maxBufLen));
29b1b8bc3fSopenharmony_ci    if (result != 0) {
30b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("[NetlinkMessage]: memset result %{public}d", result);
31b1b8bc3fSopenharmony_ci        return;
32b1b8bc3fSopenharmony_ci    }
33b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
34b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_pid = static_cast<uint32_t>(pid);
35b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_seq = 1;
36b1b8bc3fSopenharmony_ci}
37b1b8bc3fSopenharmony_ci
38b1b8bc3fSopenharmony_ciNetlinkMsg::~NetlinkMsg() = default;
39b1b8bc3fSopenharmony_ci
40b1b8bc3fSopenharmony_civoid NetlinkMsg::AddRoute(uint16_t action, struct rtmsg msg)
41b1b8bc3fSopenharmony_ci{
42b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_type = action;
43b1b8bc3fSopenharmony_ci    int32_t result = memcpy_s(NLMSG_DATA(netlinkMessage_), sizeof(struct rtmsg), &msg, sizeof(struct rtmsg));
44b1b8bc3fSopenharmony_ci    if (result != 0) {
45b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("[AddRoute]: string copy failed result %{public}d", result);
46b1b8bc3fSopenharmony_ci    }
47b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
48b1b8bc3fSopenharmony_ci}
49b1b8bc3fSopenharmony_ci
50b1b8bc3fSopenharmony_civoid NetlinkMsg::AddRule(uint16_t action, struct fib_rule_hdr msg)
51b1b8bc3fSopenharmony_ci{
52b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_type = action;
53b1b8bc3fSopenharmony_ci    int32_t result =
54b1b8bc3fSopenharmony_ci        memcpy_s(NLMSG_DATA(netlinkMessage_), sizeof(struct fib_rule_hdr), &msg, sizeof(struct fib_rule_hdr));
55b1b8bc3fSopenharmony_ci    if (result != 0) {
56b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("[AddRule]: string copy failed result %{public}d", result);
57b1b8bc3fSopenharmony_ci    }
58b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_len = static_cast<uint32_t>(NLMSG_LENGTH(sizeof(struct fib_rule_hdr)));
59b1b8bc3fSopenharmony_ci}
60b1b8bc3fSopenharmony_ci
61b1b8bc3fSopenharmony_civoid NetlinkMsg::AddAddress(uint16_t action, struct ifaddrmsg msg)
62b1b8bc3fSopenharmony_ci{
63b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_type = action;
64b1b8bc3fSopenharmony_ci    int32_t result = memcpy_s(NLMSG_DATA(netlinkMessage_), sizeof(struct ifaddrmsg), &msg, sizeof(struct ifaddrmsg));
65b1b8bc3fSopenharmony_ci    if (result != 0) {
66b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("[AddAddress]: string copy failed result %{public}d", result);
67b1b8bc3fSopenharmony_ci        return;
68b1b8bc3fSopenharmony_ci    }
69b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_len = static_cast<uint32_t>(NLMSG_LENGTH(sizeof(struct ifaddrmsg)));
70b1b8bc3fSopenharmony_ci}
71b1b8bc3fSopenharmony_ci
72b1b8bc3fSopenharmony_ciint32_t NetlinkMsg::AddAttr(uint16_t type, void *data, size_t alen)
73b1b8bc3fSopenharmony_ci{
74b1b8bc3fSopenharmony_ci    if (alen == 0 || data == nullptr) {
75b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("[NetlinkMessage]: length data can not be 0 or attr data can not be null");
76b1b8bc3fSopenharmony_ci        return -1;
77b1b8bc3fSopenharmony_ci    }
78b1b8bc3fSopenharmony_ci
79b1b8bc3fSopenharmony_ci    int32_t len = RTA_LENGTH(alen);
80b1b8bc3fSopenharmony_ci    if (NLMSG_ALIGN(netlinkMessage_->nlmsg_len) + RTA_ALIGN(len) > maxBufLen_) {
81b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("[NetlinkMessage]: attr length than max len: %{public}d", (int32_t)maxBufLen_);
82b1b8bc3fSopenharmony_ci        return -1;
83b1b8bc3fSopenharmony_ci    }
84b1b8bc3fSopenharmony_ci
85b1b8bc3fSopenharmony_ci    struct rtattr *rta = (struct rtattr *)(((char *)netlinkMessage_) + NLMSG_ALIGN(netlinkMessage_->nlmsg_len));
86b1b8bc3fSopenharmony_ci    if (rta == nullptr) {
87b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Pointer rta is nullptr");
88b1b8bc3fSopenharmony_ci        return -1;
89b1b8bc3fSopenharmony_ci    }
90b1b8bc3fSopenharmony_ci    rta->rta_type = type;
91b1b8bc3fSopenharmony_ci    rta->rta_len = static_cast<uint16_t>(len);
92b1b8bc3fSopenharmony_ci
93b1b8bc3fSopenharmony_ci    if (data != nullptr) {
94b1b8bc3fSopenharmony_ci        int32_t result = memcpy_s(RTA_DATA(rta), alen, data, alen);
95b1b8bc3fSopenharmony_ci        if (result != 0) {
96b1b8bc3fSopenharmony_ci            NETNATIVE_LOGE("[get_addr_info]: string copy failed result %{public}d", result);
97b1b8bc3fSopenharmony_ci            return -1;
98b1b8bc3fSopenharmony_ci        }
99b1b8bc3fSopenharmony_ci    }
100b1b8bc3fSopenharmony_ci
101b1b8bc3fSopenharmony_ci    netlinkMessage_->nlmsg_len = NLMSG_ALIGN(netlinkMessage_->nlmsg_len) + RTA_ALIGN(len);
102b1b8bc3fSopenharmony_ci    return 0;
103b1b8bc3fSopenharmony_ci}
104b1b8bc3fSopenharmony_ci
105b1b8bc3fSopenharmony_ciint32_t NetlinkMsg::AddAttr16(uint16_t type, uint16_t data)
106b1b8bc3fSopenharmony_ci{
107b1b8bc3fSopenharmony_ci    return AddAttr(type, &data, sizeof(uint16_t));
108b1b8bc3fSopenharmony_ci}
109b1b8bc3fSopenharmony_ci
110b1b8bc3fSopenharmony_ciint32_t NetlinkMsg::AddAttr32(uint16_t type, uint32_t data)
111b1b8bc3fSopenharmony_ci{
112b1b8bc3fSopenharmony_ci    return AddAttr(type, &data, sizeof(uint32_t));
113b1b8bc3fSopenharmony_ci}
114b1b8bc3fSopenharmony_ci
115b1b8bc3fSopenharmony_cinlmsghdr *NetlinkMsg::GetNetLinkMessage()
116b1b8bc3fSopenharmony_ci{
117b1b8bc3fSopenharmony_ci    return netlinkMessage_;
118b1b8bc3fSopenharmony_ci}
119b1b8bc3fSopenharmony_ci} // namespace nmd
120b1b8bc3fSopenharmony_ci} // namespace OHOS
121