OpenVPN 3 Core Library
Loading...
Searching...
No Matches
addrpair.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#ifndef OPENVPN_ADDR_ADDRPAIR_H
13#define OPENVPN_ADDR_ADDRPAIR_H
14
15#include <sstream>
16
20#include <openvpn/addr/ip.hpp>
21
22namespace openvpn::IP {
23
24// AddrMaskPair is basically an object that combines an IP address (v4 or v6)
25// with a netmask or prefix length.
27{
28 public:
29 OPENVPN_EXCEPTION(addr_pair_mask_parse_error);
30
32 {
33 public:
34 OPENVPN_SIMPLE_EXCEPTION(addr_pair_string_error);
35
37 : size_(0)
38 {
39 }
40
41 explicit StringPair(const std::string &s1)
42 : size_(1)
43 {
44 data[0] = s1;
45 }
46
47 explicit StringPair(const std::string &s1, const std::string &s2)
48 : size_(2)
49 {
50 data[0] = s1;
51 data[1] = s2;
52 }
53
54 void push_back(const std::string &s)
55 {
56 if (size_ < 2)
57 data[size_++] = s;
58 else
59 throw addr_pair_string_error();
60 }
61
62 const std::string &operator[](const size_t i) const
63 {
64 if (i >= 2)
65 throw addr_pair_string_error();
66 return data[i];
67 }
68
69 std::string &operator[](const size_t i)
70 {
71 if (i >= 2)
72 throw addr_pair_string_error();
73 return data[i];
74 }
75
76 size_t size() const
77 {
78 return size_;
79 }
80
81 std::string render() const
82 {
83 switch (size_)
84 {
85 case 1:
86 return data[0];
87 case 2:
88 return data[0] + "/" + data[1];
89 default:
90 return "";
91 }
92 }
93
94 private:
95 std::string data[2];
96 unsigned int size_;
97 };
98
99 static AddrMaskPair from_string(const std::string &s1, const std::string &s2, const char *title = nullptr)
100 {
101 try
102 {
103 if (s2.empty())
104 {
105 const StringPair pair = Split::by_char<StringPair, NullLex, Split::NullLimit>(s1, '/');
106 return from_string_impl(pair, title);
107 }
108
109 const StringPair pair(s1, s2);
110 return from_string_impl(pair, title);
111 }
112 catch (const std::exception &e)
113 {
114 const StringPair pair(s1, s2);
115 error(e, pair.render(), title);
116 }
117 return AddrMaskPair(); // NOTREACHED
118 }
119
120 static AddrMaskPair from_string(const std::string &s, const char *title = nullptr)
121 {
122 try
123 {
124 const StringPair pair = Split::by_char<StringPair, NullLex, Split::NullLimit>(s, '/');
125 return from_string_impl(pair, title);
126 }
127 catch (const std::exception &e)
128 {
129 error(e, s, title);
130 }
131 return AddrMaskPair(); // NOTREACHED
132 }
133
134 static AddrMaskPair from_string(const StringPair &pair, const char *title = nullptr)
135 {
136 try
137 {
138 return from_string_impl(pair, title);
139 }
140 catch (const std::exception &e)
141 {
142 error(e, pair.render(), title);
143 }
144 return AddrMaskPair(); // NOTREACHED
145 }
146
147 std::string to_string(const bool netmask_form = false) const
148 {
149 std::ostringstream os;
150 if (netmask_form)
151 os << addr.to_string() << '/' << netmask.to_string();
152 else
153 os << addr.to_string() << '/' << netmask.prefix_len();
154 return os.str();
155 }
156
157 bool is_canonical() const
158 {
159 return (addr & netmask) == addr;
160 }
161
163 {
164 const Addr::Version v1 = addr.version();
165 const Addr::Version v2 = netmask.version();
166 if (v1 == v2)
167 return v1;
168 return Addr::UNSPEC;
169 }
170
173
174 private:
175 static void error(const std::exception &e, const std::string &s, const char *title)
176 {
177 if (!title)
178 title = "";
179 OPENVPN_THROW(addr_pair_mask_parse_error, "AddrMaskPair parse error '" << title << "': " << s << " : " << e.what());
180 }
181
182 static AddrMaskPair from_string_impl(const StringPair &pair, const char *title = nullptr)
183 {
185 if (pair.size() == 1 || pair.size() == 2)
186 {
187 ret.addr = Addr::from_string(pair[0], title);
188 if (pair.size() == 2 && !pair[1].empty())
189 {
190 if (is_number(pair[1].c_str()))
191 ret.netmask = Addr::netmask_from_prefix_len(ret.addr.version(),
192 parse_number_throw<unsigned int>(pair[1], "prefix length"));
193 else
194 ret.netmask = Addr::from_string(pair[1]);
195 ret.netmask.prefix_len(); // verify that netmask is ok
196 }
197 else
198 ret.netmask = Addr::from_zero_complement(ret.addr.version());
199 ret.addr.verify_version_consistency(ret.netmask);
200 }
201 else
202 throw addr_pair_mask_parse_error("only one or two address terms allowed");
203 return ret;
204 }
205};
206OPENVPN_OSTREAM(AddrMaskPair, to_string)
207} // namespace openvpn::IP
208
209#endif
std::string & operator[](const size_t i)
Definition addrpair.hpp:69
void push_back(const std::string &s)
Definition addrpair.hpp:54
OPENVPN_SIMPLE_EXCEPTION(addr_pair_string_error)
StringPair(const std::string &s1)
Definition addrpair.hpp:41
const std::string & operator[](const size_t i) const
Definition addrpair.hpp:62
StringPair(const std::string &s1, const std::string &s2)
Definition addrpair.hpp:47
static Addr from_string(const std::string &ipstr, const TITLE &title, const Version required_version)
Definition ip.hpp:105
Version version() const
Definition ip.hpp:895
std::string to_string() const
Definition ip.hpp:528
static Addr netmask_from_prefix_len(Version v, const unsigned int prefix_len)
Definition ip.hpp:502
unsigned int prefix_len() const
Definition ip.hpp:968
static Addr from_zero_complement(const Version v)
Definition ip.hpp:478
#define OPENVPN_THROW(exc, stuff)
bool is_number(const char *str)
Definition number.hpp:123
#define OPENVPN_OSTREAM(TYPE, METH)
Definition ostream.hpp:21
static AddrMaskPair from_string(const StringPair &pair, const char *title=nullptr)
Definition addrpair.hpp:134
static void error(const std::exception &e, const std::string &s, const char *title)
Definition addrpair.hpp:175
std::string to_string(const bool netmask_form=false) const
Definition addrpair.hpp:147
OPENVPN_EXCEPTION(addr_pair_mask_parse_error)
static AddrMaskPair from_string(const std::string &s1, const std::string &s2, const char *title=nullptr)
Definition addrpair.hpp:99
static AddrMaskPair from_string_impl(const StringPair &pair, const char *title=nullptr)
Definition addrpair.hpp:182
static AddrMaskPair from_string(const std::string &s, const char *title=nullptr)
Definition addrpair.hpp:120
Addr::Version version() const
Definition addrpair.hpp:162
std::string ret
std::ostringstream os