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 #ifndef OHOS_ADDRESS_IPV6_H
17 #define OHOS_ADDRESS_IPV6_H
18 
19 #include <algorithm>
20 #include <arpa/inet.h>
21 #include <cstring>
22 #include <random>
23 #include "base_address.h"
24 #include "mac_address.h"
25 
26 namespace OHOS {
27 namespace Wifi {
28 class Ipv6Address : public BaseAddress {
29 public:
30     /**
31      * @Description  Check whether the IPv6 address is a legal IPv6 address.
32      *
33      * @param ipv6 - IPv6 address. [input]
34      * @return true - Yes    false - No.
35      */
36     static bool IsValidIPv6(const std::string &ipv6);
37     /**
38      * @Description  Check whether the IPv6 address is a local IPv6 address.
39      *
40      * @param ipv6 - IPv6 address. [input]
41      * @return true - Yes    false - No.
42      */
43     static bool IsAddrLocallink(const struct in6_addr &ip6Addr);
44     /**
45      * @Description  Obtains the prefix of a specified IPv6 address.
46      *
47      * @param ip6Addr - IPv6 address [input]
48      * @param prefixLength - Prefix Length [input]
49      * @return Parameter invalid, IN6ADDR_ANY_INIT is returned.
50                Otherwise, in6_addr is returned.
51      */
52     static struct in6_addr GetIpv6Prefix(struct in6_addr &ip6Addr, size_t prefixLength);
53     /**
54      * @Description  Obtains the IPv6 address mask with a specified prefix length.
55      *
56      * @param prefixLength - prefix length. [input]
57      * @return Parameter invalid, IN6ADDR_ANY_INIT is returned.
58                Otherwise, in6_addr is returned.
59      */
60     static struct in6_addr GetIpv6Mask(size_t prefixLength);
61 
62     /**
63      * @Description  Create an IPv6Address object based on the IPv6
64                      address with a prefix length.
65      *
66      * @param ipv6 - IPv6 abbreviation, string type such as fe80::0/64. [input]
67      * @return Parameter invalid, INVALID_INET6_ADDRESS is returned.
68                Otherwise, the successful object is returned.
69      */
70     static Ipv6Address Create(std::string ipv6);
71 
72     /**
73      * @Description  method of construct an IPv6, generate an EUI-64 address
74                      based on the input MAC address, and obtain the prefix
75                      address to generate an IPv6 address.
76      *
77      * @param ipv6Prefix - IPv6 prefix address [input]
78      * @param mac - MacAddress type of a MAC address [input]
79      * @param prefixLength - Prefix length. The default value is 64. [input]
80      * @return Parameter invalid, INVALID_INET6_ADDRESS is returned.
81                Otherwise, the successful object is returned.
82      */
83     static Ipv6Address Create(const std::string &ipv6Prefix, MacAddress &mac, const size_t prefixLength = 64);
84 
85     /**
86      * @Description  method of construct an IPv6, generate a random IPv6
87                      address in a random way.
88      *
89      * @param ipv6Prefix - IPv6 prefix address [input]
90      * @param prefixLength - prefix length [input]
91      * @param rndSeed - Random number seed. [input]
92      * @return Parameter invalid, INVALID_INET6_ADDRESS is returned.
93                Otherwise, the successful object is returned.
94      */
95     static Ipv6Address Create(const std::string &ipv6Prefix, const size_t prefixLength, unsigned int rndSeed);
96 
97     /**
98      * @Description  method of construct an IPv6, generate an IPv6 address
99                      based on input in6_addr structure.
100      *
101      * @param i6_addr - in6_addr structure of IPv6 [input]
102      * @param prefixLength - Prefix length. The default value is 128. [input]
103      * @return Parameter invalid, INVALID_INET6_ADDRESS is returned.
104                Otherwise, the successful object is returned.
105      */
106     static Ipv6Address Create(const struct in6_addr &i6Addr, const size_t prefixLength = 128);
107 
108     /**
109      * @Description  method of construct an IPv6.
110      *
111      * @param ipv6 - string of IPv6 address. [input]
112      * @param prefixLength - prefix length. [input]
113      * @return Parameter invalid, INVALID_INET6_ADDRESS is returned.
114                Otherwise, the successful object is returned.
115      */
116     static Ipv6Address Create(std::string ipv6, const size_t prefixLength);
117 
118     /**
119      * @Description  method of construct an IPv6.
120      *
121      * @param ipv6 - string of IPv6 address. [input]
122      * @param mask - string of Mask. [input]
123      * @return Parameter invalid, INVALID_INET6_ADDRESS is returned.
124                Otherwise, the successful object is returned.
125      */
126     static Ipv6Address Create(std::string ipv6, const std::string &mask);
127 
128 public:
129     static const Ipv6Address INVALID_INET6_ADDRESS; /* Invalid IPv6 object constant. */
130 
131 public:
132     /**
133      * @Description  Supports default destructor methods.
134      *
135      * @param None
136      * @return None
137      */
138     virtual ~Ipv6Address() = default;
139 
140     /**
141      * @Description  Check whether the current IP address is valid.
142      *
143      * @param None
144      * @return true - legal       false - illegal
145      */
146     bool IsValid() const override;
147 
148     /**
149      * @Description  obtain the IPv6 address in the in6_addr format.
150      *
151      * @param None
152      * @return in6_addr structure
153      */
154     struct in6_addr GetIn6Addr() const;
155 
156     /**
157      * @Description  obtain the IPv6 address prefix in character format.
158      *
159      * @param None
160      * @return string of theIPv6 address prefix.
161      */
162     std::string GetPrefix() const;
163 
164     /**
165      * @Description  obtain the IPv6 address prefix in character format.
166      *
167      * @param None
168      * @return string of theIPv6 address prefix.
169      */
170     static std::string GetPrefixByAddr(const std::string &ipv6Addr, unsigned int prefixLen);
171 
172     /**
173      * @Description  Obtain the description of the network where the
174                      current IP address is located, for example,
175                      fe80:1234::1/10.
176      *
177      * @param None
178      * @return string of network.
179      */
180     std::string GetNetwork() const;
181 
182 private:
183     /**
184      * @Description  Construction method.
185      *
186      * @param ipv6 - string of ipv6 address [input]
187      * @param prefixLength - prefix length [input]
188      * @return Ipv6Address object
189      */
190     Ipv6Address(const std::string &ipv6, const size_t prefixLength);
191     /**
192      * @Description  Generates random IPv6 addresses based on prefixes.
193      *
194      * @param ipv6Prefix - prefix of IPv6 [input]
195      * @param prefixLength - prefix length [input]
196      * @return string of random IPv6 address
197      */
198     static std::string GetRandomAddr(const std::string &ipv6Prefix, int prefixLength);
199     /**
200      * @Description  Converts four binary strings to a hexadecimal string.
201      *
202      * @param strBin - four binary strings [input]
203      * @return a hexadecimal string
204      */
205     static std::string BinToHex(const std::string &strBin);
206     /**
207      * @Description  Converts a hexadecimal string to four binary strings.
208      *
209      * @param strHex - a hexadecimal string [input]
210      * @return four binary strings
211      */
212     static std::string HexToBin(const std::string &strHex);
213     /**
214      * @Description  generating EUI-64 addresses based on MAC addresses.
215      *
216      * @param mac - MacAddress of a MAC address [input]
217      * @return string of EUI-64 address
218      */
219     static std::string MacToEui64addr(MacAddress &mac);
220 };
221 }  // namespace Wifi
222 }  // namespace OHOS
223 
224 #endif /* OHOS_ADDRESS_IPV6_H */