1/*
2 * Copyright (c) 2021-2023 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 "dev_interface_state.h"
17
18#include "inet_addr.h"
19#include "net_manager_center.h"
20#include "net_manager_constants.h"
21#include "netmanager_base_common_utils.h"
22#include "netmgr_ext_log_wrapper.h"
23#include "netsys_controller.h"
24#include "route.h"
25#include "static_configuration.h"
26
27namespace OHOS {
28namespace NetManagerStandard {
29namespace {
30constexpr const char *DEFAULT_ROUTE_ADDR = "0.0.0.0";
31} // namespace
32
33DevInterfaceState::DevInterfaceState()
34{
35    netSupplierInfo_ = new (std::nothrow) NetSupplierInfo();
36    if (netSupplierInfo_ == nullptr) {
37        NETMGR_EXT_LOG_E("NetSupplierInfo new failed");
38    }
39}
40
41void DevInterfaceState::SetDevName(const std::string &devName)
42{
43    devName_ = devName;
44}
45
46void DevInterfaceState::SetNetCaps(const std::set<NetCap> &netCaps)
47{
48    netCaps_ = netCaps;
49}
50
51void DevInterfaceState::SetLinkUp(bool up)
52{
53    linkUp_ = up;
54}
55
56void DevInterfaceState::SetlinkInfo(sptr<NetLinkInfo> &linkInfo)
57{
58    linkInfo_ = linkInfo;
59}
60
61void DevInterfaceState::SetIfcfg(sptr<InterfaceConfiguration> &ifCfg)
62{
63    ifCfg_ = ifCfg;
64    if (ifCfg_->mode_ == STATIC) {
65        UpdateLinkInfo();
66        if (connLinkState_ == LINK_AVAILABLE) {
67            RemoteUpdateNetLinkInfo();
68        }
69    }
70}
71
72void DevInterfaceState::SetLancfg(sptr<InterfaceConfiguration> &ifCfg)
73{
74    ifCfg_ = ifCfg;
75    if (ifCfg_->mode_ == LAN_STATIC) {
76        UpdateLanLinkInfo();
77    }
78}
79
80void DevInterfaceState::SetDhcpReqState(bool dhcpReqState)
81{
82    dhcpReqState_ = dhcpReqState;
83}
84
85std::string DevInterfaceState::GetDevName() const
86{
87    return devName_;
88}
89
90const std::set<NetCap> &DevInterfaceState::GetNetCaps() const
91{
92    return netCaps_;
93}
94
95std::set<NetCap> DevInterfaceState::GetNetCaps()
96{
97    return netCaps_;
98}
99
100bool DevInterfaceState::GetLinkUp() const
101{
102    return linkUp_;
103}
104
105sptr<NetLinkInfo> DevInterfaceState::GetLinkInfo() const
106{
107    return linkInfo_;
108}
109
110sptr<InterfaceConfiguration> DevInterfaceState::GetIfcfg() const
111{
112    return ifCfg_;
113}
114
115bool DevInterfaceState::IsLanIface()
116{
117    if (ifCfg_ == nullptr) {
118        return false;
119    }
120    if (ifCfg_->mode_ == LAN_STATIC || ifCfg_->mode_ == LAN_DHCP) {
121        return true;
122    }
123    return false;
124}
125
126IPSetMode DevInterfaceState::GetIPSetMode() const
127{
128    if (ifCfg_ == nullptr) {
129        return IPSetMode::STATIC;
130    }
131    return ifCfg_->mode_;
132}
133
134bool DevInterfaceState::GetDhcpReqState() const
135{
136    return dhcpReqState_;
137}
138
139void DevInterfaceState::RemoteRegisterNetSupplier()
140{
141    if (connLinkState_ == UNREGISTERED) {
142        if (netCaps_.empty()) {
143            netCaps_.insert(NET_CAPABILITY_INTERNET);
144        }
145        int32_t result =
146            NetManagerCenter::GetInstance().RegisterNetSupplier(bearerType_, devName_, netCaps_, netSupplier_);
147        if (result == NETMANAGER_SUCCESS) {
148            connLinkState_ = REGISTERED;
149        }
150        NETMGR_EXT_LOG_D("DevInterfaceCfg RemoteRegisterNetSupplier netSupplier_[%{public}d]", netSupplier_);
151    }
152}
153
154void DevInterfaceState::RemoteUnregisterNetSupplier()
155{
156    if (connLinkState_ == UNREGISTERED) {
157        return;
158    }
159    int ret = NetManagerCenter::GetInstance().UnregisterNetSupplier(netSupplier_);
160    if (ret == NETMANAGER_SUCCESS) {
161        connLinkState_ = UNREGISTERED;
162        netSupplier_ = 0;
163    }
164}
165
166void DevInterfaceState::RemoteUpdateNetLinkInfo()
167{
168    if (connLinkState_ == LINK_UNAVAILABLE) {
169        NETMGR_EXT_LOG_E("DevInterfaceCfg RemoteUpdateNetLinkInfo regState_:LINK_UNAVAILABLE");
170        return;
171    }
172    if (linkInfo_ == nullptr) {
173        NETMGR_EXT_LOG_E("DevInterfaceCfg RemoteUpdateNetLinkInfo linkInfo_ is nullptr");
174        return;
175    }
176    auto newNetLinkinfo = linkInfo_;
177    for (auto &netAddr: newNetLinkinfo->netAddrList_) {
178        if (netAddr.family_ == AF_INET) {
179            netAddr.family_ = INetAddr::IpType::IPV4;
180        } else if (netAddr.family_ == AF_INET6) {
181            netAddr.family_ = INetAddr::IpType::IPV6;
182        }
183    }
184    NetManagerCenter::GetInstance().UpdateNetLinkInfo(netSupplier_, newNetLinkinfo);
185}
186
187void DevInterfaceState::RemoteUpdateNetSupplierInfo()
188{
189    if (connLinkState_ == UNREGISTERED) {
190        NETMGR_EXT_LOG_E("DevInterfaceCfg RemoteUpdateNetSupplierInfo regState_:UNREGISTERED");
191        return;
192    }
193    if (netSupplierInfo_ == nullptr) {
194        NETMGR_EXT_LOG_E("DevInterfaceCfg RemoteUpdateNetSupplierInfo netSupplierInfo_ is nullptr");
195        return;
196    }
197    UpdateSupplierAvailable();
198    NetManagerCenter::GetInstance().UpdateNetSupplierInfo(netSupplier_, netSupplierInfo_);
199}
200
201void DevInterfaceState::UpdateNetHttpProxy(const HttpProxy &httpProxy)
202{
203    if (httpProxy == ifCfg_->httpProxy_) {
204        NETMGR_EXT_LOG_E("The currently set http proxy is the same as the entered http proxy");
205        return;
206    }
207    ifCfg_->httpProxy_ = httpProxy;
208    if (connLinkState_ == LINK_AVAILABLE) {
209        if (linkInfo_ == nullptr) {
210            NETMGR_EXT_LOG_E("linkInfo_ is nullptr");
211            return;
212        }
213        linkInfo_->httpProxy_ = httpProxy;
214        RemoteUpdateNetLinkInfo();
215    }
216}
217
218void DevInterfaceState::UpdateLinkInfo()
219{
220    if (ifCfg_ == nullptr || ifCfg_->mode_ != STATIC) {
221        return;
222    }
223    if (linkInfo_ == nullptr) {
224        linkInfo_ = new (std::nothrow) NetLinkInfo();
225        if (linkInfo_ == nullptr) {
226            NETMGR_EXT_LOG_E("linkInfo_ is nullptr");
227            return;
228        }
229    }
230    std::list<INetAddr>().swap(linkInfo_->netAddrList_);
231    std::list<Route>().swap(linkInfo_->routeList_);
232    std::list<INetAddr>().swap(linkInfo_->dnsList_);
233    linkInfo_->ifaceName_ = devName_;
234    for (const auto &ipAddr : ifCfg_->ipStatic_.ipAddrList_) {
235        linkInfo_->netAddrList_.push_back(ipAddr);
236    }
237
238    for (const auto &netAddr : ifCfg_->ipStatic_.routeList_) {
239        Route route;
240        route.iface_ = devName_;
241        route.destination_ = netAddr;
242        GetTargetNetAddrWithSameFamily(netAddr.address_, ifCfg_->ipStatic_.gatewayList_, route.gateway_);
243        linkInfo_->routeList_.push_back(route);
244    }
245    CreateLocalRoute(devName_, ifCfg_->ipStatic_.ipAddrList_, ifCfg_->ipStatic_.netMaskList_);
246
247    for (auto dnsServer : ifCfg_->ipStatic_.dnsServers_) {
248        linkInfo_->dnsList_.push_back(dnsServer);
249    }
250    linkInfo_->httpProxy_ = ifCfg_->httpProxy_;
251}
252
253void DevInterfaceState::UpdateLanLinkInfo()
254{
255    if (ifCfg_ == nullptr || ifCfg_->mode_ != LAN_STATIC) {
256        return;
257    }
258    if (linkInfo_ == nullptr) {
259        linkInfo_ = new (std::nothrow) NetLinkInfo();
260        if (linkInfo_ == nullptr) {
261            NETMGR_EXT_LOG_E("linkInfo_ is nullptr");
262            return;
263        }
264    }
265    std::list<INetAddr>().swap(linkInfo_->netAddrList_);
266    std::list<Route>().swap(linkInfo_->routeList_);
267    linkInfo_->ifaceName_ = devName_;
268    for (const auto &ipAddr : ifCfg_->ipStatic_.ipAddrList_) {
269        linkInfo_->netAddrList_.push_back(ipAddr);
270    }
271
272    for (const auto &netAddr : ifCfg_->ipStatic_.routeList_) {
273        Route route;
274        route.iface_ = devName_;
275        route.destination_ = netAddr;
276        GetRoutePrefixlen(netAddr.address_, ifCfg_->ipStatic_.netMaskList_, route.destination_);
277        GetTargetNetAddrWithSameFamily(netAddr.address_, ifCfg_->ipStatic_.gatewayList_, route.gateway_);
278        linkInfo_->routeList_.push_back(route);
279    }
280}
281
282void DevInterfaceState::UpdateLanLinkInfo(const sptr<StaticConfiguration> &config)
283{
284    if (config == nullptr) {
285        NETMGR_EXT_LOG_E("config is nullptr");
286        return;
287    }
288    if (linkInfo_ == nullptr) {
289        linkInfo_ = new (std::nothrow) NetLinkInfo();
290        if (linkInfo_ == nullptr) {
291            NETMGR_EXT_LOG_E("NetLinkInfo new failed");
292        }
293    }
294    std::list<INetAddr>().swap(linkInfo_->netAddrList_);
295    std::list<Route>().swap(linkInfo_->routeList_);
296    linkInfo_->ifaceName_ = devName_;
297    for (const auto &ipAddr : config->ipAddrList_) {
298        linkInfo_->netAddrList_.push_back(ipAddr);
299    }
300
301    for (const auto &routeAddr : config->routeList_) {
302        Route routeStc;
303        routeStc.iface_ = devName_;
304        routeStc.destination_ = routeAddr;
305        GetRoutePrefixlen(routeAddr.address_, config->netMaskList_, routeStc.destination_);
306        GetTargetNetAddrWithSameFamily(routeAddr.address_, config->gatewayList_, routeStc.gateway_);
307        linkInfo_->routeList_.push_back(routeStc);
308    }
309}
310
311void DevInterfaceState::UpdateLinkInfo(const sptr<StaticConfiguration> &config)
312{
313    if (config == nullptr) {
314        NETMGR_EXT_LOG_E("config is nullptr");
315        return;
316    }
317    if (linkInfo_ == nullptr) {
318        linkInfo_ = new (std::nothrow) NetLinkInfo();
319        if (linkInfo_ == nullptr) {
320            NETMGR_EXT_LOG_E("NetLinkInfo new failed");
321        }
322    }
323
324    std::list<INetAddr>().swap(linkInfo_->netAddrList_);
325    std::list<Route>().swap(linkInfo_->routeList_);
326    std::list<INetAddr>().swap(linkInfo_->dnsList_);
327    linkInfo_->ifaceName_ = devName_;
328    for (const auto &ipAddr : config->ipAddrList_) {
329        linkInfo_->netAddrList_.push_back(ipAddr);
330    }
331
332    for (const auto &routeAddr : config->routeList_) {
333        Route routeStc;
334        routeStc.iface_ = devName_;
335        routeStc.destination_ = routeAddr;
336        GetTargetNetAddrWithSameFamily(routeAddr.address_, config->gatewayList_, routeStc.gateway_);
337        linkInfo_->routeList_.push_back(routeStc);
338    }
339    CreateLocalRoute(devName_, config->ipAddrList_, config->netMaskList_);
340
341    for (auto dns : config->dnsServers_) {
342        linkInfo_->dnsList_.push_back(dns);
343    }
344    if (ifCfg_) {
345        linkInfo_->httpProxy_ = ifCfg_->httpProxy_;
346    }
347}
348
349void DevInterfaceState::UpdateSupplierAvailable()
350{
351    netSupplierInfo_->isAvailable_ = linkUp_;
352    connLinkState_ = linkUp_ ? LINK_AVAILABLE : LINK_UNAVAILABLE;
353}
354
355void DevInterfaceState::CreateLocalRoute(const std::string &iface, const std::vector<INetAddr> &ipAddrList,
356                                         const std::vector<INetAddr> &netMaskList)
357{
358    if (linkInfo_ == nullptr) {
359        NETMGR_EXT_LOG_E("linkInfo_ is nullptr");
360        return;
361    }
362
363    for (const auto &ipAddr : ipAddrList) {
364        auto family = CommonUtils::GetAddrFamily(ipAddr.address_);
365        std::string routeAddr = (family == AF_INET6) ? CommonUtils::GetIpv6Prefix(ipAddr.address_, ipAddr.prefixlen_)
366                                                     : GetIpv4Prefix(ipAddr.address_, netMaskList);
367        Route localRoute;
368        localRoute.iface_ = iface;
369        localRoute.destination_.type_ = family;
370        localRoute.destination_.address_ = routeAddr;
371        localRoute.destination_.prefixlen_ = ipAddr.prefixlen_;
372        localRoute.gateway_.address_ = (family == AF_INET) ? DEFAULT_ROUTE_ADDR : "";
373        linkInfo_->routeList_.push_back(localRoute);
374    }
375}
376
377std::string DevInterfaceState::GetIpv4Prefix(const std::string &ipv4Addr, const std::vector<INetAddr> &netMaskList)
378{
379    INetAddr maskAddr;
380    GetTargetNetAddrWithSameFamily(ipv4Addr, netMaskList, maskAddr);
381    uint32_t ipInt = CommonUtils::ConvertIpv4Address(ipv4Addr);
382    uint32_t maskInt = CommonUtils::ConvertIpv4Address(maskAddr.address_);
383    return CommonUtils::ConvertIpv4Address(ipInt & maskInt);
384}
385
386void DevInterfaceState::GetTargetNetAddrWithSameFamily(const std::string &bySrcAddr,
387                                                       const std::vector<INetAddr> &fromAddrList,
388                                                       INetAddr &targetNetAddr)
389{
390    auto family = CommonUtils::GetAddrFamily(bySrcAddr);
391    for (const auto &addr : fromAddrList) {
392        if (family != CommonUtils::GetAddrFamily(addr.address_)) {
393            continue;
394        }
395        targetNetAddr = addr;
396        return;
397    }
398}
399
400void DevInterfaceState::GetRoutePrefixlen(const std::string &bySrcAddr,
401                                          const std::vector<INetAddr> &fromAddrList,
402                                          INetAddr &targetNetAddr)
403{
404    auto route_family = CommonUtils::GetAddrFamily(bySrcAddr);
405    for (const auto &netMask : fromAddrList) {
406        auto route_mask_family = CommonUtils::GetAddrFamily(netMask.address_);
407        if (route_family == route_mask_family) {
408            targetNetAddr.prefixlen_ = (route_family == AF_INET6)
409                ? static_cast<uint32_t>(CommonUtils::Ipv6PrefixLen(netMask.address_))
410                : static_cast<uint32_t>(CommonUtils::Ipv4PrefixLen(netMask.address_));
411        }
412    }
413}
414
415void DevInterfaceState::GetDumpInfo(std::string &info)
416{
417    const std::string TAB = "  ";
418    std::list<std::string> dumpInfo = {
419        "DevName: " + devName_,
420        "ConnLinkState: " + std::to_string(connLinkState_),
421        "LinkUp: " + std::to_string(linkUp_),
422        "DHCPReqState: " + std::to_string(dhcpReqState_),
423    };
424    std::string data = "DevInterfaceState: \n";
425    std::for_each(dumpInfo.begin(), dumpInfo.end(),
426                  [&data, &TAB](const auto &msg) { data.append(TAB + TAB + msg + "\n"); });
427    if (linkInfo_ != nullptr) {
428        data.append(linkInfo_->ToString(TAB) + "\n");
429    }
430    if (netSupplierInfo_ != nullptr) {
431        data.append(netSupplierInfo_->ToString(TAB) + "\n");
432    }
433    if (ifCfg_ != nullptr) {
434        data.append("\n" + TAB + TAB + "InterfaceConfig: \n" + TAB + TAB + TAB +
435                    "Mode: " + std::to_string(ifCfg_->mode_) + "\n");
436        data.append("\nConfig: \n");
437        data.append(TAB + TAB + "IpAddr: ");
438        std::for_each(ifCfg_->ipStatic_.ipAddrList_.begin(), ifCfg_->ipStatic_.ipAddrList_.end(),
439                      [&data, &TAB](const auto &ipAddr) { data.append(TAB + TAB + ipAddr.ToString(TAB)); });
440
441        data.append("\n" + TAB + TAB + "Route: ");
442        std::for_each(ifCfg_->ipStatic_.routeList_.begin(), ifCfg_->ipStatic_.routeList_.end(),
443                      [&data, &TAB](const auto &routeAddr) { data.append(TAB + TAB + routeAddr.ToString(TAB)); });
444
445        data.append("\n" + TAB + TAB + "GateWay: ");
446        std::for_each(ifCfg_->ipStatic_.gatewayList_.begin(), ifCfg_->ipStatic_.gatewayList_.end(),
447                      [&data, &TAB](const auto &gateway) { data.append(TAB + TAB + gateway.ToString(TAB)); });
448
449        data.append("\n" + TAB + TAB + "NetMask: ");
450        std::for_each(ifCfg_->ipStatic_.netMaskList_.begin(), ifCfg_->ipStatic_.netMaskList_.end(),
451                      [&data, &TAB](const auto &netMask) { data.append(TAB + TAB + netMask.ToString(TAB)); });
452
453        data.append("\n" + TAB + TAB + "DNSServers: ");
454        std::for_each(ifCfg_->ipStatic_.dnsServers_.begin(), ifCfg_->ipStatic_.dnsServers_.end(),
455                      [&data, &TAB](const auto &server) { data.append(TAB + TAB + server.ToString(TAB)); });
456
457        data.append("\n" + TAB + TAB + "Domain: " + ifCfg_->ipStatic_.domain_ + "\n" + TAB + TAB + "NetCaps: {");
458        std::for_each(netCaps_.begin(), netCaps_.end(),
459                      [&data, &TAB](const auto &cap) { data.append(std::to_string(cap) + ", "); });
460        data.append("}\n");
461    }
462    data.append(TAB + TAB + "BearerType :" + std::to_string(bearerType_) + "\n");
463    info.append(data);
464}
465} // namespace NetManagerStandard
466} // namespace OHOS
467