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