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