File indexing completed on 2025-01-30 10:03:46
0001
0002
0003
0004
0005 #ifndef CPPCORO_NET_IPV6_ADDRESS_HPP_INCLUDED
0006 #define CPPCORO_NET_IPV6_ADDRESS_HPP_INCLUDED
0007
0008 #include <cstdint>
0009 #include <optional>
0010 #include <string>
0011 #include <string_view>
0012
0013 namespace cppcoro::net
0014 {
0015 class ipv4_address;
0016
0017 class ipv6_address
0018 {
0019 using bytes_t = std::uint8_t[16];
0020
0021 public:
0022
0023 constexpr ipv6_address();
0024
0025 explicit constexpr ipv6_address(
0026 std::uint64_t subnetPrefix,
0027 std::uint64_t interfaceIdentifier);
0028
0029 constexpr ipv6_address(
0030 std::uint16_t part0,
0031 std::uint16_t part1,
0032 std::uint16_t part2,
0033 std::uint16_t part3,
0034 std::uint16_t part4,
0035 std::uint16_t part5,
0036 std::uint16_t part6,
0037 std::uint16_t part7);
0038
0039 explicit constexpr ipv6_address(
0040 const std::uint16_t(&parts)[8]);
0041
0042 explicit constexpr ipv6_address(
0043 const std::uint8_t(&bytes)[16]);
0044
0045 constexpr const bytes_t& bytes() const { return m_bytes; }
0046
0047 constexpr std::uint64_t subnet_prefix() const;
0048
0049 constexpr std::uint64_t interface_identifier() const;
0050
0051
0052 static constexpr ipv6_address unspecified();
0053
0054
0055 static constexpr ipv6_address loopback();
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 static std::optional<ipv6_address> from_string(std::string_view string) noexcept;
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 std::string to_string() const;
0083
0084 constexpr bool operator==(const ipv6_address& other) const;
0085 constexpr bool operator!=(const ipv6_address& other) const;
0086 constexpr bool operator<(const ipv6_address& other) const;
0087 constexpr bool operator>(const ipv6_address& other) const;
0088 constexpr bool operator<=(const ipv6_address& other) const;
0089 constexpr bool operator>=(const ipv6_address& other) const;
0090
0091 private:
0092
0093 alignas(std::uint64_t) std::uint8_t m_bytes[16];
0094
0095 };
0096
0097 constexpr ipv6_address::ipv6_address()
0098 : m_bytes{
0099 0, 0, 0, 0, 0, 0, 0, 0,
0100 0, 0, 0, 0, 0, 0, 0, 0 }
0101 {}
0102
0103 constexpr ipv6_address::ipv6_address(
0104 std::uint64_t subnetPrefix,
0105 std::uint64_t interfaceIdentifier)
0106 : m_bytes{
0107 static_cast<std::uint8_t>(subnetPrefix >> 56),
0108 static_cast<std::uint8_t>(subnetPrefix >> 48),
0109 static_cast<std::uint8_t>(subnetPrefix >> 40),
0110 static_cast<std::uint8_t>(subnetPrefix >> 32),
0111 static_cast<std::uint8_t>(subnetPrefix >> 24),
0112 static_cast<std::uint8_t>(subnetPrefix >> 16),
0113 static_cast<std::uint8_t>(subnetPrefix >> 8),
0114 static_cast<std::uint8_t>(subnetPrefix),
0115 static_cast<std::uint8_t>(interfaceIdentifier >> 56),
0116 static_cast<std::uint8_t>(interfaceIdentifier >> 48),
0117 static_cast<std::uint8_t>(interfaceIdentifier >> 40),
0118 static_cast<std::uint8_t>(interfaceIdentifier >> 32),
0119 static_cast<std::uint8_t>(interfaceIdentifier >> 24),
0120 static_cast<std::uint8_t>(interfaceIdentifier >> 16),
0121 static_cast<std::uint8_t>(interfaceIdentifier >> 8),
0122 static_cast<std::uint8_t>(interfaceIdentifier) }
0123 {}
0124
0125 constexpr ipv6_address::ipv6_address(
0126 std::uint16_t part0,
0127 std::uint16_t part1,
0128 std::uint16_t part2,
0129 std::uint16_t part3,
0130 std::uint16_t part4,
0131 std::uint16_t part5,
0132 std::uint16_t part6,
0133 std::uint16_t part7)
0134 : m_bytes{
0135 static_cast<std::uint8_t>(part0 >> 8),
0136 static_cast<std::uint8_t>(part0),
0137 static_cast<std::uint8_t>(part1 >> 8),
0138 static_cast<std::uint8_t>(part1),
0139 static_cast<std::uint8_t>(part2 >> 8),
0140 static_cast<std::uint8_t>(part2),
0141 static_cast<std::uint8_t>(part3 >> 8),
0142 static_cast<std::uint8_t>(part3),
0143 static_cast<std::uint8_t>(part4 >> 8),
0144 static_cast<std::uint8_t>(part4),
0145 static_cast<std::uint8_t>(part5 >> 8),
0146 static_cast<std::uint8_t>(part5),
0147 static_cast<std::uint8_t>(part6 >> 8),
0148 static_cast<std::uint8_t>(part6),
0149 static_cast<std::uint8_t>(part7 >> 8),
0150 static_cast<std::uint8_t>(part7) }
0151 {}
0152
0153 constexpr ipv6_address::ipv6_address(
0154 const std::uint16_t(&parts)[8])
0155 : ipv6_address(
0156 parts[0], parts[1], parts[2], parts[3],
0157 parts[4], parts[5], parts[6], parts[7])
0158 {}
0159
0160 constexpr ipv6_address::ipv6_address(const std::uint8_t(&bytes)[16])
0161 : m_bytes{
0162 bytes[0], bytes[1], bytes[2], bytes[3],
0163 bytes[4], bytes[5], bytes[6], bytes[7],
0164 bytes[8], bytes[9], bytes[10], bytes[11],
0165 bytes[12], bytes[13], bytes[14], bytes[15] }
0166 {}
0167
0168 constexpr std::uint64_t ipv6_address::subnet_prefix() const
0169 {
0170 return
0171 static_cast<std::uint64_t>(m_bytes[0]) << 56 |
0172 static_cast<std::uint64_t>(m_bytes[1]) << 48 |
0173 static_cast<std::uint64_t>(m_bytes[2]) << 40 |
0174 static_cast<std::uint64_t>(m_bytes[3]) << 32 |
0175 static_cast<std::uint64_t>(m_bytes[4]) << 24 |
0176 static_cast<std::uint64_t>(m_bytes[5]) << 16 |
0177 static_cast<std::uint64_t>(m_bytes[6]) << 8 |
0178 static_cast<std::uint64_t>(m_bytes[7]);
0179 }
0180
0181 constexpr std::uint64_t ipv6_address::interface_identifier() const
0182 {
0183 return
0184 static_cast<std::uint64_t>(m_bytes[8]) << 56 |
0185 static_cast<std::uint64_t>(m_bytes[9]) << 48 |
0186 static_cast<std::uint64_t>(m_bytes[10]) << 40 |
0187 static_cast<std::uint64_t>(m_bytes[11]) << 32 |
0188 static_cast<std::uint64_t>(m_bytes[12]) << 24 |
0189 static_cast<std::uint64_t>(m_bytes[13]) << 16 |
0190 static_cast<std::uint64_t>(m_bytes[14]) << 8 |
0191 static_cast<std::uint64_t>(m_bytes[15]);
0192 }
0193
0194 constexpr ipv6_address ipv6_address::unspecified()
0195 {
0196 return ipv6_address{};
0197 }
0198
0199 constexpr ipv6_address ipv6_address::loopback()
0200 {
0201 return ipv6_address{ 0, 0, 0, 0, 0, 0, 0, 1 };
0202 }
0203
0204 constexpr bool ipv6_address::operator==(const ipv6_address& other) const
0205 {
0206 for (int i = 0; i < 16; ++i)
0207 {
0208 if (m_bytes[i] != other.m_bytes[i]) return false;
0209 }
0210 return true;
0211 }
0212
0213 constexpr bool ipv6_address::operator!=(const ipv6_address& other) const
0214 {
0215 return !(*this == other);
0216 }
0217
0218 constexpr bool ipv6_address::operator<(const ipv6_address& other) const
0219 {
0220 for (int i = 0; i < 16; ++i)
0221 {
0222 if (m_bytes[i] != other.m_bytes[i])
0223 return m_bytes[i] < other.m_bytes[i];
0224 }
0225
0226 return false;
0227 }
0228
0229 constexpr bool ipv6_address::operator>(const ipv6_address& other) const
0230 {
0231 return (other < *this);
0232 }
0233
0234 constexpr bool ipv6_address::operator<=(const ipv6_address& other) const
0235 {
0236 return !(other < *this);
0237 }
0238
0239 constexpr bool ipv6_address::operator>=(const ipv6_address& other) const
0240 {
0241 return !(*this < other);
0242 }
0243 }
0244
0245 #endif