blob: cc15d3d8242b9be915b7e44abe52e21789d566e4 [file] [log] [blame]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net-base/ipv4_address.h"
#include <algorithm>
#include <arpa/inet.h>
#include <base/check.h>
#include <base/sys_byteorder.h>
namespace net_base {
// static
std::optional<IPv4Address> IPv4Address::CreateFromString(
const std::string& address_string) {
return CreateFromString(address_string.c_str());
}
// static
std::optional<IPv4Address> IPv4Address::CreateFromString(
const char* address_string) {
DataType data;
if (inet_pton(AF_INET, address_string, data.data()) <= 0) {
return std::nullopt;
}
return IPv4Address(data);
}
// static
std::optional<IPv4Address> IPv4Address::CreateFromBytes(
base::span<const char> bytes) {
return CreateFromBytes(base::span<const uint8_t>(
reinterpret_cast<const uint8_t*>(bytes.data()), bytes.size()));
}
// static
std::optional<IPv4Address> IPv4Address::CreateFromBytes(
base::span<const uint8_t> bytes) {
return CreateAddressFromBytes<IPv4Address>(bytes);
}
IPv4Address::IPv4Address(const struct in_addr& addr)
: IPv4Address(addr.s_addr) {}
IPv4Address::IPv4Address(uint32_t addr) {
const uint32_t host_endian = base::NetToHost32(addr);
data_[0] = static_cast<uint8_t>((host_endian >> 24) & 0xff);
data_[1] = static_cast<uint8_t>((host_endian >> 16) & 0xff);
data_[2] = static_cast<uint8_t>((host_endian >> 8) & 0xff);
data_[3] = static_cast<uint8_t>(host_endian & 0xff);
}
bool IPv4Address::IsZero() const {
return std::all_of(data_.begin(), data_.end(),
[](uint8_t byte) { return byte == 0; });
}
bool IPv4Address::operator==(const IPv4Address& rhs) const {
return data_ == rhs.data_;
}
bool IPv4Address::operator!=(const IPv4Address& rhs) const {
return !(*this == rhs);
}
bool IPv4Address::operator<(const IPv4Address& rhs) const {
return data_ < rhs.data_;
}
std::vector<uint8_t> IPv4Address::ToBytes() const {
return {std::begin(data_), std::end(data_)};
}
std::string IPv4Address::ToByteString() const {
return {reinterpret_cast<const char*>(data_.data()), kAddressLength};
}
std::string IPv4Address::ToString() const {
char address_buf[INET_ADDRSTRLEN];
const char* res =
inet_ntop(AF_INET, data_.data(), address_buf, sizeof(address_buf));
DCHECK(res);
return std::string(address_buf);
}
struct in_addr IPv4Address::ToInAddr() const {
const uint32_t host_endian = (static_cast<uint32_t>(data_[0]) << 24) |
(static_cast<uint32_t>(data_[1]) << 16) |
(static_cast<uint32_t>(data_[2]) << 8) |
static_cast<uint32_t>(data_[3]);
struct in_addr ret;
ret.s_addr = htonl(host_endian);
return ret;
}
std::ostream& operator<<(std::ostream& os, const IPv4Address& address) {
os << address.ToString();
return os;
}
} // namespace net_base