1 /*
2  * Copyright (C) 2021-2022 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 "ipv4_address.h"
17 #include <cstdio>
18 #include <string>
19 #include <arpa/inet.h>
20 #include <sys/socket.h>
21 #include "wifi_log.h"
22 
23 #undef LOG_TAG
24 #define LOG_TAG "OHWIFI_UTIL_Ipv4Address"
25 
26 namespace OHOS {
27 namespace Wifi {
28 const int MAX_IPV4_PREFIX_LENGTH = 32;
29 const int MAX_IPV4_STRING_LENGTH = 64;
30 const Ipv4Address Ipv4Address::invalidInetAddress("255.255.255.255", MAX_IPV4_PREFIX_LENGTH);
31 const Ipv4Address Ipv4Address::defaultInetAddress("192.168.49.1", MAX_IPV4_PREFIX_LENGTH);
IsValidIPv4(const std::string & ipv4)32 bool Ipv4Address::IsValidIPv4(const std::string &ipv4)
33 {
34     struct in_addr ipv4Addr = {INADDR_ANY};
35     if (inet_pton(AF_INET, ipv4.c_str(), static_cast<void*>(&ipv4Addr)) != 1 ||
36         ipv4 == invalidInetAddress.GetAddressWithString()) {
37         return false;
38     } else {
39         return true;
40     }
41 }
42 
Create(const std::string & ipv4,size_t prefixLength)43 Ipv4Address Ipv4Address::Create(const std::string &ipv4, size_t prefixLength)
44 {
45     if (!IsValidIPv4(ipv4) || prefixLength > MAX_IPV4_PREFIX_LENGTH - 1) {
46         return invalidInetAddress;
47     }
48     return Ipv4Address(ipv4, prefixLength);
49 }
50 
Create(const std::string & ipv4,const std::string & mask)51 Ipv4Address Ipv4Address::Create(const std::string &ipv4, const std::string &mask)
52 {
53     size_t prefixLength = 0;
54     struct in_addr maskAddr = {INADDR_ANY};
55     if ((inet_aton(mask.c_str(), &maskAddr) != 1) || (!IsValidIPv4(ipv4))) {
56         return invalidInetAddress;
57     }
58     for (int i = 0; i < MAX_MASK_LENGTH; i++) {
59         if (maskAddr.s_addr != 0) {
60             maskAddr.s_addr = maskAddr.s_addr >> 1;
61             ++prefixLength;
62         }
63     }
64     return Ipv4Address(ipv4, prefixLength);
65 }
66 
Create(const in_addr & ipv4,const in_addr & mask)67 Ipv4Address Ipv4Address::Create(const in_addr &ipv4, const in_addr &mask)
68 {
69     size_t prefixLength = 0;
70     struct in_addr maskAddr = mask;
71     for (int i = 0; i < MAX_MASK_LENGTH; i++) {
72         if (maskAddr.s_addr != 0) {
73             maskAddr.s_addr = maskAddr.s_addr >> 1;
74             ++prefixLength;
75         }
76     }
77     char ipStr[MAX_IPV4_STRING_LENGTH] = {0};
78     if (inet_ntop(AF_INET, &ipv4, ipStr, sizeof(ipStr)) == nullptr) {
79         return invalidInetAddress;
80     }
81     return Ipv4Address(ipStr, prefixLength);
82 }
83 
Ipv4Address(const std::string & ipv4,size_t prefixLength)84 Ipv4Address::Ipv4Address(const std::string &ipv4, size_t prefixLength)
85     : BaseAddress(ipv4, prefixLength, FamilyType::FAMILY_INET)
86 {}
87 
IsValid() const88 bool Ipv4Address::IsValid() const
89 {
90     return IsValidIPv4(GetAddressWithString());
91 }
92 
GetAddressWithInet() const93 in_addr Ipv4Address::GetAddressWithInet() const
94 {
95     struct in_addr ipv4Addr = {INADDR_ANY};
96     if (inet_aton(GetAddressWithString().c_str(), &ipv4Addr) == 0) {
97         LOGI("inet_aton error");
98     }
99     return ipv4Addr;
100 }
101 
GetMaskWithString() const102 std::string Ipv4Address::GetMaskWithString() const
103 {
104     char ipStr[MAX_IPV4_STRING_LENGTH] = {0};
105     in_addr ipAddr = GetMaskWithInet();
106     if (inet_ntop(AF_INET, &ipAddr, ipStr, sizeof(ipStr)) == nullptr) {
107         return "";
108     }
109     return std::string(ipStr);
110 }
111 
GetMaskWithInet() const112 in_addr Ipv4Address::GetMaskWithInet() const
113 {
114     struct in_addr mask4Addr = {INADDR_ANY};
115     size_t num = GetAddressPrefixLength();
116     size_t i = 0xffffffff;
117     i = i >> (MAX_MASK_LENGTH - num);
118     mask4Addr.s_addr = i;
119     return mask4Addr;
120 }
121 
GetNetworkAddressWithString() const122 std::string Ipv4Address::GetNetworkAddressWithString() const
123 {
124     char ipStr[MAX_IPV4_STRING_LENGTH] = {0};
125     in_addr ipAddr = GetNetworkAddressWithInet();
126     if (inet_ntop(AF_INET, &ipAddr, ipStr, sizeof(ipStr)) == nullptr) {
127         return "";
128     }
129     return std::string(ipStr);
130 }
131 
GetNetworkAddressWithInet() const132 in_addr Ipv4Address::GetNetworkAddressWithInet() const
133 {
134     struct in_addr networkAddress = {INADDR_ANY};
135     networkAddress.s_addr = GetMaskWithInet().s_addr & GetAddressWithInet().s_addr;
136     return networkAddress;
137 }
138 
GetHostAddressWithString() const139 std::string Ipv4Address::GetHostAddressWithString() const
140 {
141     char ipStr[MAX_IPV4_STRING_LENGTH] = {0};
142     in_addr ipAddr = GetHostAddressWithInet();
143     if (inet_ntop(AF_INET, &ipAddr, ipStr, sizeof(ipStr)) == nullptr) {
144         return "";
145     }
146     return std::string(ipStr);
147 }
148 
GetHostAddressWithInet() const149 in_addr Ipv4Address::GetHostAddressWithInet() const
150 {
151     struct in_addr hostAddress = {INADDR_ANY};
152     hostAddress.s_addr = (~(GetMaskWithInet().s_addr)) & GetAddressWithInet().s_addr;
153     return hostAddress;
154 }
155 
GetNetwork() const156 std::string Ipv4Address::GetNetwork() const
157 {
158     std::string network = GetAddressWithString() + "/" + std::to_string(GetAddressPrefixLength());
159     return network;
160 }
161 }  // namespace Wifi
162 }  // namespace OHOS
163