1b1b8bc3fSopenharmony_ci/* 2b1b8bc3fSopenharmony_ci * Copyright (c) 2021-2024 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 "route_utils.h" 17b1b8bc3fSopenharmony_ci 18b1b8bc3fSopenharmony_ci#include <arpa/inet.h> 19b1b8bc3fSopenharmony_ci 20b1b8bc3fSopenharmony_ci#include "net_mgr_log_wrapper.h" 21b1b8bc3fSopenharmony_ci#include "netsys_controller.h" 22b1b8bc3fSopenharmony_ci 23b1b8bc3fSopenharmony_cinamespace OHOS { 24b1b8bc3fSopenharmony_cinamespace NetManagerStandard { 25b1b8bc3fSopenharmony_cistatic constexpr const char *IPV6_DEFAULT_PRIFX = "fe80::"; 26b1b8bc3fSopenharmony_cistatic constexpr const char *IPV6_DEFAULT_GATEWAY = "::"; 27b1b8bc3fSopenharmony_cistatic constexpr int32_t IPV6_PRIFX_LEN = 64; 28b1b8bc3fSopenharmony_cistatic constexpr int32_t IPV4_PRIFX_LEN = 32; 29b1b8bc3fSopenharmony_cistatic constexpr int32_t IPV6_UINT_LEN = 16; 30b1b8bc3fSopenharmony_cistatic constexpr int32_t IPV4_UINT_LEN = 4; 31b1b8bc3fSopenharmony_cistatic constexpr int32_t IP_PER_UINT_SIZE = 8; 32b1b8bc3fSopenharmony_cistatic constexpr int32_t IP_PER_UINT_MASK = 0xFF; 33b1b8bc3fSopenharmony_ci 34b1b8bc3fSopenharmony_ciint32_t RouteUtils::AddRoutesToLocal(const std::string &iface, const std::list<Route> &routes) 35b1b8bc3fSopenharmony_ci{ 36b1b8bc3fSopenharmony_ci std::list<Route>::const_iterator iter; 37b1b8bc3fSopenharmony_ci for (iter = routes.begin(); iter != routes.end(); ++iter) { 38b1b8bc3fSopenharmony_ci if (!(iter->rtnType_ == RTN_UNICAST && iter->destination_.prefixlen_ == 0)) { 39b1b8bc3fSopenharmony_ci NETMGR_LOG_D("AddRoutesToLocalNetwork: dest addr, gw addr"); 40b1b8bc3fSopenharmony_ci AddRoute(LOCAL_NET_ID, *iter); 41b1b8bc3fSopenharmony_ci } 42b1b8bc3fSopenharmony_ci } 43b1b8bc3fSopenharmony_ci 44b1b8bc3fSopenharmony_ci Route ipv6Rt; 45b1b8bc3fSopenharmony_ci ipv6Rt.iface_ = iface; 46b1b8bc3fSopenharmony_ci ipv6Rt.destination_.type_ = INetAddr::IPV6; 47b1b8bc3fSopenharmony_ci ipv6Rt.destination_.address_ = IPV6_DEFAULT_PRIFX; 48b1b8bc3fSopenharmony_ci ipv6Rt.destination_.prefixlen_ = IPV6_PRIFX_LEN; 49b1b8bc3fSopenharmony_ci ipv6Rt.gateway_.address_ = IPV6_DEFAULT_GATEWAY; 50b1b8bc3fSopenharmony_ci ipv6Rt.gateway_.prefixlen_ = 0; 51b1b8bc3fSopenharmony_ci ipv6Rt.hasGateway_ = false; 52b1b8bc3fSopenharmony_ci ipv6Rt.rtnType_ = RTN_UNICAST; 53b1b8bc3fSopenharmony_ci ipv6Rt.isDefaultRoute_ = false; 54b1b8bc3fSopenharmony_ci return AddRoute(LOCAL_NET_ID, ipv6Rt); 55b1b8bc3fSopenharmony_ci} 56b1b8bc3fSopenharmony_ci 57b1b8bc3fSopenharmony_ciint32_t RouteUtils::RemoveRoutesFromLocal(const std::list<Route> &routes) 58b1b8bc3fSopenharmony_ci{ 59b1b8bc3fSopenharmony_ci std::list<Route>::const_iterator iter; 60b1b8bc3fSopenharmony_ci for (iter = routes.begin(); iter != routes.end(); ++iter) { 61b1b8bc3fSopenharmony_ci RemoveRoute(LOCAL_NET_ID, *iter); 62b1b8bc3fSopenharmony_ci } 63b1b8bc3fSopenharmony_ci 64b1b8bc3fSopenharmony_ci return 0; 65b1b8bc3fSopenharmony_ci} 66b1b8bc3fSopenharmony_ci 67b1b8bc3fSopenharmony_ciint32_t RouteUtils::AddRoute(int32_t netId, const Route &route) 68b1b8bc3fSopenharmony_ci{ 69b1b8bc3fSopenharmony_ci return ModifyRoute(ROUTE_ADD, netId, route); 70b1b8bc3fSopenharmony_ci} 71b1b8bc3fSopenharmony_ci 72b1b8bc3fSopenharmony_ciint32_t RouteUtils::RemoveRoute(int32_t netId, const Route &route) 73b1b8bc3fSopenharmony_ci{ 74b1b8bc3fSopenharmony_ci return ModifyRoute(ROUTE_REMOVE, netId, route); 75b1b8bc3fSopenharmony_ci} 76b1b8bc3fSopenharmony_ci 77b1b8bc3fSopenharmony_ciint32_t RouteUtils::UpdateRoutes(int32_t netId, const NetLinkInfo &newnl, const NetLinkInfo &oldnl) 78b1b8bc3fSopenharmony_ci{ 79b1b8bc3fSopenharmony_ci std::list<Route> added; 80b1b8bc3fSopenharmony_ci std::list<Route> updated; 81b1b8bc3fSopenharmony_ci std::list<Route> removed; 82b1b8bc3fSopenharmony_ci std::list<Route>::const_iterator itero; 83b1b8bc3fSopenharmony_ci std::list<Route>::const_iterator itern; 84b1b8bc3fSopenharmony_ci std::list<Route>::const_iterator iterf; 85b1b8bc3fSopenharmony_ci 86b1b8bc3fSopenharmony_ci for (itero = oldnl.routeList_.begin(); itero != oldnl.routeList_.end(); ++itero) { 87b1b8bc3fSopenharmony_ci iterf = std::find(newnl.routeList_.begin(), newnl.routeList_.end(), *itero); 88b1b8bc3fSopenharmony_ci if (iterf == newnl.routeList_.end()) { 89b1b8bc3fSopenharmony_ci removed.push_back(*itero); 90b1b8bc3fSopenharmony_ci } else { 91b1b8bc3fSopenharmony_ci if (itero->rtnType_ != iterf->rtnType_ || itero->mtu_ != iterf->mtu_) { 92b1b8bc3fSopenharmony_ci updated.push_back(*iterf); 93b1b8bc3fSopenharmony_ci } 94b1b8bc3fSopenharmony_ci } 95b1b8bc3fSopenharmony_ci } 96b1b8bc3fSopenharmony_ci 97b1b8bc3fSopenharmony_ci for (itern = newnl.routeList_.begin(); itern != newnl.routeList_.end(); ++itern) { 98b1b8bc3fSopenharmony_ci if (std::find(oldnl.routeList_.begin(), oldnl.routeList_.end(), *itern) == oldnl.routeList_.end()) { 99b1b8bc3fSopenharmony_ci added.push_back(*itern); 100b1b8bc3fSopenharmony_ci } 101b1b8bc3fSopenharmony_ci } 102b1b8bc3fSopenharmony_ci 103b1b8bc3fSopenharmony_ci for (itern = added.begin(); itern != added.end(); ++itern) { 104b1b8bc3fSopenharmony_ci if (itern->hasGateway_) { 105b1b8bc3fSopenharmony_ci continue; 106b1b8bc3fSopenharmony_ci } 107b1b8bc3fSopenharmony_ci AddRoute(netId, *itern); 108b1b8bc3fSopenharmony_ci } 109b1b8bc3fSopenharmony_ci 110b1b8bc3fSopenharmony_ci for (itern = added.begin(); itern != added.end(); ++itern) { 111b1b8bc3fSopenharmony_ci if (!itern->hasGateway_) { 112b1b8bc3fSopenharmony_ci continue; 113b1b8bc3fSopenharmony_ci } 114b1b8bc3fSopenharmony_ci AddRoute(netId, *itern); 115b1b8bc3fSopenharmony_ci } 116b1b8bc3fSopenharmony_ci 117b1b8bc3fSopenharmony_ci for (itern = removed.begin(); itern != removed.end(); ++itern) { 118b1b8bc3fSopenharmony_ci RemoveRoute(netId, *itern); 119b1b8bc3fSopenharmony_ci } 120b1b8bc3fSopenharmony_ci 121b1b8bc3fSopenharmony_ci return (!added.empty() || !updated.empty() || !removed.empty()) ? 1 : 0; 122b1b8bc3fSopenharmony_ci} 123b1b8bc3fSopenharmony_ci 124b1b8bc3fSopenharmony_ciint32_t RouteUtils::ModifyRoute(routeOperateType op, int32_t netId, const Route &route) 125b1b8bc3fSopenharmony_ci{ 126b1b8bc3fSopenharmony_ci int32_t ret = -1; 127b1b8bc3fSopenharmony_ci std::string nextHop; 128b1b8bc3fSopenharmony_ci std::string dest; 129b1b8bc3fSopenharmony_ci 130b1b8bc3fSopenharmony_ci NETMGR_LOG_D("ModifyRoute: netId[%{public}d], dest addr, gw addr", netId); 131b1b8bc3fSopenharmony_ci 132b1b8bc3fSopenharmony_ci switch (route.rtnType_) { 133b1b8bc3fSopenharmony_ci case RTN_UNICAST: 134b1b8bc3fSopenharmony_ci if (route.hasGateway_) { 135b1b8bc3fSopenharmony_ci nextHop = route.gateway_.address_; 136b1b8bc3fSopenharmony_ci } 137b1b8bc3fSopenharmony_ci break; 138b1b8bc3fSopenharmony_ci case RTN_UNREACHABLE: 139b1b8bc3fSopenharmony_ci nextHop = NEXTHOP_UNREACHABLE; 140b1b8bc3fSopenharmony_ci break; 141b1b8bc3fSopenharmony_ci case RTN_THROW: 142b1b8bc3fSopenharmony_ci nextHop = NEXTHOP_THROW; 143b1b8bc3fSopenharmony_ci break; 144b1b8bc3fSopenharmony_ci default: 145b1b8bc3fSopenharmony_ci break; 146b1b8bc3fSopenharmony_ci } 147b1b8bc3fSopenharmony_ci 148b1b8bc3fSopenharmony_ci ToPrefixString(route.destination_.address_, route.destination_.prefixlen_, dest); 149b1b8bc3fSopenharmony_ci if (dest.empty()) { 150b1b8bc3fSopenharmony_ci NETMGR_LOG_E("route dest is empty."); 151b1b8bc3fSopenharmony_ci return ret; 152b1b8bc3fSopenharmony_ci } 153b1b8bc3fSopenharmony_ci 154b1b8bc3fSopenharmony_ci switch (op) { 155b1b8bc3fSopenharmony_ci case ROUTE_ADD: 156b1b8bc3fSopenharmony_ci ret = NetsysController::GetInstance().NetworkAddRoute(netId, route.iface_, dest, nextHop); 157b1b8bc3fSopenharmony_ci break; 158b1b8bc3fSopenharmony_ci case ROUTE_REMOVE: 159b1b8bc3fSopenharmony_ci ret = NetsysController::GetInstance().NetworkRemoveRoute(netId, route.iface_, dest, nextHop); 160b1b8bc3fSopenharmony_ci break; 161b1b8bc3fSopenharmony_ci default: 162b1b8bc3fSopenharmony_ci break; 163b1b8bc3fSopenharmony_ci } 164b1b8bc3fSopenharmony_ci 165b1b8bc3fSopenharmony_ci return ret; 166b1b8bc3fSopenharmony_ci} 167b1b8bc3fSopenharmony_ci 168b1b8bc3fSopenharmony_civoid RouteUtils::ToPrefixString(const std::string &src, int32_t prefixLen, std::string &dest) 169b1b8bc3fSopenharmony_ci{ 170b1b8bc3fSopenharmony_ci dest = MaskAddress(src, prefixLen); 171b1b8bc3fSopenharmony_ci NETMGR_LOG_D("ToPrefixString: src addr, src prefixlen[%{public}d], mask dest addr", prefixLen); 172b1b8bc3fSopenharmony_ci if (!dest.empty()) { 173b1b8bc3fSopenharmony_ci dest += "/"; 174b1b8bc3fSopenharmony_ci dest += std::to_string(prefixLen); 175b1b8bc3fSopenharmony_ci } 176b1b8bc3fSopenharmony_ci} 177b1b8bc3fSopenharmony_ci 178b1b8bc3fSopenharmony_cistd::string RouteUtils::MaskAddress(const std::string &addr, int32_t prefixLen) 179b1b8bc3fSopenharmony_ci{ 180b1b8bc3fSopenharmony_ci int32_t netScope = 0; 181b1b8bc3fSopenharmony_ci int32_t hostScope = 0; 182b1b8bc3fSopenharmony_ci uint8_t mask = 0; 183b1b8bc3fSopenharmony_ci uint8_t array[IPV6_UINT_LEN] = {0}; 184b1b8bc3fSopenharmony_ci char str[INET6_ADDRSTRLEN] = {0}; 185b1b8bc3fSopenharmony_ci int32_t af = prefixLen > IPV4_PRIFX_LEN ? AF_INET6 : AF_INET; 186b1b8bc3fSopenharmony_ci int32_t arrayLen = (af == AF_INET ? IPV4_UINT_LEN : IPV6_UINT_LEN); 187b1b8bc3fSopenharmony_ci 188b1b8bc3fSopenharmony_ci netScope = prefixLen / IP_PER_UINT_SIZE; 189b1b8bc3fSopenharmony_ci hostScope = prefixLen % IP_PER_UINT_SIZE; 190b1b8bc3fSopenharmony_ci mask = (uint8_t)(IP_PER_UINT_MASK << (IP_PER_UINT_SIZE - hostScope)); 191b1b8bc3fSopenharmony_ci 192b1b8bc3fSopenharmony_ci if (inet_pton(af, addr.c_str(), array) != 1) { 193b1b8bc3fSopenharmony_ci return std::string(""); 194b1b8bc3fSopenharmony_ci } 195b1b8bc3fSopenharmony_ci 196b1b8bc3fSopenharmony_ci if (netScope < arrayLen) { 197b1b8bc3fSopenharmony_ci array[netScope] = (uint8_t)(array[netScope] & mask); 198b1b8bc3fSopenharmony_ci } 199b1b8bc3fSopenharmony_ci 200b1b8bc3fSopenharmony_ci netScope++; 201b1b8bc3fSopenharmony_ci for (; netScope < arrayLen; netScope++) { 202b1b8bc3fSopenharmony_ci array[netScope] = 0; 203b1b8bc3fSopenharmony_ci } 204b1b8bc3fSopenharmony_ci 205b1b8bc3fSopenharmony_ci if (inet_ntop(af, array, str, INET6_ADDRSTRLEN) == nullptr) { 206b1b8bc3fSopenharmony_ci return std::string(""); 207b1b8bc3fSopenharmony_ci } 208b1b8bc3fSopenharmony_ci 209b1b8bc3fSopenharmony_ci return std::string(str); 210b1b8bc3fSopenharmony_ci} 211b1b8bc3fSopenharmony_ci} // namespace NetManagerStandard 212b1b8bc3fSopenharmony_ci} // namespace OHOS 213