OpenVPN 3 Core Library
Loading...
Searching...
No Matches
test_ip.cpp
Go to the documentation of this file.
1#include "test_common.hpp"
2#include <iostream>
3
6
8#include <openvpn/addr/ip.hpp>
10#include <openvpn/addr/ipv6.hpp>
11
12#if defined(SIN6_LEN) || defined(__APPLE__) || defined(__FreeBSD__)
13#include <sys/socket.h>
14#endif
15
16using namespace openvpn;
17
18static const uint8_t icmp6_packet[] = {
19 // clang-format off
20 0x60, 0x06, 0x22, 0xe5, 0x00, 0x40, 0x3a, 0x28, 0x26, 0x01, 0x02, 0x81, 0x84, 0x80, 0x14, 0xe0,
21 0xbc, 0xc1, 0x91, 0x20, 0xfc, 0xa3, 0x0e, 0x22, 0x26, 0x00, 0x1f, 0x18, 0x47, 0x2b, 0x89, 0x05,
22 0x2a, 0xc4, 0x3b, 0xf3, 0xd5, 0x77, 0x29, 0x42, 0x80, 0x00, 0x99, 0x99, 0x3f, 0xd4, 0x00, 0x0e,
23 0x43, 0xd4, 0xc3, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xc2, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
25 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
26 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
27 // clang-format on
28
29};
30
31static bool verbose = false;
32
33TEST(IPAddr, icmp6csum)
34{
35 const ICMPv6 *icmp = (const ICMPv6 *)icmp6_packet;
36 const size_t len = sizeof(icmp6_packet);
37
38 if (verbose)
39 {
40 std::cout << "From : " << IPv6::Addr::from_in6_addr(&icmp->head.saddr).to_string() << std::endl;
41 std::cout << "To : " << IPv6::Addr::from_in6_addr(&icmp->head.daddr).to_string() << std::endl;
42 }
43 const std::uint16_t csum = Ping6::csum_icmp(icmp, len);
44 if (verbose)
45 {
46 std::cout << "Checksum: " << csum << std::endl;
47 }
48 ASSERT_TRUE(csum == 0) << "checksum=" << csum << " but should be zero";
49}
50
51TEST(IPAddr, pool)
52{
53 IP::Pool pool;
54 pool.add_range(IP::Range(IP::Addr::from_string("1.2.3.4"), 16));
55 pool.add_range(IP::Range(IP::Addr::from_string("Fe80::23a1:b152"), 4));
56 pool.add_addr(IP::Addr::from_string("10.10.1.1"));
57 ASSERT_TRUE(pool.acquire_specific_addr(IP::Addr::from_string("1.2.3.10")));
58
59 std::stringstream s;
60 for (int i = 0;; ++i)
61 {
62 IP::Addr addr;
63 if (i == 7)
64 {
65 pool.release_addr(IP::Addr::from_string("1.2.3.7"));
66 }
67 else if (i == 11)
68 {
69 pool.release_addr(IP::Addr::from_string("1.2.3.3"));
70 pool.release_addr(IP::Addr::from_string("1.2.3.4"));
71 pool.release_addr(IP::Addr::from_string("1.2.3.5"));
72 }
73 else
74 {
75 if (pool.acquire_addr(addr))
76 {
77 s << addr << " (" << pool.n_in_use() << ")" << std::endl;
78 }
79 else
80 break;
81 }
82 }
83 ASSERT_EQ("1.2.3.4 (1)\n"
84 "1.2.3.5 (2)\n"
85 "1.2.3.6 (3)\n"
86 "1.2.3.7 (4)\n"
87 "1.2.3.8 (5)\n"
88 "1.2.3.9 (6)\n"
89 "1.2.3.11 (8)\n"
90 "1.2.3.12 (8)\n"
91 "1.2.3.13 (9)\n"
92 "1.2.3.14 (10)\n"
93 "1.2.3.15 (9)\n"
94 "1.2.3.16 (10)\n"
95 "1.2.3.17 (11)\n"
96 "1.2.3.18 (12)\n"
97 "1.2.3.19 (13)\n"
98 "fe80::23a1:b152 (14)\n"
99 "fe80::23a1:b153 (15)\n"
100 "fe80::23a1:b154 (16)\n"
101 "fe80::23a1:b155 (17)\n"
102 "10.10.1.1 (18)\n"
103 "1.2.3.7 (19)\n"
104 "1.2.3.4 (20)\n"
105 "1.2.3.5 (21)\n",
106 s.str());
107}
108
109TEST(Pool, AcquiringNotAvailableAddressReturnsFalse)
110{
111 auto pool = IP::Pool{};
112 pool.add_range(IP::Range(IP::Addr::from_string("1.2.3.4"), 16));
113 ASSERT_FALSE(pool.acquire_specific_addr(IP::Addr::from_string("1.2.3.42")));
114}
115
116TEST(Range, EmptyRangeBeginEndIteratorsAreEqual)
117{
118 auto empty_range = IP::Range{};
119 ASSERT_FALSE(empty_range.begin() != empty_range.end()); // Because using ASSERT_EQ or ASSERT_TRUE with == would require implementing operator==
120}
121
123{
124 int shift;
125 uint8_t ip[16];
126};
127
128
129
130void do_shift_tests(const std::vector<test_case> &test_vectors, bool leftshift)
131{
132 sockaddr_in6 sa{};
133
134 for (int i = 0; i < 16; i++)
135 {
136 /* first vector has to use a shift of 0 */
137 sa.sin6_addr.s6_addr[i] = test_vectors[0].ip[i];
138 }
139
140 for (const auto &t : test_vectors)
141 {
142 // Shift by zero should not change anything
143 auto addr = IPv6::Addr::from_sockaddr(&sa);
144
145 IPv6::Addr shifted_addr{};
146
147 if (leftshift)
148 shifted_addr = addr << t.shift;
149 else
150 shifted_addr = addr >> t.shift;
151 auto ret = shifted_addr.to_sockaddr();
152
153 sockaddr_in6 cmp{};
154#if defined(SIN6_LEN) || defined(__APPLE__) || defined(__FreeBSD__)
155 /* Enable this test on the platforms that we know to have sin6_len
156 * to not only depend on SIN6_LEN */
157 cmp.sin6_len = sizeof(sockaddr_in6);
158#endif
159 cmp.sin6_family = AF_INET6;
160 for (int i = 0; i < 16; i++)
161 {
162 cmp.sin6_addr.s6_addr[i] = t.ip[i];
163 }
164
165 if (memcmp(&cmp, &ret, sizeof(sockaddr_in6)) != 0)
166 std::cout << "BROKEN " << std::to_string(t.shift) << std::endl;
167
168 EXPECT_EQ(memcmp(&cmp, &ret, sizeof(sockaddr_in6)), 0);
169 }
170}
171
172
173/* test vectors are generated with gen_ip_shifts.py */
174TEST(IPAddr, left_shift)
175{
176 std::vector<test_case> tests{{0, {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x0, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
177 {1, {0x22, 0x44, 0x66, 0x88, 0xaa, 0xcc, 0xef, 0x11, 0x32, 0x1, 0x55, 0x77, 0x99, 0xbb, 0xdd, 0xfe}},
178 {31, {0x2a, 0xb3, 0x3b, 0xc4, 0x4c, 0x80, 0x55, 0x5d, 0xe6, 0x6e, 0xf7, 0x7f, 0x80, 0x0, 0x0, 0x0}},
179 {32, {0x55, 0x66, 0x77, 0x88, 0x99, 0x0, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x0, 0x0, 0x0, 0x0}},
180 {33, {0xaa, 0xcc, 0xef, 0x11, 0x32, 0x1, 0x55, 0x77, 0x99, 0xbb, 0xdd, 0xfe, 0x0, 0x0, 0x0, 0x0}},
181 {45, {0xce, 0xf1, 0x13, 0x20, 0x15, 0x57, 0x79, 0x9b, 0xbd, 0xdf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0}},
182 {63, {0x4c, 0x80, 0x55, 0x5d, 0xe6, 0x6e, 0xf7, 0x7f, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
183 {64, {0x99, 0x0, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
184 {67, {0xc8, 0x5, 0x55, 0xde, 0x66, 0xef, 0x77, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
185 {80, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
186 {97, {0x99, 0xbb, 0xdd, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
187 {127, {0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
188 {128, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}};
189 do_shift_tests(tests, true);
190}
191
192TEST(IPAddr, left_shift_random)
193{
194 std::vector<test_case> tests{
195 {0, {0xbc, 0x46, 0xc, 0xcb, 0x8f, 0x85, 0x25, 0x9a, 0x74, 0x91, 0xd4, 0x80, 0xed, 0x2d, 0xe8, 0xe0}},
196 {1, {0x78, 0x8c, 0x19, 0x97, 0x1f, 0xa, 0x4b, 0x34, 0xe9, 0x23, 0xa9, 0x1, 0xda, 0x5b, 0xd1, 0xc0}},
197 {31, {0xc7, 0xc2, 0x92, 0xcd, 0x3a, 0x48, 0xea, 0x40, 0x76, 0x96, 0xf4, 0x70, 0x0, 0x0, 0x0, 0x0}},
198 {32, {0x8f, 0x85, 0x25, 0x9a, 0x74, 0x91, 0xd4, 0x80, 0xed, 0x2d, 0xe8, 0xe0, 0x0, 0x0, 0x0, 0x0}},
199 {33, {0x1f, 0xa, 0x4b, 0x34, 0xe9, 0x23, 0xa9, 0x1, 0xda, 0x5b, 0xd1, 0xc0, 0x0, 0x0, 0x0, 0x0}},
200 {45, {0xa4, 0xb3, 0x4e, 0x92, 0x3a, 0x90, 0x1d, 0xa5, 0xbd, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
201 {63, {0x3a, 0x48, 0xea, 0x40, 0x76, 0x96, 0xf4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
202 {64, {0x74, 0x91, 0xd4, 0x80, 0xed, 0x2d, 0xe8, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
203 {67, {0xa4, 0x8e, 0xa4, 0x7, 0x69, 0x6f, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
204 {80, {0xd4, 0x80, 0xed, 0x2d, 0xe8, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
205 {97, {0xda, 0x5b, 0xd1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
206 {127, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
207 {128, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}};
208 do_shift_tests(tests, true);
209}
210
211TEST(IPAddr, right_shift)
212{
213 std::vector<test_case> tests{
214 {0, {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x0, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
215 {1, {0x8, 0x91, 0x19, 0xa2, 0x2a, 0xb3, 0x3b, 0xc4, 0x4c, 0x80, 0x55, 0x5d, 0xe6, 0x6e, 0xf7, 0x7f}},
216 {31, {0x0, 0x0, 0x0, 0x0, 0x22, 0x44, 0x66, 0x88, 0xaa, 0xcc, 0xef, 0x11, 0x32, 0x1, 0x55, 0x77}},
217 {32, {0x0, 0x0, 0x0, 0x0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x0, 0xaa, 0xbb}},
218 {33, {0x0, 0x0, 0x0, 0x0, 0x8, 0x91, 0x19, 0xa2, 0x2a, 0xb3, 0x3b, 0xc4, 0x4c, 0x80, 0x55, 0x5d}},
219 {45, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89, 0x11, 0x9a, 0x22, 0xab, 0x33, 0xbc, 0x44, 0xc8, 0x5}},
220 {63, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x44, 0x66, 0x88, 0xaa, 0xcc, 0xef, 0x11}},
221 {64, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}},
222 {67, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x24, 0x46, 0x68, 0x8a, 0xac, 0xce, 0xf1}},
223 {80, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}},
224 {97, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x91, 0x19, 0xa2}},
225 {127, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
226 {128, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}};
227 do_shift_tests(tests, false);
228}
229
230TEST(IPAddr, right_shift_random)
231{
232 std::vector<test_case> tests{{0, {0x6d, 0xfb, 0x4a, 0x15, 0xb3, 0x6a, 0xd8, 0x25, 0x42, 0x83, 0x27, 0x83, 0xa9, 0x27, 0x2d, 0x3}},
233 {1, {0x36, 0xfd, 0xa5, 0xa, 0xd9, 0xb5, 0x6c, 0x12, 0xa1, 0x41, 0x93, 0xc1, 0xd4, 0x93, 0x96, 0x81}},
234 {31, {0x0, 0x0, 0x0, 0x0, 0xdb, 0xf6, 0x94, 0x2b, 0x66, 0xd5, 0xb0, 0x4a, 0x85, 0x6, 0x4f, 0x7}},
235 {32, {0x0, 0x0, 0x0, 0x0, 0x6d, 0xfb, 0x4a, 0x15, 0xb3, 0x6a, 0xd8, 0x25, 0x42, 0x83, 0x27, 0x83}},
236 {33, {0x0, 0x0, 0x0, 0x0, 0x36, 0xfd, 0xa5, 0xa, 0xd9, 0xb5, 0x6c, 0x12, 0xa1, 0x41, 0x93, 0xc1}},
237 {45, {0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x6f, 0xda, 0x50, 0xad, 0x9b, 0x56, 0xc1, 0x2a, 0x14, 0x19}},
238 {63, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdb, 0xf6, 0x94, 0x2b, 0x66, 0xd5, 0xb0, 0x4a}},
239 {64, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6d, 0xfb, 0x4a, 0x15, 0xb3, 0x6a, 0xd8, 0x25}},
240 {67, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xbf, 0x69, 0x42, 0xb6, 0x6d, 0x5b, 0x4}},
241 {80, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6d, 0xfb, 0x4a, 0x15, 0xb3, 0x6a}},
242 {97, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0xfd, 0xa5, 0xa}},
243 {127, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}},
244 {128, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}};
245 do_shift_tests(tests, false);
246}
247
248TEST(IPAddr, mapped_v4)
249{
250 IP::Addr v6mapped{"::ffff:2332:123a"};
251
252
253 EXPECT_TRUE(v6mapped.is_mapped_address());
254 IP::Addr notMapped = v6mapped.to_v4_addr();
255
256 EXPECT_EQ(v6mapped.to_string(), "::ffff:35.50.18.58");
257 EXPECT_EQ(notMapped.to_string(), "35.50.18.58");
258
259 EXPECT_FALSE(IP::Addr{"::faff:2332:123a"}.is_mapped_address());
260 EXPECT_FALSE(IP::Addr{"::2332:123a"}.is_mapped_address());
261 EXPECT_FALSE(IP::Addr{"192.168.0.123"}.is_mapped_address());
262}
static Addr from_string(const std::string &ipstr, const TITLE &title, const Version required_version)
Definition ip.hpp:105
std::string to_string() const
Definition ip.hpp:528
IP::Addr to_v4_addr() const
Definition ip.hpp:866
bool is_mapped_address() const
Definition ip.hpp:858
void add_range(const RangeType< ADDR > &range)
Adds range of addresses to pool (pool will own the addresses).
Definition pool.hpp:38
void add_addr(const ADDR &addr)
Definition pool.hpp:47
bool acquire_addr(ADDR &dest)
Definition pool.hpp:76
bool acquire_specific_addr(const ADDR &addr)
Acquires a specific address from the pool.
Definition pool.hpp:108
void release_addr(const ADDR &addr)
Definition pool.hpp:122
size_t n_in_use() const noexcept
Returns number of pool addresses currently in use.
Definition pool.hpp:60
designed to represent and manage a range of IP addresses.
Definition range.hpp:65
static Addr from_sockaddr(const sockaddr_in6 *sa)
Definition ipv6.hpp:82
static Addr from_in6_addr(const in6_addr *in6)
Definition ipv6.hpp:63
std::string to_string() const
Definition ipv6.hpp:131
sockaddr_in6 to_sockaddr(const unsigned short port=0) const
Definition ipv6.hpp:87
std::uint16_t csum_icmp(const ICMPv6 *icmp, const size_t len)
Definition ping6.hpp:83
struct IPv6Header head
Definition icmp6.hpp:35
struct in6_addr saddr
Definition ip6.hpp:35
struct in6_addr daddr
Definition ip6.hpp:36
uint8_t ip[16]
Definition test_ip.cpp:125
std::string ret
static const uint8_t icmp6_packet[]
Definition test_ip.cpp:18
TEST(IPAddr, icmp6csum)
Definition test_ip.cpp:33
static bool verbose
Definition test_ip.cpp:31
void do_shift_tests(const std::vector< test_case > &test_vectors, bool leftshift)
Definition test_ip.cpp:130