Spicy
address.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 
8 #include <string>
9 #include <tuple>
10 
11 #include <hilti/rt/extension-points.h>
12 #include <hilti/rt/result.h>
13 #include <hilti/rt/types/bytes.h>
14 #include <hilti/rt/types/stream.h>
15 
16 namespace hilti::rt {
17 
18 enum class AddressFamily { Undef, IPv4, IPv6 };
19 
24 class Address {
25 public:
33  explicit Address(const std::string& addr) { _parse(addr); }
34 
36  explicit Address(struct in_addr addr4) { _init(addr4); }
37 
41  explicit Address(struct in6_addr addr6) { _init(addr6); }
42 
48  explicit Address(uint32_t addr4) : Address(0, addr4, AddressFamily::IPv4) {} // addr4 in host byte order
49 
56  explicit Address(uint64_t addr6a, uint64_t addr6b, AddressFamily family = AddressFamily::IPv6)
57  : _a1(addr6a), _a2(addr6b), _family(family) {}
58 
59  Address() noexcept = default;
60  Address(const Address&) = default;
61  Address(Address&&) noexcept = default;
62  ~Address() = default;
63 
64  Address& operator=(const Address&) = default;
65  Address& operator=(Address&&) noexcept = default;
66 
71  AddressFamily family() const;
72 
78  Address mask(unsigned int width) const;
79 
84  std::variant<struct in_addr, struct in6_addr> asInAddr() const;
85 
86  bool operator==(const Address& other) const;
87  bool operator!=(const Address& other) const { return ! (*this == other); }
88 
95  operator std::string() const;
96 
97 private:
98  void _init(struct in_addr addr);
99  void _init(struct in6_addr addr);
100 
101  // Throws RuntimeError if it cannot parse the address.
102  void _parse(const std::string& addr);
103 
104  uint64_t _a1 = 0; // The 8 more significant bytes.
105  uint64_t _a2 = 0; // The 8 less significant bytes.
106 
107  AddressFamily _family = AddressFamily::Undef;
108 };
109 
110 namespace address {
112 extern Result<std::tuple<Address, Bytes>> unpack(const Bytes& data, AddressFamily family, ByteOrder fmt);
113 
115 extern Result<std::tuple<Address, stream::View>> unpack(const stream::View& data, AddressFamily family, ByteOrder fmt);
116 
117 } // namespace address
118 
119 namespace detail::adl {
120 extern std::string to_string(const AddressFamily& x, adl::tag /*unused*/);
121 inline std::string to_string(const Address& x, adl::tag /*unused*/) { return x; }
122 } // namespace detail::adl
123 
124 inline std::ostream& operator<<(std::ostream& out, const Address& x) {
125  out << to_string(x);
126  return out;
127 }
128 
129 inline std::ostream& operator<<(std::ostream& out, const AddressFamily& family) { return out << to_string(family); }
130 
131 } // namespace hilti::rt
ByteOrder
Definition: util.h:515
std::string to_string(T &&x)
Definition: extension-points.h:26
Definition: any.h:7
Address(uint32_t addr4)
Definition: address.h:48
Address(struct in_addr addr4)
Definition: address.h:36
Definition: bytes.h:153
Address(uint64_t addr6a, uint64_t addr6b, AddressFamily family=AddressFamily::IPv6)
Definition: address.h:56
Definition: stream.h:978
Address(struct in6_addr addr6)
Definition: address.h:41
Definition: address.h:24
Address(const std::string &addr)
Definition: address.h:33
Definition: result.h:67
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13