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 : int64_t { 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  bool operator<(const Address& other) const {
89  return std::tie(_a1, _a2, _family) < std::tie(other._a1, other._a2, other._family);
90  };
91 
98  operator std::string() const;
99 
100  Bytes pack(ByteOrder fmt) const;
101 
102 private:
103  void _init(struct in_addr addr);
104  void _init(struct in6_addr addr);
105 
106  // Throws ``InvalidArgument`` if it cannot parse the address.
107  void _parse(const std::string& addr);
108 
109  uint64_t _a1 = 0; // The 8 more significant bytes.
110  uint64_t _a2 = 0; // The 8 less significant bytes.
111 
112  AddressFamily _family = AddressFamily::Undef;
113 };
114 
115 namespace address {
117 inline Bytes pack(const Address& addr, ByteOrder fmt) { return addr.pack(fmt); }
118 
120 extern Result<std::tuple<Address, Bytes>> unpack(const Bytes& data, AddressFamily family, ByteOrder fmt);
121 
123 extern Result<std::tuple<Address, stream::View>> unpack(const stream::View& data, AddressFamily family, ByteOrder fmt);
124 
132 inline Address parse(const Bytes& data) { return Address(data.str()); }
133 
141 inline Address parse(const std::string& data) { return Address(data); }
142 
143 } // namespace address
144 
145 namespace detail::adl {
146 extern std::string to_string(const AddressFamily& x, adl::tag /*unused*/);
147 inline std::string to_string(const Address& x, adl::tag /*unused*/) { return x; }
148 } // namespace detail::adl
149 
150 inline std::ostream& operator<<(std::ostream& out, const Address& x) {
151  out << to_string(x);
152  return out;
153 }
154 
155 inline std::ostream& operator<<(std::ostream& out, const AddressFamily& family) { return out << to_string(family); }
156 
157 } // namespace hilti::rt
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:157
Address(uint64_t addr6a, uint64_t addr6b, AddressFamily family=AddressFamily::IPv6)
Definition: address.h:56
Definition: stream.h:1001
ByteOrder
Definition: util.h:503
const std::string & str() const &
Definition: bytes.h:223
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