1 /*
2 * Copyright (C) 2025 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 #include <securec.h>
16 #include "dhcp_ipv6_define.h"
17 #include "dhcp_ipv6_info.h"
18 #include "dhcp_logger.h"
19 namespace OHOS {
20 namespace DHCP {
21 DEFINE_DHCPLOG_DHCP_LABEL("DhcpIpv6InfoManager");
22
AddRoute(DhcpIpv6Info & dhcpIpv6Info,std::string defaultRouteAddr)23 bool DhcpIpv6InfoManager::AddRoute(DhcpIpv6Info &dhcpIpv6Info, std::string defaultRouteAddr)
24 {
25 if (std::find(dhcpIpv6Info.defaultRouteAddr.begin(), dhcpIpv6Info.defaultRouteAddr.end(), defaultRouteAddr) !=
26 dhcpIpv6Info.defaultRouteAddr.end()) {
27 return false;
28 }
29 DHCP_LOGI("AddRoute addr %{private}s", defaultRouteAddr.c_str());
30 dhcpIpv6Info.defaultRouteAddr.push_back(defaultRouteAddr);
31 if (memset_s(dhcpIpv6Info.routeAddr, DHCP_INET6_ADDRSTRLEN, 0, DHCP_INET6_ADDRSTRLEN) != EOK) {
32 DHCP_LOGE("AddRoute memset_s failed");
33 return false;
34 }
35 for (auto route : dhcpIpv6Info.defaultRouteAddr) {
36 if (memcpy_s(dhcpIpv6Info.routeAddr, DHCP_INET6_ADDRSTRLEN, route.c_str(), route.length() + 1) == EOK) {
37 return true;
38 }
39 }
40 return false;
41 }
42
RemoveRoute(DhcpIpv6Info & dhcpIpv6Info,std::string defaultRoute)43 bool DhcpIpv6InfoManager::RemoveRoute(DhcpIpv6Info &dhcpIpv6Info, std::string defaultRoute)
44 {
45 if (memset_s(dhcpIpv6Info.routeAddr, DHCP_INET6_ADDRSTRLEN, 0, DHCP_INET6_ADDRSTRLEN) != EOK) {
46 return false;
47 }
48 DHCP_LOGI("RemoveRoute addr %{private}s", defaultRoute.c_str());
49 if (dhcpIpv6Info.defaultRouteAddr.size() == 0) {
50 DHCP_LOGI("RemoveRoute empty list");
51 return false;
52 }
53 bool isChanged = false;
54 for (int i = static_cast<int>(dhcpIpv6Info.defaultRouteAddr.size()) - 1; i >=0 ; i--) {
55 if (dhcpIpv6Info.defaultRouteAddr[i] == defaultRoute) {
56 dhcpIpv6Info.defaultRouteAddr.erase(dhcpIpv6Info.defaultRouteAddr.begin() + i);
57 isChanged = true;
58 }
59 }
60 for (auto route : dhcpIpv6Info.defaultRouteAddr) {
61 if (memcpy_s(dhcpIpv6Info.routeAddr, DHCP_INET6_ADDRSTRLEN, route.c_str(), route.length() + 1) == EOK) {
62 return true;
63 }
64 }
65 return isChanged;
66 }
67
UpdateAddress(char * dest,const std::string & addr,AddrType type)68 static bool UpdateAddress(char *dest, const std::string &addr, AddrType type)
69 {
70 if (memset_s(dest, DHCP_INET6_ADDRSTRLEN, 0, DHCP_INET6_ADDRSTRLEN) != EOK) {
71 DHCP_LOGE("UpdateAddr memset_s failed for type %{public}d", static_cast<int>(type));
72 return false;
73 }
74 if (memcpy_s(dest, DHCP_INET6_ADDRSTRLEN, addr.c_str(), addr.length() + 1) != EOK) {
75 DHCP_LOGE("UpdateAddr memcpy_s failed for type %{public}d", static_cast<int>(type));
76 return false;
77 }
78 return true;
79 }
80
UpdateAddrInline(DhcpIpv6Info & dhcpIpv6Info,std::string addr,AddrType type)81 inline bool UpdateAddrInline(DhcpIpv6Info &dhcpIpv6Info, std::string addr, AddrType type)
82 {
83 switch (type) {
84 case AddrType::DEFAULT: return UpdateAddress(dhcpIpv6Info.linkIpv6Addr, addr, type);
85 case AddrType::GLOBAL: return UpdateAddress(dhcpIpv6Info.globalIpv6Addr, addr, type);
86 case AddrType::RAND: return UpdateAddress(dhcpIpv6Info.randIpv6Addr, addr, type);
87 case AddrType::UNIQUE: return UpdateAddress(dhcpIpv6Info.uniqueLocalAddr1, addr, type);
88 case AddrType::UNIQUE2: return UpdateAddress(dhcpIpv6Info.uniqueLocalAddr2, addr, type);
89 default: return false;
90 }
91 }
92
UpdateAddr(DhcpIpv6Info & dhcpIpv6Info,std::string addr,AddrType type)93 bool DhcpIpv6InfoManager::UpdateAddr(DhcpIpv6Info &dhcpIpv6Info, std::string addr, AddrType type)
94 {
95 if (addr.length() == 0 || addr.length() > DHCP_INET6_ADDRSTRLEN) {
96 DHCP_LOGE("UpdateAddr invalid addr");
97 return false;
98 }
99 bool existingKey = (dhcpIpv6Info.IpAddrMap.find(addr) != dhcpIpv6Info.IpAddrMap.end());
100 if (existingKey && dhcpIpv6Info.IpAddrMap[addr] == static_cast<int>(type)) {
101 DHCP_LOGI("UpdateAddr existing addr");
102 return false;
103 }
104 if (existingKey) {
105 DhcpIpv6InfoManager::RemoveAddr(dhcpIpv6Info, addr);
106 }
107 dhcpIpv6Info.IpAddrMap.insert({addr, static_cast<int>(type)});
108 if (!UpdateAddrInline(dhcpIpv6Info, addr, type)) {
109 DHCP_LOGE("UpdateAddr failed %{public}d", static_cast<int>(type));
110 return false;
111 }
112 DHCP_LOGI("UpdateAddr addr %{private}s, type %{public}d", addr.c_str(), static_cast<int>(type));
113 return true;
114 }
115
ClearAddress(char * addr,AddrType type)116 static bool ClearAddress(char *addr, AddrType type)
117 {
118 if (memset_s(addr, DHCP_INET6_ADDRSTRLEN, 0, DHCP_INET6_ADDRSTRLEN) != EOK) {
119 DHCP_LOGE("RemoveAddr memset_s failed %{public}d", static_cast<int>(type));
120 return false;
121 }
122 return true;
123 }
124
RemoveAddrInline(DhcpIpv6Info & dhcpIpv6Info,AddrType type)125 inline bool RemoveAddrInline(DhcpIpv6Info &dhcpIpv6Info, AddrType type)
126 {
127 switch (type) {
128 case AddrType::DEFAULT: return ClearAddress(dhcpIpv6Info.linkIpv6Addr, type);
129 case AddrType::GLOBAL: return ClearAddress(dhcpIpv6Info.globalIpv6Addr, type);
130 case AddrType::RAND: return ClearAddress(dhcpIpv6Info.randIpv6Addr, type);
131 case AddrType::UNIQUE: return ClearAddress(dhcpIpv6Info.uniqueLocalAddr1, type);
132 case AddrType::UNIQUE2: return ClearAddress(dhcpIpv6Info.uniqueLocalAddr2, type);
133 default: return false;
134 }
135 }
136
RemoveAddr(DhcpIpv6Info & dhcpIpv6Info,std::string addr)137 bool DhcpIpv6InfoManager::RemoveAddr(DhcpIpv6Info &dhcpIpv6Info, std::string addr)
138 {
139 if (addr.length() == 0 || addr.length() > DHCP_INET6_ADDRSTRLEN) {
140 DHCP_LOGE("RemoveAddr invalid addr");
141 return false;
142 }
143 DHCP_LOGI("RemoveAddr addr %{private}s", addr.c_str());
144 if (dhcpIpv6Info.IpAddrMap.find(addr) == dhcpIpv6Info.IpAddrMap.end()) {
145 DHCP_LOGI("RemoveAddr unexisting addr");
146 return false;
147 }
148 AddrType type = static_cast<AddrType>(dhcpIpv6Info.IpAddrMap[addr]);
149 dhcpIpv6Info.IpAddrMap.erase(addr);
150 return RemoveAddrInline(dhcpIpv6Info, type);
151 }
152 }
153 }