1 /*
2 * Copyright 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * clatd_test.cpp - unit tests for clatd
17 */
18
19 #include <iostream>
20
21 #include <arpa/inet.h>
22 #include <netinet/in6.h>
23 #include <stdio.h>
24 #include <sys/uio.h>
25
26 #include <gtest/gtest.h>
27
28 #include "netutils/ifc.h"
29 #include "tun_interface.h"
30
31 extern "C" {
32 #include "clatd.h"
33 #include "config.h"
34 #include "getaddr.h"
35 #include "netutils/checksum.h"
36 #include "translate.h"
37 #include "tun.h"
38 }
39
40 // For convenience.
41 #define ARRAYSIZE(x) sizeof((x)) / sizeof((x)[0])
42
43 using android::net::TunInterface;
44
45 // Default translation parameters.
46 static const char kIPv4LocalAddr[] = "192.0.0.4";
47 static const char kIPv6LocalAddr[] = "2001:db8:0:b11::464";
48 static const char kIPv6PlatSubnet[] = "64:ff9b::";
49
50 // clang-format off
51 // Test packet portions. Defined as macros because it's easy to concatenate them to make packets.
52 #define IPV4_HEADER(p, c1, c2) \
53 0x45, 0x00, 0, 41, /* Version=4, IHL=5, ToS=0x80, len=41 */ \
54 0x00, 0x00, 0x40, 0x00, /* ID=0x0000, flags=IP_DF, offset=0 */ \
55 55, (p), (c1), (c2), /* TTL=55, protocol=p, checksum=c1,c2 */ \
56 192, 0, 0, 4, /* Src=192.0.0.4 */ \
57 8, 8, 8, 8, /* Dst=8.8.8.8 */
58 #define IPV4_UDP_HEADER IPV4_HEADER(IPPROTO_UDP, 0x73, 0xb0)
59 #define IPV4_ICMP_HEADER IPV4_HEADER(IPPROTO_ICMP, 0x73, 0xc0)
60
61 #define IPV6_HEADER(p) \
62 0x60, 0x00, 0, 0, /* Version=6, tclass=0x00, flowlabel=0 */ \
63 0, 21, (p), 55, /* plen=11, nxthdr=p, hlim=55 */ \
64 0x20, 0x01, 0x0d, 0xb8, /* Src=2001:db8:0:b11::464 */ \
65 0x00, 0x00, 0x0b, 0x11, \
66 0x00, 0x00, 0x00, 0x00, \
67 0x00, 0x00, 0x04, 0x64, \
68 0x00, 0x64, 0xff, 0x9b, /* Dst=64:ff9b::8.8.8.8 */ \
69 0x00, 0x00, 0x00, 0x00, \
70 0x00, 0x00, 0x00, 0x00, \
71 0x08, 0x08, 0x08, 0x08,
72 #define IPV6_UDP_HEADER IPV6_HEADER(IPPROTO_UDP)
73 #define IPV6_ICMPV6_HEADER IPV6_HEADER(IPPROTO_ICMPV6)
74
75 #define UDP_LEN 21
76 #define UDP_HEADER \
77 0xc8, 0x8b, 0, 53, /* Port 51339->53 */ \
78 0x00, UDP_LEN, 0, 0, /* Length 21, checksum empty for now */
79
80 #define PAYLOAD 'H', 'e', 'l', 'l', 'o', ' ', 0x4e, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0x00
81
82 #define IPV4_PING \
83 0x08, 0x00, 0x88, 0xd0, /* Type 8, code 0, checksum 0x88d0 */ \
84 0xd0, 0x0d, 0x00, 0x03, /* ID=0xd00d, seq=3 */
85
86 #define IPV6_PING \
87 0x80, 0x00, 0xc3, 0x42, /* Type 128, code 0, checksum 0xc342 */ \
88 0xd0, 0x0d, 0x00, 0x03, /* ID=0xd00d, seq=3 */
89
90 // Macros to return pseudo-headers from packets.
91 #define IPV4_PSEUDOHEADER(ip, tlen) \
92 ip[12], ip[13], ip[14], ip[15], /* Source address */ \
93 ip[16], ip[17], ip[18], ip[19], /* Destination address */ \
94 0, ip[9], /* 0, protocol */ \
95 ((tlen) >> 16) & 0xff, (tlen) & 0xff, /* Transport length */
96
97 #define IPV6_PSEUDOHEADER(ip6, protocol, tlen) \
98 ip6[8], ip6[9], ip6[10], ip6[11], /* Source address */ \
99 ip6[12], ip6[13], ip6[14], ip6[15], \
100 ip6[16], ip6[17], ip6[18], ip6[19], \
101 ip6[20], ip6[21], ip6[22], ip6[23], \
102 ip6[24], ip6[25], ip6[26], ip6[27], /* Destination address */ \
103 ip6[28], ip6[29], ip6[30], ip6[31], \
104 ip6[32], ip6[33], ip6[34], ip6[35], \
105 ip6[36], ip6[37], ip6[38], ip6[39], \
106 ((tlen) >> 24) & 0xff, /* Transport length */ \
107 ((tlen) >> 16) & 0xff, \
108 ((tlen) >> 8) & 0xff, \
109 (tlen) & 0xff, \
110 0, 0, 0, (protocol),
111
112 // A fragmented DNS request.
113 static const uint8_t kIPv4Frag1[] = {
114 0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x00, 0x40, 0x11,
115 0x8c, 0x6d, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
116 0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47,
117 0x01, 0x00, 0x00, 0x01, 0x00, 0x00
118 };
119 static const uint8_t kIPv4Frag2[] = {
120 0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x02, 0x40, 0x11,
121 0x8c, 0x6b, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
122 0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06,
123 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65
124 };
125 static const uint8_t kIPv4Frag3[] = {
126 0x45, 0x00, 0x00, 0x1d, 0xfe, 0x47, 0x00, 0x04, 0x40, 0x11,
127 0xac, 0x70, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
128 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
129 };
130 static const uint8_t *kIPv4Fragments[] = { kIPv4Frag1, kIPv4Frag2, kIPv4Frag3 };
131 static const size_t kIPv4FragLengths[] = { sizeof(kIPv4Frag1), sizeof(kIPv4Frag2),
132 sizeof(kIPv4Frag3) };
133
134 static const uint8_t kIPv6Frag1[] = {
135 0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01,
136 0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
139 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0xfe, 0x47, 0x14, 0x5d,
140 0x00, 0x35, 0x00, 0x29, 0xeb, 0x91, 0x50, 0x47, 0x01, 0x00,
141 0x00, 0x01, 0x00, 0x00
142 };
143
144 static const uint8_t kIPv6Frag2[] = {
145 0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01,
146 0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
149 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0xfe, 0x47, 0x00, 0x00,
150 0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f,
151 0x6f, 0x67, 0x6c, 0x65
152 };
153
154 static const uint8_t kIPv6Frag3[] = {
155 0x60, 0x00, 0x00, 0x00, 0x00, 0x11, 0x2c, 0x40, 0x20, 0x01,
156 0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
159 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0xfe, 0x47, 0x03, 0x63,
160 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
161 };
162 static const uint8_t *kIPv6Fragments[] = { kIPv6Frag1, kIPv6Frag2, kIPv6Frag3 };
163 static const size_t kIPv6FragLengths[] = { sizeof(kIPv6Frag1), sizeof(kIPv6Frag2),
164 sizeof(kIPv6Frag3) };
165
166 static const uint8_t kReassembledIPv4[] = {
167 0x45, 0x00, 0x00, 0x3d, 0xfe, 0x47, 0x00, 0x00, 0x40, 0x11,
168 0xac, 0x54, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
169 0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47,
170 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f, 0x6f, 0x67,
172 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
173 0x01
174 };
175 // clang-format on
176
177 // Expected checksums.
178 static const uint32_t kUdpPartialChecksum = 0xd5c8;
179 static const uint32_t kPayloadPartialChecksum = 0x31e9c;
180 static const uint16_t kUdpV4Checksum = 0xd0c7;
181 static const uint16_t kUdpV6Checksum = 0xa74a;
182
ip_version(const uint8_t * packet)183 uint8_t ip_version(const uint8_t *packet) {
184 uint8_t version = packet[0] >> 4;
185 return version;
186 }
187
is_ipv4_fragment(struct iphdr * ip)188 int is_ipv4_fragment(struct iphdr *ip) {
189 // A packet is a fragment if its fragment offset is nonzero or if the MF flag is set.
190 return ntohs(ip->frag_off) & (IP_OFFMASK | IP_MF);
191 }
192
is_ipv6_fragment(struct ip6_hdr * ip6,size_t len)193 int is_ipv6_fragment(struct ip6_hdr *ip6, size_t len) {
194 if (ip6->ip6_nxt != IPPROTO_FRAGMENT) {
195 return 0;
196 }
197 struct ip6_frag *frag = (struct ip6_frag *)(ip6 + 1);
198 return len >= sizeof(*ip6) + sizeof(*frag) &&
199 (frag->ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG));
200 }
201
ipv4_fragment_offset(struct iphdr * ip)202 int ipv4_fragment_offset(struct iphdr *ip) {
203 return ntohs(ip->frag_off) & IP_OFFMASK;
204 }
205
ipv6_fragment_offset(struct ip6_frag * frag)206 int ipv6_fragment_offset(struct ip6_frag *frag) {
207 return ntohs((frag->ip6f_offlg & IP6F_OFF_MASK) >> 3);
208 }
209
check_packet(const uint8_t * packet,size_t len,const char * msg)210 void check_packet(const uint8_t *packet, size_t len, const char *msg) {
211 void *payload;
212 size_t payload_length = 0;
213 uint32_t pseudo_checksum = 0;
214 uint8_t protocol = 0;
215 int version = ip_version(packet);
216 switch (version) {
217 case 4: {
218 struct iphdr *ip = (struct iphdr *)packet;
219 ASSERT_GE(len, sizeof(*ip)) << msg << ": IPv4 packet shorter than IPv4 header\n";
220 EXPECT_EQ(5, ip->ihl) << msg << ": Unsupported IP header length\n";
221 EXPECT_EQ(len, ntohs(ip->tot_len)) << msg << ": Incorrect IPv4 length\n";
222 EXPECT_EQ(0, ip_checksum(ip, sizeof(*ip))) << msg << ": Incorrect IP checksum\n";
223 protocol = ip->protocol;
224 payload = ip + 1;
225 if (!is_ipv4_fragment(ip)) {
226 payload_length = len - sizeof(*ip);
227 pseudo_checksum = ipv4_pseudo_header_checksum(ip, payload_length);
228 }
229 ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMP)
230 << msg << ": Unsupported IPv4 protocol " << protocol << "\n";
231 break;
232 }
233 case 6: {
234 struct ip6_hdr *ip6 = (struct ip6_hdr *)packet;
235 ASSERT_GE(len, sizeof(*ip6)) << msg << ": IPv6 packet shorter than IPv6 header\n";
236 EXPECT_EQ(len - sizeof(*ip6), htons(ip6->ip6_plen)) << msg << ": Incorrect IPv6 length\n";
237
238 if (ip6->ip6_nxt == IPPROTO_FRAGMENT) {
239 struct ip6_frag *frag = (struct ip6_frag *)(ip6 + 1);
240 ASSERT_GE(len, sizeof(*ip6) + sizeof(*frag))
241 << msg << ": IPv6 fragment: short fragment header\n";
242 protocol = frag->ip6f_nxt;
243 payload = frag + 1;
244 // Even though the packet has a Fragment header, it might not be a fragment.
245 if (!is_ipv6_fragment(ip6, len)) {
246 payload_length = len - sizeof(*ip6) - sizeof(*frag);
247 }
248 } else {
249 // Since there are no extension headers except Fragment, this must be the payload.
250 protocol = ip6->ip6_nxt;
251 payload = ip6 + 1;
252 payload_length = len - sizeof(*ip6);
253 }
254 ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMPV6)
255 << msg << ": Unsupported IPv6 next header " << protocol;
256 if (payload_length) {
257 pseudo_checksum = ipv6_pseudo_header_checksum(ip6, payload_length, protocol);
258 }
259 break;
260 }
261 default:
262 FAIL() << msg << ": Unsupported IP version " << version << "\n";
263 return;
264 }
265
266 // If we understand the payload, verify the checksum.
267 if (payload_length) {
268 uint16_t checksum;
269 switch (protocol) {
270 case IPPROTO_UDP:
271 case IPPROTO_TCP:
272 case IPPROTO_ICMPV6:
273 checksum = ip_checksum_finish(ip_checksum_add(pseudo_checksum, payload, payload_length));
274 break;
275 case IPPROTO_ICMP:
276 checksum = ip_checksum(payload, payload_length);
277 break;
278 default:
279 checksum = 0; // Don't check.
280 break;
281 }
282 EXPECT_EQ(0, checksum) << msg << ": Incorrect transport checksum\n";
283 }
284
285 if (protocol == IPPROTO_UDP) {
286 struct udphdr *udp = (struct udphdr *)payload;
287 EXPECT_NE(0, udp->check) << msg << ": UDP checksum 0 should be 0xffff";
288 // If this is not a fragment, check the UDP length field.
289 if (payload_length) {
290 EXPECT_EQ(payload_length, ntohs(udp->len)) << msg << ": Incorrect UDP length\n";
291 }
292 }
293 }
294
reassemble_packet(const uint8_t ** fragments,const size_t lengths[],int numpackets,uint8_t * reassembled,size_t * reassembled_len,const char * msg)295 void reassemble_packet(const uint8_t **fragments, const size_t lengths[], int numpackets,
296 uint8_t *reassembled, size_t *reassembled_len, const char *msg) {
297 struct iphdr *ip = nullptr;
298 struct ip6_hdr *ip6 = nullptr;
299 size_t total_length, pos = 0;
300 uint8_t protocol = 0;
301 uint8_t version = ip_version(fragments[0]);
302
303 for (int i = 0; i < numpackets; i++) {
304 const uint8_t *packet = fragments[i];
305 int len = lengths[i];
306 int headersize, payload_offset;
307
308 ASSERT_EQ(ip_version(packet), version) << msg << ": Inconsistent fragment versions\n";
309 check_packet(packet, len, "Fragment sanity check");
310
311 switch (version) {
312 case 4: {
313 struct iphdr *ip_orig = (struct iphdr *)packet;
314 headersize = sizeof(*ip_orig);
315 ASSERT_TRUE(is_ipv4_fragment(ip_orig))
316 << msg << ": IPv4 fragment #" << i + 1 << " not a fragment\n";
317 ASSERT_EQ(pos, ipv4_fragment_offset(ip_orig) * 8 + ((i != 0) ? sizeof(*ip) : 0))
318 << msg << ": IPv4 fragment #" << i + 1 << ": inconsistent offset\n";
319
320 headersize = sizeof(*ip_orig);
321 payload_offset = headersize;
322 if (pos == 0) {
323 ip = (struct iphdr *)reassembled;
324 }
325 break;
326 }
327 case 6: {
328 struct ip6_hdr *ip6_orig = (struct ip6_hdr *)packet;
329 struct ip6_frag *frag = (struct ip6_frag *)(ip6_orig + 1);
330 ASSERT_TRUE(is_ipv6_fragment(ip6_orig, len))
331 << msg << ": IPv6 fragment #" << i + 1 << " not a fragment\n";
332 ASSERT_EQ(pos, ipv6_fragment_offset(frag) * 8 + ((i != 0) ? sizeof(*ip6) : 0))
333 << msg << ": IPv6 fragment #" << i + 1 << ": inconsistent offset\n";
334
335 headersize = sizeof(*ip6_orig);
336 payload_offset = sizeof(*ip6_orig) + sizeof(*frag);
337 if (pos == 0) {
338 ip6 = (struct ip6_hdr *)reassembled;
339 protocol = frag->ip6f_nxt;
340 }
341 break;
342 }
343 default:
344 FAIL() << msg << ": Invalid IP version << " << version;
345 }
346
347 // If this is the first fragment, copy the header.
348 if (pos == 0) {
349 ASSERT_LT(headersize, (int)*reassembled_len) << msg << ": Reassembly buffer too small\n";
350 memcpy(reassembled, packet, headersize);
351 total_length = headersize;
352 pos += headersize;
353 }
354
355 // Copy the payload.
356 int payload_length = len - payload_offset;
357 total_length += payload_length;
358 ASSERT_LT(total_length, *reassembled_len) << msg << ": Reassembly buffer too small\n";
359 memcpy(reassembled + pos, packet + payload_offset, payload_length);
360 pos += payload_length;
361 }
362
363 // Fix up the reassembled headers to reflect fragmentation and length (and IPv4 checksum).
364 ASSERT_EQ(total_length, pos) << msg << ": Reassembled packet length incorrect\n";
365 if (ip) {
366 ip->frag_off &= ~htons(IP_MF);
367 ip->tot_len = htons(total_length);
368 ip->check = 0;
369 ip->check = ip_checksum(ip, sizeof(*ip));
370 ASSERT_FALSE(is_ipv4_fragment(ip)) << msg << ": reassembled IPv4 packet is a fragment!\n";
371 }
372 if (ip6) {
373 ip6->ip6_nxt = protocol;
374 ip6->ip6_plen = htons(total_length - sizeof(*ip6));
375 ASSERT_FALSE(is_ipv6_fragment(ip6, ip6->ip6_plen))
376 << msg << ": reassembled IPv6 packet is a fragment!\n";
377 }
378
379 *reassembled_len = total_length;
380 }
381
check_data_matches(const void * expected,const void * actual,size_t len,const char * msg)382 void check_data_matches(const void *expected, const void *actual, size_t len, const char *msg) {
383 if (memcmp(expected, actual, len)) {
384 // Hex dump, 20 bytes per line, one space between bytes (1 byte = 3 chars), indented by 4.
385 int hexdump_len = len * 3 + (len / 20 + 1) * 5;
386 char expected_hexdump[hexdump_len], actual_hexdump[hexdump_len];
387 unsigned pos = 0;
388 for (unsigned i = 0; i < len; i++) {
389 if (i % 20 == 0) {
390 snprintf(expected_hexdump + pos, hexdump_len - pos, "\n ");
391 snprintf(actual_hexdump + pos, hexdump_len - pos, "\n ");
392 pos += 4;
393 }
394 snprintf(expected_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)expected)[i]);
395 snprintf(actual_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)actual)[i]);
396 pos += 3;
397 }
398 FAIL() << msg << ": Data doesn't match"
399 << "\n Expected:" << (char *) expected_hexdump
400 << "\n Actual:" << (char *) actual_hexdump << "\n";
401 }
402 }
403
fix_udp_checksum(uint8_t * packet)404 void fix_udp_checksum(uint8_t *packet) {
405 uint32_t pseudo_checksum;
406 uint8_t version = ip_version(packet);
407 struct udphdr *udp;
408 switch (version) {
409 case 4: {
410 struct iphdr *ip = (struct iphdr *)packet;
411 udp = (struct udphdr *)(ip + 1);
412 pseudo_checksum = ipv4_pseudo_header_checksum(ip, ntohs(udp->len));
413 break;
414 }
415 case 6: {
416 struct ip6_hdr *ip6 = (struct ip6_hdr *)packet;
417 udp = (struct udphdr *)(ip6 + 1);
418 pseudo_checksum = ipv6_pseudo_header_checksum(ip6, ntohs(udp->len), IPPROTO_UDP);
419 break;
420 }
421 default:
422 FAIL() << "unsupported IP version" << version << "\n";
423 return;
424 }
425
426 udp->check = 0;
427 udp->check = ip_checksum_finish(ip_checksum_add(pseudo_checksum, udp, ntohs(udp->len)));
428 }
429
430 // Testing stub for send_rawv6. The real version uses sendmsg() with a
431 // destination IPv6 address, and attempting to call that on our test socketpair
432 // fd results in EINVAL.
send_rawv6(int fd,clat_packet out,int iov_len)433 extern "C" void send_rawv6(int fd, clat_packet out, int iov_len) { writev(fd, out, iov_len); }
434
do_translate_packet(const uint8_t * original,size_t original_len,uint8_t * out,size_t * outlen,const char * msg)435 void do_translate_packet(const uint8_t *original, size_t original_len, uint8_t *out, size_t *outlen,
436 const char *msg) {
437 int fds[2];
438 if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, fds)) {
439 abort();
440 }
441
442 char foo[512];
443 snprintf(foo, sizeof(foo), "%s: Invalid original packet", msg);
444 check_packet(original, original_len, foo);
445
446 int read_fd, write_fd;
447 uint16_t expected_proto;
448 int version = ip_version(original);
449 switch (version) {
450 case 4:
451 expected_proto = htons(ETH_P_IPV6);
452 read_fd = fds[1];
453 write_fd = fds[0];
454 break;
455 case 6:
456 expected_proto = htons(ETH_P_IP);
457 read_fd = fds[0];
458 write_fd = fds[1];
459 break;
460 default:
461 FAIL() << msg << ": Unsupported IP version " << version << "\n";
462 break;
463 }
464
465 translate_packet(write_fd, (version == 4), original, original_len);
466
467 snprintf(foo, sizeof(foo), "%s: Invalid translated packet", msg);
468 if (version == 6) {
469 // Translating to IPv4. Expect a tun header.
470 struct tun_pi new_tun_header;
471 struct iovec iov[] = {
472 { &new_tun_header, sizeof(new_tun_header) },
473 { out, *outlen },
474 };
475
476 int len = readv(read_fd, iov, 2);
477 if (len > (int)sizeof(new_tun_header)) {
478 ASSERT_LT((size_t)len, *outlen) << msg << ": Translated packet buffer too small\n";
479 EXPECT_EQ(expected_proto, new_tun_header.proto) << msg << "Unexpected tun proto\n";
480 *outlen = len - sizeof(new_tun_header);
481 check_packet(out, *outlen, msg);
482 } else {
483 FAIL() << msg << ": Packet was not translated: len=" << len;
484 *outlen = 0;
485 }
486 } else {
487 // Translating to IPv6. Expect raw packet.
488 *outlen = read(read_fd, out, *outlen);
489 check_packet(out, *outlen, msg);
490 }
491 }
492
check_translated_packet(const uint8_t * original,size_t original_len,const uint8_t * expected,size_t expected_len,const char * msg)493 void check_translated_packet(const uint8_t *original, size_t original_len, const uint8_t *expected,
494 size_t expected_len, const char *msg) {
495 uint8_t translated[MAXMTU];
496 size_t translated_len = sizeof(translated);
497 do_translate_packet(original, original_len, translated, &translated_len, msg);
498 EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n";
499 check_data_matches(expected, translated, translated_len, msg);
500 }
501
check_fragment_translation(const uint8_t * original[],const size_t original_lengths[],const uint8_t * expected[],const size_t expected_lengths[],int numfragments,const char * msg)502 void check_fragment_translation(const uint8_t *original[], const size_t original_lengths[],
503 const uint8_t *expected[], const size_t expected_lengths[],
504 int numfragments, const char *msg) {
505 for (int i = 0; i < numfragments; i++) {
506 // Check that each of the fragments translates as expected.
507 char frag_msg[512];
508 snprintf(frag_msg, sizeof(frag_msg), "%s: fragment #%d", msg, i + 1);
509 check_translated_packet(original[i], original_lengths[i], expected[i], expected_lengths[i],
510 frag_msg);
511 }
512
513 // Sanity check that reassembling the original and translated fragments produces valid packets.
514 uint8_t reassembled[MAXMTU];
515 size_t reassembled_len = sizeof(reassembled);
516 reassemble_packet(original, original_lengths, numfragments, reassembled, &reassembled_len, msg);
517 check_packet(reassembled, reassembled_len, msg);
518
519 uint8_t translated[MAXMTU];
520 size_t translated_len = sizeof(translated);
521 do_translate_packet(reassembled, reassembled_len, translated, &translated_len, msg);
522 check_packet(translated, translated_len, msg);
523 }
524
get_transport_checksum(const uint8_t * packet)525 int get_transport_checksum(const uint8_t *packet) {
526 struct iphdr *ip;
527 struct ip6_hdr *ip6;
528 uint8_t protocol;
529 const void *payload;
530
531 int version = ip_version(packet);
532 switch (version) {
533 case 4:
534 ip = (struct iphdr *)packet;
535 if (is_ipv4_fragment(ip)) {
536 return -1;
537 }
538 protocol = ip->protocol;
539 payload = ip + 1;
540 break;
541 case 6:
542 ip6 = (struct ip6_hdr *)packet;
543 protocol = ip6->ip6_nxt;
544 payload = ip6 + 1;
545 break;
546 default:
547 return -1;
548 }
549
550 switch (protocol) {
551 case IPPROTO_UDP:
552 return ((struct udphdr *)payload)->check;
553
554 case IPPROTO_TCP:
555 return ((struct tcphdr *)payload)->check;
556
557 case IPPROTO_FRAGMENT:
558 default:
559 return -1;
560 }
561 }
562
makeTunData()563 static tun_data makeTunData() {
564 // Create some fake but realistic-looking sockets so update_clat_ipv6_address doesn't balk.
565 return {
566 .write_fd6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW),
567 .read_fd6 = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)),
568 .fd4 = socket(AF_UNIX, SOCK_DGRAM, 0),
569 };
570 }
571
freeTunData(tun_data * tunnel)572 void freeTunData(tun_data *tunnel) {
573 close(tunnel->write_fd6);
574 close(tunnel->read_fd6);
575 close(tunnel->fd4);
576 }
577
578 struct clat_config Global_Clatd_Config;
579
580 class ClatdTest : public ::testing::Test {
581 protected:
582 static TunInterface sTun;
583
SetUp()584 virtual void SetUp() {
585 inet_pton(AF_INET, kIPv4LocalAddr, &Global_Clatd_Config.ipv4_local_subnet);
586 inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet);
587 memset(&Global_Clatd_Config.ipv6_local_subnet, 0, sizeof(in6_addr));
588 Global_Clatd_Config.ipv6_host_id = in6addr_any;
589 Global_Clatd_Config.use_dynamic_iid = 1;
590 Global_Clatd_Config.default_pdp_interface = const_cast<char *>(sTun.name().c_str());
591 }
592
593 // Static because setting up the tun interface takes about 40ms.
SetUpTestCase()594 static void SetUpTestCase() { ASSERT_EQ(0, sTun.init()); }
595
596 // Closing the socket removes the interface and IP addresses.
TearDownTestCase()597 static void TearDownTestCase() { sTun.destroy(); }
598 };
599
600 TunInterface ClatdTest::sTun;
601
expect_ipv6_addr_equal(struct in6_addr * expected,struct in6_addr * actual)602 void expect_ipv6_addr_equal(struct in6_addr *expected, struct in6_addr *actual) {
603 if (!IN6_ARE_ADDR_EQUAL(expected, actual)) {
604 char expected_str[INET6_ADDRSTRLEN], actual_str[INET6_ADDRSTRLEN];
605 inet_ntop(AF_INET6, expected, expected_str, sizeof(expected_str));
606 inet_ntop(AF_INET6, actual, actual_str, sizeof(actual_str));
607 FAIL()
608 << "Unexpected IPv6 address:: "
609 << "\n Expected: " << expected_str
610 << "\n Actual: " << actual_str
611 << "\n";
612 }
613 }
614
TEST_F(ClatdTest,TestIPv6PrefixEqual)615 TEST_F(ClatdTest, TestIPv6PrefixEqual) {
616 EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet,
617 &Global_Clatd_Config.plat_subnet));
618 EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet,
619 &Global_Clatd_Config.ipv6_local_subnet));
620
621 struct in6_addr subnet2 = Global_Clatd_Config.ipv6_local_subnet;
622 EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2));
623 EXPECT_TRUE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
624
625 subnet2.s6_addr[6] = 0xff;
626 EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2));
627 EXPECT_FALSE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
628 }
629
count_onebits(const void * data,size_t size)630 int count_onebits(const void *data, size_t size) {
631 int onebits = 0;
632 for (size_t pos = 0; pos < size; pos++) {
633 uint8_t *byte = ((uint8_t *)data) + pos;
634 for (int shift = 0; shift < 8; shift++) {
635 onebits += (*byte >> shift) & 1;
636 }
637 }
638 return onebits;
639 }
640
TEST_F(ClatdTest,TestCountOnebits)641 TEST_F(ClatdTest, TestCountOnebits) {
642 uint64_t i;
643 i = 1;
644 ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
645 i <<= 61;
646 ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
647 i |= ((uint64_t)1 << 33);
648 ASSERT_EQ(2, count_onebits(&i, sizeof(i)));
649 i = 0xf1000202020000f0;
650 ASSERT_EQ(5 + 1 + 1 + 1 + 4, count_onebits(&i, sizeof(i)));
651 }
652
TEST_F(ClatdTest,TestGenIIDConfigured)653 TEST_F(ClatdTest, TestGenIIDConfigured) {
654 struct in6_addr myaddr, expected;
655 Global_Clatd_Config.use_dynamic_iid = 0;
656 ASSERT_TRUE(inet_pton(AF_INET6, "::bad:ace:d00d", &Global_Clatd_Config.ipv6_host_id));
657 ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:0:bad:ace:d00d", &expected));
658 ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &myaddr));
659 config_generate_local_ipv6_subnet(&myaddr);
660 expect_ipv6_addr_equal(&expected, &myaddr);
661
662 Global_Clatd_Config.use_dynamic_iid = 1;
663 config_generate_local_ipv6_subnet(&myaddr);
664 EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&expected, &myaddr));
665 }
666
TEST_F(ClatdTest,TestGenIIDRandom)667 TEST_F(ClatdTest, TestGenIIDRandom) {
668 struct in6_addr interface_ipv6;
669 ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &interface_ipv6));
670 Global_Clatd_Config.ipv6_host_id = in6addr_any;
671
672 // Generate a boatload of random IIDs.
673 int onebits = 0;
674 uint64_t prev_iid = 0;
675 for (int i = 0; i < 100000; i++) {
676 struct in6_addr myaddr = interface_ipv6;
677
678 config_generate_local_ipv6_subnet(&myaddr);
679
680 // Check the generated IP address is in the same prefix as the interface IPv6 address.
681 EXPECT_TRUE(ipv6_prefix_equal(&interface_ipv6, &myaddr));
682
683 // Check that consecutive IIDs are not the same.
684 uint64_t iid = *(uint64_t *)(&myaddr.s6_addr[8]);
685 ASSERT_TRUE(iid != prev_iid)
686 << "Two consecutive random IIDs are the same: "
687 << std::showbase << std::hex
688 << iid << "\n";
689 prev_iid = iid;
690
691 // Check that the IID is checksum-neutral with the NAT64 prefix and the
692 // local prefix.
693 struct in_addr *ipv4addr = &Global_Clatd_Config.ipv4_local_subnet;
694 struct in6_addr *plat_subnet = &Global_Clatd_Config.plat_subnet;
695
696 uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, ipv4addr, sizeof(*ipv4addr)));
697 uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
698 ip_checksum_add(0, &myaddr, sizeof(myaddr)));
699
700 if (c1 != c2) {
701 char myaddr_str[INET6_ADDRSTRLEN], plat_str[INET6_ADDRSTRLEN], ipv4_str[INET6_ADDRSTRLEN];
702 inet_ntop(AF_INET6, &myaddr, myaddr_str, sizeof(myaddr_str));
703 inet_ntop(AF_INET6, plat_subnet, plat_str, sizeof(plat_str));
704 inet_ntop(AF_INET, ipv4addr, ipv4_str, sizeof(ipv4_str));
705 FAIL()
706 << "Bad IID: " << myaddr_str
707 << " not checksum-neutral with " << ipv4_str << " and " << plat_str
708 << std::showbase << std::hex
709 << "\n IPv4 checksum: " << c1
710 << "\n IPv6 checksum: " << c2
711 << "\n";
712 }
713
714 // Check that IIDs are roughly random and use all the bits by counting the
715 // total number of bits set to 1 in a random sample of 100000 generated IIDs.
716 onebits += count_onebits(&iid, sizeof(iid));
717 }
718 EXPECT_LE(3190000, onebits);
719 EXPECT_GE(3210000, onebits);
720 }
721
722 extern "C" addr_free_func config_is_ipv4_address_free;
never_free(in_addr_t)723 int never_free(in_addr_t /* addr */) { return 0; }
always_free(in_addr_t)724 int always_free(in_addr_t /* addr */) { return 1; }
only2_free(in_addr_t addr)725 int only2_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 2; }
over6_free(in_addr_t addr)726 int over6_free(in_addr_t addr) { return (ntohl(addr) & 0xff) >= 6; }
only10_free(in_addr_t addr)727 int only10_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 10; }
728
TEST_F(ClatdTest,SelectIPv4Address)729 TEST_F(ClatdTest, SelectIPv4Address) {
730 struct in_addr addr;
731
732 inet_pton(AF_INET, kIPv4LocalAddr, &addr);
733
734 addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
735
736 // If no addresses are free, return INADDR_NONE.
737 config_is_ipv4_address_free = never_free;
738 EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
739 EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 16));
740
741 // If the configured address is free, pick that. But a prefix that's too big is invalid.
742 config_is_ipv4_address_free = always_free;
743 EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 29));
744 EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 20));
745 EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 15));
746
747 // A prefix length of 32 works, but anything above it is invalid.
748 EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 32));
749 EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 33));
750
751 // If another address is free, pick it.
752 config_is_ipv4_address_free = over6_free;
753 EXPECT_EQ(inet_addr("192.0.0.6"), config_select_ipv4_address(&addr, 29));
754
755 // Check that we wrap around to addresses that are lower than the first address.
756 config_is_ipv4_address_free = only2_free;
757 EXPECT_EQ(inet_addr("192.0.0.2"), config_select_ipv4_address(&addr, 29));
758 EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 30));
759
760 // If a free address exists outside the prefix, we don't pick it.
761 config_is_ipv4_address_free = only10_free;
762 EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
763 EXPECT_EQ(inet_addr("192.0.0.10"), config_select_ipv4_address(&addr, 24));
764
765 // Now try using the real function which sees if IP addresses are free using bind().
766 // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8.
767 config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
768 addr.s_addr = inet_addr("8.8.8.8");
769 EXPECT_EQ(inet_addr("8.8.8.8"), config_select_ipv4_address(&addr, 29));
770
771 addr.s_addr = inet_addr("127.0.0.1");
772 EXPECT_EQ(inet_addr("127.0.0.2"), config_select_ipv4_address(&addr, 29));
773 }
774
TEST_F(ClatdTest,ConfigureTunIp)775 TEST_F(ClatdTest, ConfigureTunIp) {
776 addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
777 config_is_ipv4_address_free = over6_free;
778
779 Global_Clatd_Config.ipv4_local_prefixlen = 29;
780 Global_Clatd_Config.ipv4mtu = 1472;
781
782 // Create an interface for configure_tun_ip to configure and bring up.
783 TunInterface v4Iface;
784 ASSERT_EQ(0, v4Iface.init());
785 struct tun_data tunnel = makeTunData();
786 strlcpy(tunnel.device4, v4Iface.name().c_str(), sizeof(tunnel.device4));
787
788 configure_tun_ip(&tunnel, nullptr /* v4_addr */);
789 EXPECT_EQ(inet_addr("192.0.0.6"), Global_Clatd_Config.ipv4_local_subnet.s_addr);
790
791 union anyip *ip = getinterface_ip(v4Iface.name().c_str(), AF_INET);
792 EXPECT_EQ(inet_addr("192.0.0.6"), ip->ip4.s_addr);
793 free(ip);
794
795 config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
796 v4Iface.destroy();
797 }
798
TEST_F(ClatdTest,ConfigureTunIpManual)799 TEST_F(ClatdTest, ConfigureTunIpManual) {
800 addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
801 config_is_ipv4_address_free = over6_free;
802
803 Global_Clatd_Config.ipv4_local_prefixlen = 29;
804 Global_Clatd_Config.ipv4mtu = 1472;
805
806 // Create an interface for configure_tun_ip to configure and bring up.
807 TunInterface v4Iface;
808 ASSERT_EQ(0, v4Iface.init());
809 struct tun_data tunnel = makeTunData();
810 strlcpy(tunnel.device4, v4Iface.name().c_str(), sizeof(tunnel.device4));
811
812 configure_tun_ip(&tunnel, "192.0.2.1" /* v4_addr */);
813 EXPECT_EQ(inet_addr("192.0.2.1"), Global_Clatd_Config.ipv4_local_subnet.s_addr);
814
815 union anyip *ip = getinterface_ip(v4Iface.name().c_str(), AF_INET);
816 ASSERT_NE(nullptr, ip);
817 EXPECT_EQ(inet_addr("192.0.2.1"), ip->ip4.s_addr);
818 free(ip);
819
820 config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
821 v4Iface.destroy();
822 }
823
TEST_F(ClatdTest,DataSanitycheck)824 TEST_F(ClatdTest, DataSanitycheck) {
825 // Sanity checks the data.
826 uint8_t v4_header[] = { IPV4_UDP_HEADER };
827 ASSERT_EQ(sizeof(struct iphdr), sizeof(v4_header)) << "Test IPv4 header: incorrect length\n";
828
829 uint8_t v6_header[] = { IPV6_UDP_HEADER };
830 ASSERT_EQ(sizeof(struct ip6_hdr), sizeof(v6_header)) << "Test IPv6 header: incorrect length\n";
831
832 uint8_t udp_header[] = { UDP_HEADER };
833 ASSERT_EQ(sizeof(struct udphdr), sizeof(udp_header)) << "Test UDP header: incorrect length\n";
834
835 // Sanity checks check_packet.
836 struct udphdr *udp;
837 uint8_t v4_udp_packet[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
838 udp = (struct udphdr *)(v4_udp_packet + sizeof(struct iphdr));
839 fix_udp_checksum(v4_udp_packet);
840 ASSERT_EQ(kUdpV4Checksum, udp->check) << "UDP/IPv4 packet checksum sanity check\n";
841 check_packet(v4_udp_packet, sizeof(v4_udp_packet), "UDP/IPv4 packet sanity check");
842
843 uint8_t v6_udp_packet[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
844 udp = (struct udphdr *)(v6_udp_packet + sizeof(struct ip6_hdr));
845 fix_udp_checksum(v6_udp_packet);
846 ASSERT_EQ(kUdpV6Checksum, udp->check) << "UDP/IPv6 packet checksum sanity check\n";
847 check_packet(v6_udp_packet, sizeof(v6_udp_packet), "UDP/IPv6 packet sanity check");
848
849 uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD };
850 check_packet(ipv4_ping, sizeof(ipv4_ping), "IPv4 ping sanity check");
851
852 uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD };
853 check_packet(ipv6_ping, sizeof(ipv6_ping), "IPv6 ping sanity check");
854
855 // Sanity checks reassemble_packet.
856 uint8_t reassembled[MAXMTU];
857 size_t total_length = sizeof(reassembled);
858 reassemble_packet(kIPv4Fragments, kIPv4FragLengths, ARRAYSIZE(kIPv4Fragments), reassembled,
859 &total_length, "Reassembly sanity check");
860 check_packet(reassembled, total_length, "IPv4 Reassembled packet is valid");
861 ASSERT_EQ(sizeof(kReassembledIPv4), total_length) << "IPv4 reassembly sanity check: length\n";
862 ASSERT_TRUE(!is_ipv4_fragment((struct iphdr *)reassembled))
863 << "Sanity check: reassembled packet is a fragment!\n";
864 check_data_matches(kReassembledIPv4, reassembled, total_length, "IPv4 reassembly sanity check");
865
866 total_length = sizeof(reassembled);
867 reassemble_packet(kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv6Fragments), reassembled,
868 &total_length, "IPv6 reassembly sanity check");
869 ASSERT_TRUE(!is_ipv6_fragment((struct ip6_hdr *)reassembled, total_length))
870 << "Sanity check: reassembled packet is a fragment!\n";
871 check_packet(reassembled, total_length, "IPv6 Reassembled packet is valid");
872 }
873
TEST_F(ClatdTest,PseudoChecksum)874 TEST_F(ClatdTest, PseudoChecksum) {
875 uint32_t pseudo_checksum;
876
877 uint8_t v4_header[] = { IPV4_UDP_HEADER };
878 uint8_t v4_pseudo_header[] = { IPV4_PSEUDOHEADER(v4_header, UDP_LEN) };
879 pseudo_checksum = ipv4_pseudo_header_checksum((struct iphdr *)v4_header, UDP_LEN);
880 EXPECT_EQ(ip_checksum_finish(pseudo_checksum),
881 ip_checksum(v4_pseudo_header, sizeof(v4_pseudo_header)))
882 << "ipv4_pseudo_header_checksum incorrect\n";
883
884 uint8_t v6_header[] = { IPV6_UDP_HEADER };
885 uint8_t v6_pseudo_header[] = { IPV6_PSEUDOHEADER(v6_header, IPPROTO_UDP, UDP_LEN) };
886 pseudo_checksum = ipv6_pseudo_header_checksum((struct ip6_hdr *)v6_header, UDP_LEN, IPPROTO_UDP);
887 EXPECT_EQ(ip_checksum_finish(pseudo_checksum),
888 ip_checksum(v6_pseudo_header, sizeof(v6_pseudo_header)))
889 << "ipv6_pseudo_header_checksum incorrect\n";
890 }
891
TEST_F(ClatdTest,TransportChecksum)892 TEST_F(ClatdTest, TransportChecksum) {
893 uint8_t udphdr[] = { UDP_HEADER };
894 uint8_t payload[] = { PAYLOAD };
895 EXPECT_EQ(kUdpPartialChecksum, ip_checksum_add(0, udphdr, sizeof(udphdr)))
896 << "UDP partial checksum\n";
897 EXPECT_EQ(kPayloadPartialChecksum, ip_checksum_add(0, payload, sizeof(payload)))
898 << "Payload partial checksum\n";
899
900 uint8_t ip[] = { IPV4_UDP_HEADER };
901 uint8_t ip6[] = { IPV6_UDP_HEADER };
902 uint32_t ipv4_pseudo_sum = ipv4_pseudo_header_checksum((struct iphdr *)ip, UDP_LEN);
903 uint32_t ipv6_pseudo_sum =
904 ipv6_pseudo_header_checksum((struct ip6_hdr *)ip6, UDP_LEN, IPPROTO_UDP);
905
906 EXPECT_EQ(0x3ad0U, ipv4_pseudo_sum) << "IPv4 pseudo-checksum sanity check\n";
907 EXPECT_EQ(0x2644bU, ipv6_pseudo_sum) << "IPv6 pseudo-checksum sanity check\n";
908 EXPECT_EQ(
909 kUdpV4Checksum,
910 ip_checksum_finish(ipv4_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum))
911 << "Unexpected UDP/IPv4 checksum\n";
912 EXPECT_EQ(
913 kUdpV6Checksum,
914 ip_checksum_finish(ipv6_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum))
915 << "Unexpected UDP/IPv6 checksum\n";
916
917 EXPECT_EQ(kUdpV6Checksum,
918 ip_checksum_adjust(kUdpV4Checksum, ipv4_pseudo_sum, ipv6_pseudo_sum))
919 << "Adjust IPv4/UDP checksum to IPv6\n";
920 EXPECT_EQ(kUdpV4Checksum,
921 ip_checksum_adjust(kUdpV6Checksum, ipv6_pseudo_sum, ipv4_pseudo_sum))
922 << "Adjust IPv6/UDP checksum to IPv4\n";
923 }
924
TEST_F(ClatdTest,AdjustChecksum)925 TEST_F(ClatdTest, AdjustChecksum) {
926 struct checksum_data {
927 uint16_t checksum;
928 uint32_t old_hdr_sum;
929 uint32_t new_hdr_sum;
930 uint16_t result;
931 } DATA[] = {
932 { 0x1423, 0xb8ec, 0x2d757, 0xf5b5 },
933 { 0xf5b5, 0x2d757, 0xb8ec, 0x1423 },
934 { 0xdd2f, 0x5555, 0x3285, 0x0000 },
935 { 0x1215, 0x5560, 0x15560 + 20, 0x1200 },
936 { 0xd0c7, 0x3ad0, 0x2644b, 0xa74a },
937 };
938 unsigned i = 0;
939
940 for (i = 0; i < ARRAYSIZE(DATA); i++) {
941 struct checksum_data *data = DATA + i;
942 uint16_t result = ip_checksum_adjust(data->checksum, data->old_hdr_sum, data->new_hdr_sum);
943 EXPECT_EQ(result, data->result)
944 << "Incorrect checksum" << std::showbase << std::hex
945 << "\n Expected: " << data->result
946 << "\n Actual: " << result
947 << "\n checksum=" << data->checksum
948 << " old_sum=" << data->old_hdr_sum << " new_sum=" << data->new_hdr_sum << "\n";
949 }
950 }
951
TEST_F(ClatdTest,Translate)952 TEST_F(ClatdTest, Translate) {
953 // This test uses hardcoded packets so the clatd address must be fixed.
954 inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet);
955
956 uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
957 uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
958 fix_udp_checksum(udp_ipv4);
959 fix_udp_checksum(udp_ipv6);
960 check_translated_packet(udp_ipv4, sizeof(udp_ipv4), udp_ipv6, sizeof(udp_ipv6),
961 "UDP/IPv4 -> UDP/IPv6 translation");
962 check_translated_packet(udp_ipv6, sizeof(udp_ipv6), udp_ipv4, sizeof(udp_ipv4),
963 "UDP/IPv6 -> UDP/IPv4 translation");
964
965 uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD };
966 uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD };
967 check_translated_packet(ipv4_ping, sizeof(ipv4_ping), ipv6_ping, sizeof(ipv6_ping),
968 "ICMP->ICMPv6 translation");
969 check_translated_packet(ipv6_ping, sizeof(ipv6_ping), ipv4_ping, sizeof(ipv4_ping),
970 "ICMPv6->ICMP translation");
971 }
972
TEST_F(ClatdTest,Fragmentation)973 TEST_F(ClatdTest, Fragmentation) {
974 // This test uses hardcoded packets so the clatd address must be fixed.
975 inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet);
976
977 check_fragment_translation(kIPv4Fragments, kIPv4FragLengths, kIPv6Fragments, kIPv6FragLengths,
978 ARRAYSIZE(kIPv4Fragments), "IPv4->IPv6 fragment translation");
979
980 check_fragment_translation(kIPv6Fragments, kIPv6FragLengths, kIPv4Fragments, kIPv4FragLengths,
981 ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation");
982 }
983
check_translate_checksum_neutral(const uint8_t * original,size_t original_len,size_t expected_len,const char * msg)984 void check_translate_checksum_neutral(const uint8_t *original, size_t original_len,
985 size_t expected_len, const char *msg) {
986 uint8_t translated[MAXMTU];
987 size_t translated_len = sizeof(translated);
988 do_translate_packet(original, original_len, translated, &translated_len, msg);
989 EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n";
990 // do_translate_packet already checks packets for validity and verifies the checksum.
991 int original_check = get_transport_checksum(original);
992 int translated_check = get_transport_checksum(translated);
993 ASSERT_NE(-1, original_check);
994 ASSERT_NE(-1, translated_check);
995 ASSERT_EQ(original_check, translated_check)
996 << "Not checksum neutral: original and translated checksums differ\n";
997 }
998
TEST_F(ClatdTest,TranslateChecksumNeutral)999 TEST_F(ClatdTest, TranslateChecksumNeutral) {
1000 // Generate a random clat IPv6 address and check that translation is checksum-neutral.
1001 Global_Clatd_Config.ipv6_host_id = in6addr_any;
1002 ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54",
1003 &Global_Clatd_Config.ipv6_local_subnet));
1004 config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet);
1005 ASSERT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1006 ASSERT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1007
1008 // Check that translating UDP packets is checksum-neutral. First, IPv4.
1009 uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
1010 fix_udp_checksum(udp_ipv4);
1011 check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20,
1012 "UDP/IPv4 -> UDP/IPv6 checksum neutral");
1013
1014 // Now try IPv6.
1015 uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
1016 // The test packet uses the static IID, not the random IID. Fix up the source address.
1017 struct ip6_hdr *ip6 = (struct ip6_hdr *)udp_ipv6;
1018 memcpy(&ip6->ip6_src, &Global_Clatd_Config.ipv6_local_subnet, sizeof(ip6->ip6_src));
1019 fix_udp_checksum(udp_ipv6);
1020 check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20,
1021 "UDP/IPv4 -> UDP/IPv6 checksum neutral");
1022 }
1023
TEST_F(ClatdTest,GetInterfaceIp)1024 TEST_F(ClatdTest, GetInterfaceIp) {
1025 union anyip *ip = getinterface_ip(sTun.name().c_str(), AF_INET6);
1026 ASSERT_NE(nullptr, ip);
1027 in6_addr expected = sTun.srcAddr();
1028 in6_addr actual = ip->ip6;
1029 expect_ipv6_addr_equal(&expected, &actual);
1030 }
1031
expectSocketBound(int ifindex,int sock)1032 void expectSocketBound(int ifindex, int sock) {
1033 // Check that the packet socket is bound to the interface. We can't check the socket filter
1034 // because there is no way to fetch it from the kernel.
1035 sockaddr_ll sll;
1036 socklen_t len = sizeof(sll);
1037 ASSERT_EQ(0, getsockname(sock, reinterpret_cast<sockaddr *>(&sll), &len));
1038 EXPECT_EQ(htons(ETH_P_IPV6), sll.sll_protocol);
1039 EXPECT_EQ(ifindex, sll.sll_ifindex);
1040 }
1041
TEST_F(ClatdTest,ConfigureIpv6Address)1042 TEST_F(ClatdTest, ConfigureIpv6Address) {
1043 struct tun_data tunnel = makeTunData();
1044
1045 // Run configure_clat_ipv6_address.
1046 ASSERT_TRUE(IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet));
1047 ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, sTun.name().c_str(), nullptr /* v6_addr */));
1048
1049 // Check that it generated an IID in the same prefix as the address assigned to the interface,
1050 // and that the IID is not the default IID.
1051 in6_addr addr = sTun.srcAddr();
1052 EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &addr));
1053 EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&Global_Clatd_Config.ipv6_local_subnet, &addr));
1054 EXPECT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1055 EXPECT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1056
1057 expectSocketBound(sTun.ifindex(), tunnel.read_fd6);
1058
1059 freeTunData(&tunnel);
1060 }
1061
TEST_F(ClatdTest,ConfigureIpv6AddressCommandLine)1062 TEST_F(ClatdTest, ConfigureIpv6AddressCommandLine) {
1063 struct tun_data tunnel = makeTunData();
1064
1065 ASSERT_TRUE(IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet));
1066
1067 const char *addrStr = "2001:db8::f00";
1068 in6_addr addr;
1069 ASSERT_EQ(1, inet_pton(AF_INET6, addrStr, &addr));
1070 ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, sTun.name().c_str(), addrStr));
1071
1072 EXPECT_EQ(htonl(0x20010db8), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[0]);
1073 EXPECT_EQ(htonl(0x00000000), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[1]);
1074 EXPECT_EQ(htonl(0x00000000), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[2]);
1075 EXPECT_EQ(htonl(0x00000f00), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1076
1077 // Check that the packet socket is bound to the interface. We can't check the socket filter
1078 // because there is no way to fetch it from the kernel.
1079 sockaddr_ll sll;
1080 socklen_t len = sizeof(sll);
1081 ASSERT_EQ(0, getsockname(tunnel.read_fd6, reinterpret_cast<sockaddr *>(&sll), &len));
1082 EXPECT_EQ(htons(ETH_P_IPV6), sll.sll_protocol);
1083 EXPECT_EQ(sll.sll_ifindex, sTun.ifindex());
1084
1085 expectSocketBound(sTun.ifindex(), tunnel.read_fd6);
1086
1087 freeTunData(&tunnel);
1088 }
1089
TEST_F(ClatdTest,Ipv6AddressChanged)1090 TEST_F(ClatdTest, Ipv6AddressChanged) {
1091 // Configure the clat IPv6 address.
1092 struct tun_data tunnel = {
1093 .write_fd6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW),
1094 .read_fd6 = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)),
1095 };
1096 const char *ifname = sTun.name().c_str();
1097 ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, ifname, nullptr));
1098 EXPECT_EQ(0, ipv6_address_changed(ifname));
1099 EXPECT_EQ(0, ipv6_address_changed(ifname));
1100
1101 // Change the IP address on the tun interface to a new prefix.
1102 char srcaddr[INET6_ADDRSTRLEN];
1103 char dstaddr[INET6_ADDRSTRLEN];
1104 ASSERT_NE(nullptr, inet_ntop(AF_INET6, &sTun.srcAddr(), srcaddr, sizeof(srcaddr)));
1105 ASSERT_NE(nullptr, inet_ntop(AF_INET6, &sTun.dstAddr(), dstaddr, sizeof(dstaddr)));
1106 EXPECT_EQ(0, ifc_del_address(ifname, srcaddr, 64));
1107 EXPECT_EQ(0, ifc_del_address(ifname, dstaddr, 64));
1108
1109 // Check that we can tell that the address has changed.
1110 EXPECT_EQ(0, ifc_add_address(ifname, "2001:db8::1:2", 64));
1111 EXPECT_EQ(1, ipv6_address_changed(ifname));
1112 EXPECT_EQ(1, ipv6_address_changed(ifname));
1113
1114 // Restore the tun interface configuration.
1115 sTun.destroy();
1116 ASSERT_EQ(0, sTun.init());
1117 }
1118